1 /* 2 * LCD peripheral support for the JZ4740 and related SoCs. 3 * 4 * Copyright (C) 2018, 2020 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #pragma once 23 24 #include "lcd.h" 25 #include "lcd-jz4740-panel.h" 26 27 #include <l4/sys/types.h> 28 29 #include <stdint.h> 30 31 /* Descriptor referenced by the DMA mechanism extended to 8 words for JZ4780 32 support. */ 33 34 struct Jz4740_lcd_descriptor 35 { 36 struct Jz4740_lcd_descriptor *next; /* FDADR: frame descriptor address */ 37 uint32_t source; /* FSADR: frame source address */ 38 uint32_t identifier; /* FIDR: frame identifier */ 39 uint32_t command; /* CMD: command */ 40 41 /* "New" descriptor fields. */ 42 43 uint32_t offset; /* OFFSIZE: offset in words between lines */ 44 uint32_t page_width; /* PW: number of words per line (16x16 block mode) */ 45 uint32_t command_position; /* CNUM: command number (smart LCD mode) or 46 CPOS: foreground position and properties */ 47 uint32_t fg_size; /* DESSIZE: foreground size and alpha properties */ 48 }; 49 50 /* Interrupt conditions. */ 51 52 enum Jz4740_lcd_irq_condition 53 { 54 Lcd_irq_none = 0, 55 Lcd_irq_frame_start = 1, 56 Lcd_irq_frame_end = 2, 57 }; 58 59 60 61 /* C++ language interface. */ 62 63 #ifdef __cplusplus 64 65 #include <l4/devices/hw_mmio_register_block.h> 66 67 /* General JZ4740 LCD controller support. */ 68 69 class Lcd_jz4740_chip : public Lcd_chip 70 { 71 private: 72 Hw::Register_block<32> _regs; 73 Jz4740_lcd_panel *_panel; 74 int _burst_size; 75 enum Jz4740_lcd_irq_condition _irq_conditions = Lcd_irq_none; 76 l4_cap_idx_t _irq = L4_INVALID_CAP; 77 78 /* Control register value calculation. */ 79 80 uint32_t _control_bpp(); 81 uint32_t _control_irq(); 82 uint32_t _control_panel(); 83 uint32_t _control_stn_frc(); 84 uint32_t _control_transfer(); 85 86 /* OSD configure register value calculation. */ 87 88 uint32_t _osd_config_irq(); 89 90 /* Command register value calculation. */ 91 92 uint32_t _command_irq(); 93 94 /* Status register value calculation. */ 95 96 uint32_t _status_irq(); 97 98 /* Priority level threshold value calculation. */ 99 100 uint32_t _priority_transfer(); 101 102 /* Position value calculation. */ 103 104 uint32_t _position_bpp(); 105 106 /* Panel mode access. */ 107 108 uint32_t _mode(); 109 110 /* Panel initialisation. */ 111 112 void _init_stn(); 113 void _init_tft(); 114 void _init_panel(); 115 116 /* Descriptor initialisation. */ 117 118 void _set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, 119 l4_size_t size, struct Jz4740_lcd_descriptor *next, 120 uint32_t flags = 0, bool frame_enable = true); 121 122 public: 123 Lcd_jz4740_chip(l4_addr_t addr, Jz4740_lcd_panel *panel); 124 125 struct Jz4740_lcd_panel *get_panel(); 126 127 /* Peripheral control. */ 128 129 void disable(); 130 void disable_quick(); 131 void enable(); 132 bool enabled(); 133 134 /* Peripheral properties. */ 135 136 int get_pixel_clock(); 137 138 /* Panel properties. */ 139 140 int get_panels(); 141 int have_stn_panel(); 142 int have_colour_stn(); 143 int have_serial_tft(); 144 145 /* Memory properties. */ 146 147 l4_size_t get_pixel_size(); 148 l4_size_t get_line_size(); 149 l4_size_t get_screen_size(); 150 l4_size_t get_aligned_size(); 151 l4_size_t get_palette_size(); 152 l4_size_t get_aligned_palette_size(); 153 154 /* Memory properties for allocation purposes. */ 155 156 l4_size_t get_total_size(); 157 l4_size_t get_descriptors_size(); 158 159 /* Memory region access. */ 160 161 l4_addr_t get_palette(l4_addr_t screen); 162 l4_addr_t get_framebuffer(int panel, l4_addr_t screen); 163 164 /* Convenience methods. */ 165 166 void init_palette(l4_addr_t palette); 167 168 /* Configuration. */ 169 170 void config(struct Jz4740_lcd_descriptor *desc_vaddr, 171 struct Jz4740_lcd_descriptor *desc_paddr, 172 l4_addr_t fb_paddr); 173 174 /* Interrupt configuration. */ 175 176 void set_irq(l4_cap_idx_t irq, enum Jz4740_lcd_irq_condition conditions); 177 178 /* Interrupt handling. */ 179 180 long wait_for_irq(); 181 }; 182 183 #endif 184 185 186 187 /* C language interface. */ 188 189 EXTERN_C_BEGIN 190 191 void *jz4740_lcd_init(l4_addr_t lcd_base, struct Jz4740_lcd_panel *panel); 192 193 void jz4740_lcd_config(void *lcd, struct Jz4740_lcd_descriptor *desc_vaddr, 194 struct Jz4740_lcd_descriptor *desc_paddr, 195 l4_addr_t fb_paddr); 196 197 void jz4740_lcd_set_irq(void *lcd, l4_cap_idx_t irq, 198 enum Jz4740_lcd_irq_condition conditions); 199 200 long jz4740_lcd_wait_for_irq(void *lcd); 201 202 void jz4740_lcd_disable(void *lcd); 203 void jz4740_lcd_disable_quick(void *lcd); 204 void jz4740_lcd_enable(void *lcd); 205 int jz4740_lcd_enabled(void *lcd); 206 207 l4_size_t jz4740_lcd_get_descriptors_size(void *lcd); 208 l4_size_t jz4740_lcd_get_line_size(void *lcd); 209 l4_size_t jz4740_lcd_get_screen_size(void *lcd); 210 211 l4_addr_t jz4740_lcd_get_palette(void *lcd, l4_addr_t base); 212 int jz4740_lcd_get_pixel_clock(void *lcd); 213 214 void jz4740_lcd_init_palette(void *lcd, l4_addr_t palette); 215 216 EXTERN_C_END