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 protected: 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 /* Command register value calculation. */ 87 88 uint32_t _command_irq(); 89 90 /* Status register value calculation. */ 91 92 uint32_t _status_irq(); 93 94 /* Panel mode access. */ 95 96 uint32_t _mode(); 97 98 /* Panel initialisation. */ 99 100 void _init_stn(); 101 void _init_tft(); 102 void _init_panel(); 103 104 /* Descriptor initialisation. */ 105 106 virtual void _set_descriptor(struct Jz4740_lcd_descriptor &desc, l4_addr_t source, 107 l4_size_t size, struct Jz4740_lcd_descriptor *next, 108 uint32_t flags = 0); 109 110 public: 111 Lcd_jz4740_chip(l4_addr_t addr, Jz4740_lcd_panel *panel); 112 113 struct Jz4740_lcd_panel *get_panel(); 114 115 /* Peripheral control. */ 116 117 void disable(); 118 void disable_quick(); 119 virtual void enable(); 120 bool enabled(); 121 122 /* Peripheral properties. */ 123 124 int get_pixel_clock(); 125 126 /* Panel properties. */ 127 128 int get_panels(); 129 int have_stn_panel(); 130 int have_colour_stn(); 131 int have_serial_tft(); 132 133 /* Memory properties. */ 134 135 l4_size_t get_pixel_size(); 136 l4_size_t get_line_size(); 137 l4_size_t get_screen_size(); 138 l4_size_t get_aligned_size(); 139 l4_size_t get_palette_size(); 140 l4_size_t get_aligned_palette_size(); 141 142 /* Memory properties for allocation purposes. */ 143 144 l4_size_t get_total_size(); 145 l4_size_t get_descriptors_size(); 146 147 /* Memory region access. */ 148 149 l4_addr_t get_palette(l4_addr_t screen); 150 l4_addr_t get_framebuffer(int panel, l4_addr_t screen); 151 152 /* Convenience methods. */ 153 154 void init_palette(l4_addr_t palette); 155 156 /* Configuration. */ 157 158 virtual void config(struct Jz4740_lcd_descriptor *desc_vaddr, 159 struct Jz4740_lcd_descriptor *desc_paddr, 160 l4_addr_t fb_paddr); 161 162 /* Interrupt configuration. */ 163 164 void set_irq(l4_cap_idx_t irq, enum Jz4740_lcd_irq_condition conditions); 165 166 /* Interrupt handling. */ 167 168 long wait_for_irq(); 169 }; 170 171 #endif 172 173 174 175 /* C language interface. */ 176 177 EXTERN_C_BEGIN 178 179 void *jz4740_lcd_init(l4_addr_t lcd_base, struct Jz4740_lcd_panel *panel); 180 181 void jz4740_lcd_config(void *lcd, struct Jz4740_lcd_descriptor *desc_vaddr, 182 struct Jz4740_lcd_descriptor *desc_paddr, 183 l4_addr_t fb_paddr); 184 185 void jz4740_lcd_set_irq(void *lcd, l4_cap_idx_t irq, 186 enum Jz4740_lcd_irq_condition conditions); 187 188 long jz4740_lcd_wait_for_irq(void *lcd); 189 190 void jz4740_lcd_disable(void *lcd); 191 void jz4740_lcd_disable_quick(void *lcd); 192 void jz4740_lcd_enable(void *lcd); 193 int jz4740_lcd_enabled(void *lcd); 194 195 l4_size_t jz4740_lcd_get_descriptors_size(void *lcd); 196 l4_size_t jz4740_lcd_get_line_size(void *lcd); 197 l4_size_t jz4740_lcd_get_screen_size(void *lcd); 198 199 l4_addr_t jz4740_lcd_get_palette(void *lcd, l4_addr_t base); 200 int jz4740_lcd_get_pixel_clock(void *lcd); 201 202 void jz4740_lcd_init_palette(void *lcd, l4_addr_t palette); 203 204 EXTERN_C_END