2.1 --- a/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Fri Jun 05 23:45:28 2020 +0200
2.2 +++ b/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Fri Jun 05 23:59:12 2020 +0200
2.3 @@ -23,6 +23,7 @@
2.4
2.5 #include <l4/devices/hw_mmio_register_block.h>
2.6 #include <l4/sys/cache.h>
2.7 +#include <l4/sys/err.h>
2.8 #include <l4/sys/irq.h>
2.9 #include <l4/sys/types.h>
2.10 #include <l4/util/util.h>
2.11 @@ -52,11 +53,16 @@
2.12 Source_address_0 = 0x044, // LCD_SA0
2.13 Frame_id_0 = 0x048, // LCD_FID0
2.14 Command_0 = 0x04c, // LCD_CMD0
2.15 + Counter_position_0 = 0x068, // LCD_CPOS0
2.16 + Foreground_size_0 = 0x06c, // LCD_DESSIZE0
2.17 Desc_address_1 = 0x050, // LCD_DA1
2.18 Source_address_1 = 0x054, // LCD_SA1
2.19 Frame_id_1 = 0x058, // LCD_FID1
2.20 Command_1 = 0x05c, // LCD_CMD1
2.21 + Counter_position_1 = 0x078, // LCD_CPOS1
2.22 + Foreground_size_1 = 0x07c, // LCD_DESSIZE1
2.23 Rgb_control = 0x090, // LCD_RGBC (JZ4780)
2.24 + Alpha_levels = 0x108, // LCD_ALPHA (JZ4780)
2.25 Priority_level = 0x2c0, // LCD_PCFG
2.26
2.27 // OSD registers.
2.28 @@ -186,6 +192,9 @@
2.29 {
2.30 Status_frame_end_irq = 5,
2.31 Status_frame_start_irq = 4,
2.32 + Status_out_underrun_irq = 3,
2.33 + Status_in0_underrun_irq = 2,
2.34 + Status_in1_underrun_irq = 1,
2.35 Status_disabled = 0,
2.36 };
2.37
2.38 @@ -193,13 +202,23 @@
2.39
2.40 enum Osd_config_bits : unsigned
2.41 {
2.42 + Osd_config_fg1_pixel_alpha_enable = 17,
2.43 Osd_config_fg1_frame_start_irq_enable = 15,
2.44 Osd_config_fg1_frame_end_irq_enable = 14,
2.45 Osd_config_fg0_frame_start_irq_enable = 11,
2.46 Osd_config_fg0_frame_end_irq_enable = 10,
2.47 + Osd_config_fg1_enable = 4,
2.48 + Osd_config_fg0_enable = 3,
2.49 + Osd_config_alpha_enable = 2,
2.50 + Osd_config_fg0_pixel_alpha_enable = 1,
2.51 Osd_config_enable = 0,
2.52 };
2.53
2.54 +enum Osd_control_bits : unsigned
2.55 +{
2.56 + Osd_control_ipu_clock_enable = 15,
2.57 +};
2.58 +
2.59 // RGB control (JZ4780).
2.60
2.61 enum Rgb_control_bits : unsigned
2.62 @@ -230,6 +249,20 @@
2.63 Rgb_even_line_bgr = 5U << Rgb_even_line,
2.64 };
2.65
2.66 +// Alpha levels (JZ4780).
2.67 +
2.68 +enum Alpha_levels_bits : unsigned
2.69 +{
2.70 + Alpha_level_fg1 = 8,
2.71 + Alpha_level_fg0 = 0,
2.72 +};
2.73 +
2.74 +enum Alpha_levels_values : unsigned
2.75 +{
2.76 + Alpha_level_fg1_mask = 0x0000ff00,
2.77 + Alpha_level_fg0_mask = 0x000000ff,
2.78 +};
2.79 +
2.80 // Priority level.
2.81
2.82 enum Priority_level_bits : unsigned
2.83 @@ -317,8 +350,8 @@
2.84 : _panel(panel)
2.85 {
2.86 _regs = new Hw::Mmio_register_block<32>(addr);
2.87 - //_burst_size = 64; // 64-word burst size (JZ4780)
2.88 - _burst_size = 16; // 16-word burst size
2.89 + _burst_size = 64; // 64-word burst size (JZ4780)
2.90 + //_burst_size = 16; // 16-word burst size
2.91
2.92 // add_cid("lcd");
2.93 // add_cid("lcd-jz4740");
2.94 @@ -684,7 +717,8 @@
2.95 uint32_t
2.96 Lcd_jz4740_chip::_control_irq()
2.97 {
2.98 - return ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Control_frame_start_irq_enable) : 0) |
2.99 + return // (1U << Control_out_underrun_irq_enable) |
2.100 + ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Control_frame_start_irq_enable) : 0) |
2.101 ((_irq_conditions & Lcd_irq_frame_end) ? (1U << Control_frame_end_irq_enable) : 0);
2.102 }
2.103
2.104 @@ -711,7 +745,8 @@
2.105 uint32_t
2.106 Lcd_jz4740_chip::_status_irq()
2.107 {
2.108 - return ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Status_frame_start_irq) : 0) |
2.109 + return // (1U << Status_out_underrun_irq) |
2.110 + ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Status_frame_start_irq) : 0) |
2.111 ((_irq_conditions & Lcd_irq_frame_end) ? (1U << Status_frame_end_irq) : 0);
2.112 }
2.113
2.114 @@ -834,30 +869,28 @@
2.115 Lcd_jz4740_chip::_set_descriptor(struct Jz4740_lcd_descriptor &desc,
2.116 l4_addr_t source, l4_size_t size,
2.117 struct Jz4740_lcd_descriptor *next,
2.118 - uint32_t flags)
2.119 + uint32_t flags,
2.120 + bool frame_enable)
2.121 {
2.122 // In the command, indicate the number of words from the source for transfer.
2.123
2.124 desc.next = next;
2.125 - desc.source = source;
2.126 + desc.source = frame_enable ? source : 0;
2.127 desc.identifier = source;
2.128 desc.command = ((size / sizeof(uint32_t)) & Command_buffer_length_mask) |
2.129 - (1U << Command_frame_enable) |
2.130 + (frame_enable ? (1U << Command_frame_enable) : 0) |
2.131 flags;
2.132
2.133 - printf("next = %08x\n", desc.next);
2.134 - printf("source = %08x\n", desc.source);
2.135 - printf("identifier = %08x\n", desc.identifier);
2.136 - printf("command = %08x\n", desc.command);
2.137 -
2.138 // Initialise "new" descriptor fields.
2.139
2.140 desc.offset = 0;
2.141 desc.page_width = 0;
2.142 - desc.command_position = (1UL << Position_premultiply_lcd) |
2.143 - (1UL << Position_coefficient) |
2.144 + desc.command_position = (1U << Position_premultiply_lcd) |
2.145 + ((frame_enable ? 1U : 3U) << Position_coefficient) |
2.146 _position_bpp();
2.147 - desc.fg_size = 0xff000000 | (1023 << 12) | (1279 << 0); // JZ4780 driver magic
2.148 + desc.fg_size = 0xff000000 |
2.149 + ((_panel->height - 1) << 12) |
2.150 + ((_panel->width - 1) << 0);
2.151 }
2.152
2.153
2.154 @@ -875,6 +908,8 @@
2.155
2.156 int have_palette = (_panel->bpp <= 8);
2.157
2.158 + bool _have_fg1 = true; // NOTE: To be formalised!
2.159 +
2.160 // Provide the first framebuffer descriptor in single and dual modes.
2.161 // Flip back and forth between any palette and the framebuffer.
2.162
2.163 @@ -886,11 +921,12 @@
2.164 // Provide the second framebuffer descriptor only in dual-panel mode.
2.165 // Only employ this descriptor in the second DMA channel.
2.166
2.167 - if (get_panels() == 2)
2.168 + if ((get_panels() == 2) || _have_fg1)
2.169 _set_descriptor(desc_vaddr[1], get_framebuffer(1, fb_paddr),
2.170 get_aligned_size(),
2.171 desc_paddr + 1,
2.172 - _command_irq());
2.173 + _command_irq(),
2.174 + false);
2.175
2.176 // Initialise palette descriptor details for lower colour depths.
2.177
2.178 @@ -910,11 +946,10 @@
2.179 // Provide the palette descriptor address first, if employed.
2.180
2.181 _regs[Desc_address_0] = (uint32_t) (have_palette ? desc_paddr + 2 : desc_paddr);
2.182 - printf("descriptor = %08x\n", (uint32_t) _regs[Desc_address_0]);
2.183
2.184 // Provide a descriptor for the second DMA channel in dual-panel mode.
2.185
2.186 - if (get_panels() == 2)
2.187 + if ((get_panels() == 2) || _have_fg1)
2.188 _regs[Desc_address_1] = (uint32_t) (desc_paddr + 1);
2.189
2.190 // Initialise panel-related registers.
2.191 @@ -931,10 +966,15 @@
2.192
2.193 _regs[Rgb_control] = (1U << Rgb_format_enable) | Rgb_odd_line_rgb | Rgb_even_line_rgb;
2.194 _regs[Priority_level] = _priority_transfer();
2.195 - _regs[Osd_config] = 0; // (1U << Osd_config_enable) | _osd_config_irq();
2.196 + _regs[Osd_config] = //_osd_config_irq() |
2.197 + (1U << Osd_config_enable) |
2.198 + (1U << Osd_config_alpha_enable);
2.199 + _regs[Alpha_levels] = ((255U << Alpha_level_fg1) & Alpha_level_fg1_mask) |
2.200 + ((255U << Alpha_level_fg0) & Alpha_level_fg0_mask);
2.201
2.202 printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
2.203 printf("LCD status: %08x\n", (unsigned int) _regs[Lcd_status]);
2.204 + printf("OSD control: %08x\n", (unsigned int) _regs[Osd_control]);
2.205 printf("OSD config: %08x\n", (unsigned int) _regs[Osd_config]);
2.206 printf("OSD status: %08x\n", (unsigned int) _regs[Osd_status]);
2.207 }
2.208 @@ -953,35 +993,42 @@
2.209 long
2.210 Lcd_jz4740_chip::wait_for_irq()
2.211 {
2.212 - long err;
2.213 l4_msgtag_t tag;
2.214
2.215 _regs[Lcd_status] = _regs[Lcd_status] & ~(_status_irq());
2.216
2.217 // Wait for a condition.
2.218
2.219 - printf("Waiting for IRQ...\n");
2.220 - tag = l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(1000000)));
2.221 + //printf("Waiting for IRQ...\n");
2.222 + tag = l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(2000000)));
2.223 +
2.224 + //if (_regs[Lcd_status] & (1U << Status_out_underrun_irq))
2.225 + // enable();
2.226 +
2.227 +#if 0
2.228 + printf("LCD config: %08x\n", (unsigned int) _regs[Lcd_config]);
2.229 + printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
2.230 printf("LCD status: %08x\n", (unsigned int) _regs[Lcd_status]);
2.231 + printf("OSD config: %08x\n", (unsigned int) _regs[Osd_config]);
2.232 + printf("OSD control: %08x\n", (unsigned int) _regs[Osd_control]);
2.233 printf("OSD status: %08x\n", (unsigned int) _regs[Osd_status]);
2.234 - printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
2.235 printf("LCD command: %08x\n", (unsigned int) _regs[Command_0]);
2.236 printf("LCD IRQ id: %08x\n", (unsigned int) _regs[Lcd_irq_id]);
2.237 printf("LCD descriptor: %08x\n", (unsigned int) _regs[Desc_address_0]);
2.238 printf("LCD source: %08x\n", (unsigned int) _regs[Source_address_0]);
2.239 printf("LCD frame id: %08x\n", (unsigned int) _regs[Frame_id_0]);
2.240 -
2.241 - // Return errors immediately.
2.242 -
2.243 - err = l4_ipc_error(tag, l4_utcb());
2.244 - if (err)
2.245 - return err;
2.246 + printf("LCD counter/position: %08x\n", (unsigned int) _regs[Counter_position_0]);
2.247 + printf("LCD foreground size: %08x\n", (unsigned int) _regs[Foreground_size_0]);
2.248 +#endif
2.249
2.250 // Acknowledge interrupts.
2.251
2.252 - _regs[Lcd_status] = _regs[Lcd_status] & ~(_status_irq());
2.253 + _regs[Lcd_status] = 0;
2.254
2.255 - return L4_EOK;
2.256 + // Return errors.
2.257 +
2.258 + //printf("Error: %s\n", l4sys_errtostr(l4_error(tag)));
2.259 + return l4_error(tag);
2.260 }
2.261
2.262
2.263 @@ -1051,6 +1098,12 @@
2.264 }
2.265
2.266 l4_size_t
2.267 +jz4740_lcd_get_line_size(void *lcd)
2.268 +{
2.269 + return static_cast<Lcd_jz4740_chip *>(lcd)->get_line_size();
2.270 +}
2.271 +
2.272 +l4_size_t
2.273 jz4740_lcd_get_screen_size(void *lcd)
2.274 {
2.275 return static_cast<Lcd_jz4740_chip *>(lcd)->get_screen_size();