1.1 --- a/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Fri Jun 05 23:45:28 2020 +0200
1.2 +++ b/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Fri Jun 05 23:59:12 2020 +0200
1.3 @@ -23,6 +23,7 @@
1.4
1.5 #include <l4/devices/hw_mmio_register_block.h>
1.6 #include <l4/sys/cache.h>
1.7 +#include <l4/sys/err.h>
1.8 #include <l4/sys/irq.h>
1.9 #include <l4/sys/types.h>
1.10 #include <l4/util/util.h>
1.11 @@ -52,11 +53,16 @@
1.12 Source_address_0 = 0x044, // LCD_SA0
1.13 Frame_id_0 = 0x048, // LCD_FID0
1.14 Command_0 = 0x04c, // LCD_CMD0
1.15 + Counter_position_0 = 0x068, // LCD_CPOS0
1.16 + Foreground_size_0 = 0x06c, // LCD_DESSIZE0
1.17 Desc_address_1 = 0x050, // LCD_DA1
1.18 Source_address_1 = 0x054, // LCD_SA1
1.19 Frame_id_1 = 0x058, // LCD_FID1
1.20 Command_1 = 0x05c, // LCD_CMD1
1.21 + Counter_position_1 = 0x078, // LCD_CPOS1
1.22 + Foreground_size_1 = 0x07c, // LCD_DESSIZE1
1.23 Rgb_control = 0x090, // LCD_RGBC (JZ4780)
1.24 + Alpha_levels = 0x108, // LCD_ALPHA (JZ4780)
1.25 Priority_level = 0x2c0, // LCD_PCFG
1.26
1.27 // OSD registers.
1.28 @@ -186,6 +192,9 @@
1.29 {
1.30 Status_frame_end_irq = 5,
1.31 Status_frame_start_irq = 4,
1.32 + Status_out_underrun_irq = 3,
1.33 + Status_in0_underrun_irq = 2,
1.34 + Status_in1_underrun_irq = 1,
1.35 Status_disabled = 0,
1.36 };
1.37
1.38 @@ -193,13 +202,23 @@
1.39
1.40 enum Osd_config_bits : unsigned
1.41 {
1.42 + Osd_config_fg1_pixel_alpha_enable = 17,
1.43 Osd_config_fg1_frame_start_irq_enable = 15,
1.44 Osd_config_fg1_frame_end_irq_enable = 14,
1.45 Osd_config_fg0_frame_start_irq_enable = 11,
1.46 Osd_config_fg0_frame_end_irq_enable = 10,
1.47 + Osd_config_fg1_enable = 4,
1.48 + Osd_config_fg0_enable = 3,
1.49 + Osd_config_alpha_enable = 2,
1.50 + Osd_config_fg0_pixel_alpha_enable = 1,
1.51 Osd_config_enable = 0,
1.52 };
1.53
1.54 +enum Osd_control_bits : unsigned
1.55 +{
1.56 + Osd_control_ipu_clock_enable = 15,
1.57 +};
1.58 +
1.59 // RGB control (JZ4780).
1.60
1.61 enum Rgb_control_bits : unsigned
1.62 @@ -230,6 +249,20 @@
1.63 Rgb_even_line_bgr = 5U << Rgb_even_line,
1.64 };
1.65
1.66 +// Alpha levels (JZ4780).
1.67 +
1.68 +enum Alpha_levels_bits : unsigned
1.69 +{
1.70 + Alpha_level_fg1 = 8,
1.71 + Alpha_level_fg0 = 0,
1.72 +};
1.73 +
1.74 +enum Alpha_levels_values : unsigned
1.75 +{
1.76 + Alpha_level_fg1_mask = 0x0000ff00,
1.77 + Alpha_level_fg0_mask = 0x000000ff,
1.78 +};
1.79 +
1.80 // Priority level.
1.81
1.82 enum Priority_level_bits : unsigned
1.83 @@ -317,8 +350,8 @@
1.84 : _panel(panel)
1.85 {
1.86 _regs = new Hw::Mmio_register_block<32>(addr);
1.87 - //_burst_size = 64; // 64-word burst size (JZ4780)
1.88 - _burst_size = 16; // 16-word burst size
1.89 + _burst_size = 64; // 64-word burst size (JZ4780)
1.90 + //_burst_size = 16; // 16-word burst size
1.91
1.92 // add_cid("lcd");
1.93 // add_cid("lcd-jz4740");
1.94 @@ -684,7 +717,8 @@
1.95 uint32_t
1.96 Lcd_jz4740_chip::_control_irq()
1.97 {
1.98 - return ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Control_frame_start_irq_enable) : 0) |
1.99 + return // (1U << Control_out_underrun_irq_enable) |
1.100 + ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Control_frame_start_irq_enable) : 0) |
1.101 ((_irq_conditions & Lcd_irq_frame_end) ? (1U << Control_frame_end_irq_enable) : 0);
1.102 }
1.103
1.104 @@ -711,7 +745,8 @@
1.105 uint32_t
1.106 Lcd_jz4740_chip::_status_irq()
1.107 {
1.108 - return ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Status_frame_start_irq) : 0) |
1.109 + return // (1U << Status_out_underrun_irq) |
1.110 + ((_irq_conditions & Lcd_irq_frame_start) ? (1U << Status_frame_start_irq) : 0) |
1.111 ((_irq_conditions & Lcd_irq_frame_end) ? (1U << Status_frame_end_irq) : 0);
1.112 }
1.113
1.114 @@ -834,30 +869,28 @@
1.115 Lcd_jz4740_chip::_set_descriptor(struct Jz4740_lcd_descriptor &desc,
1.116 l4_addr_t source, l4_size_t size,
1.117 struct Jz4740_lcd_descriptor *next,
1.118 - uint32_t flags)
1.119 + uint32_t flags,
1.120 + bool frame_enable)
1.121 {
1.122 // In the command, indicate the number of words from the source for transfer.
1.123
1.124 desc.next = next;
1.125 - desc.source = source;
1.126 + desc.source = frame_enable ? source : 0;
1.127 desc.identifier = source;
1.128 desc.command = ((size / sizeof(uint32_t)) & Command_buffer_length_mask) |
1.129 - (1U << Command_frame_enable) |
1.130 + (frame_enable ? (1U << Command_frame_enable) : 0) |
1.131 flags;
1.132
1.133 - printf("next = %08x\n", desc.next);
1.134 - printf("source = %08x\n", desc.source);
1.135 - printf("identifier = %08x\n", desc.identifier);
1.136 - printf("command = %08x\n", desc.command);
1.137 -
1.138 // Initialise "new" descriptor fields.
1.139
1.140 desc.offset = 0;
1.141 desc.page_width = 0;
1.142 - desc.command_position = (1UL << Position_premultiply_lcd) |
1.143 - (1UL << Position_coefficient) |
1.144 + desc.command_position = (1U << Position_premultiply_lcd) |
1.145 + ((frame_enable ? 1U : 3U) << Position_coefficient) |
1.146 _position_bpp();
1.147 - desc.fg_size = 0xff000000 | (1023 << 12) | (1279 << 0); // JZ4780 driver magic
1.148 + desc.fg_size = 0xff000000 |
1.149 + ((_panel->height - 1) << 12) |
1.150 + ((_panel->width - 1) << 0);
1.151 }
1.152
1.153
1.154 @@ -875,6 +908,8 @@
1.155
1.156 int have_palette = (_panel->bpp <= 8);
1.157
1.158 + bool _have_fg1 = true; // NOTE: To be formalised!
1.159 +
1.160 // Provide the first framebuffer descriptor in single and dual modes.
1.161 // Flip back and forth between any palette and the framebuffer.
1.162
1.163 @@ -886,11 +921,12 @@
1.164 // Provide the second framebuffer descriptor only in dual-panel mode.
1.165 // Only employ this descriptor in the second DMA channel.
1.166
1.167 - if (get_panels() == 2)
1.168 + if ((get_panels() == 2) || _have_fg1)
1.169 _set_descriptor(desc_vaddr[1], get_framebuffer(1, fb_paddr),
1.170 get_aligned_size(),
1.171 desc_paddr + 1,
1.172 - _command_irq());
1.173 + _command_irq(),
1.174 + false);
1.175
1.176 // Initialise palette descriptor details for lower colour depths.
1.177
1.178 @@ -910,11 +946,10 @@
1.179 // Provide the palette descriptor address first, if employed.
1.180
1.181 _regs[Desc_address_0] = (uint32_t) (have_palette ? desc_paddr + 2 : desc_paddr);
1.182 - printf("descriptor = %08x\n", (uint32_t) _regs[Desc_address_0]);
1.183
1.184 // Provide a descriptor for the second DMA channel in dual-panel mode.
1.185
1.186 - if (get_panels() == 2)
1.187 + if ((get_panels() == 2) || _have_fg1)
1.188 _regs[Desc_address_1] = (uint32_t) (desc_paddr + 1);
1.189
1.190 // Initialise panel-related registers.
1.191 @@ -931,10 +966,15 @@
1.192
1.193 _regs[Rgb_control] = (1U << Rgb_format_enable) | Rgb_odd_line_rgb | Rgb_even_line_rgb;
1.194 _regs[Priority_level] = _priority_transfer();
1.195 - _regs[Osd_config] = 0; // (1U << Osd_config_enable) | _osd_config_irq();
1.196 + _regs[Osd_config] = //_osd_config_irq() |
1.197 + (1U << Osd_config_enable) |
1.198 + (1U << Osd_config_alpha_enable);
1.199 + _regs[Alpha_levels] = ((255U << Alpha_level_fg1) & Alpha_level_fg1_mask) |
1.200 + ((255U << Alpha_level_fg0) & Alpha_level_fg0_mask);
1.201
1.202 printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
1.203 printf("LCD status: %08x\n", (unsigned int) _regs[Lcd_status]);
1.204 + printf("OSD control: %08x\n", (unsigned int) _regs[Osd_control]);
1.205 printf("OSD config: %08x\n", (unsigned int) _regs[Osd_config]);
1.206 printf("OSD status: %08x\n", (unsigned int) _regs[Osd_status]);
1.207 }
1.208 @@ -953,35 +993,42 @@
1.209 long
1.210 Lcd_jz4740_chip::wait_for_irq()
1.211 {
1.212 - long err;
1.213 l4_msgtag_t tag;
1.214
1.215 _regs[Lcd_status] = _regs[Lcd_status] & ~(_status_irq());
1.216
1.217 // Wait for a condition.
1.218
1.219 - printf("Waiting for IRQ...\n");
1.220 - tag = l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(1000000)));
1.221 + //printf("Waiting for IRQ...\n");
1.222 + tag = l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(2000000)));
1.223 +
1.224 + //if (_regs[Lcd_status] & (1U << Status_out_underrun_irq))
1.225 + // enable();
1.226 +
1.227 +#if 0
1.228 + printf("LCD config: %08x\n", (unsigned int) _regs[Lcd_config]);
1.229 + printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
1.230 printf("LCD status: %08x\n", (unsigned int) _regs[Lcd_status]);
1.231 + printf("OSD config: %08x\n", (unsigned int) _regs[Osd_config]);
1.232 + printf("OSD control: %08x\n", (unsigned int) _regs[Osd_control]);
1.233 printf("OSD status: %08x\n", (unsigned int) _regs[Osd_status]);
1.234 - printf("LCD control: %08x\n", (unsigned int) _regs[Lcd_control]);
1.235 printf("LCD command: %08x\n", (unsigned int) _regs[Command_0]);
1.236 printf("LCD IRQ id: %08x\n", (unsigned int) _regs[Lcd_irq_id]);
1.237 printf("LCD descriptor: %08x\n", (unsigned int) _regs[Desc_address_0]);
1.238 printf("LCD source: %08x\n", (unsigned int) _regs[Source_address_0]);
1.239 printf("LCD frame id: %08x\n", (unsigned int) _regs[Frame_id_0]);
1.240 -
1.241 - // Return errors immediately.
1.242 -
1.243 - err = l4_ipc_error(tag, l4_utcb());
1.244 - if (err)
1.245 - return err;
1.246 + printf("LCD counter/position: %08x\n", (unsigned int) _regs[Counter_position_0]);
1.247 + printf("LCD foreground size: %08x\n", (unsigned int) _regs[Foreground_size_0]);
1.248 +#endif
1.249
1.250 // Acknowledge interrupts.
1.251
1.252 - _regs[Lcd_status] = _regs[Lcd_status] & ~(_status_irq());
1.253 + _regs[Lcd_status] = 0;
1.254
1.255 - return L4_EOK;
1.256 + // Return errors.
1.257 +
1.258 + //printf("Error: %s\n", l4sys_errtostr(l4_error(tag)));
1.259 + return l4_error(tag);
1.260 }
1.261
1.262
1.263 @@ -1051,6 +1098,12 @@
1.264 }
1.265
1.266 l4_size_t
1.267 +jz4740_lcd_get_line_size(void *lcd)
1.268 +{
1.269 + return static_cast<Lcd_jz4740_chip *>(lcd)->get_line_size();
1.270 +}
1.271 +
1.272 +l4_size_t
1.273 jz4740_lcd_get_screen_size(void *lcd)
1.274 {
1.275 return static_cast<Lcd_jz4740_chip *>(lcd)->get_screen_size();