9 #include <l4/arm_drivers/lcd.h>
11 #include <l4/re/c/dataspace.h>
12 #include <l4/re/c/mem_alloc.h>
13 #include <l4/re/c/namespace.h>
14 #include <l4/re/c/rm.h>
15 #include <l4/re/c/util/cap_alloc.h>
16 #include <l4/util/util.h>
17 #include <l4/vbus/vbus.h>
18 #include <l4/vbus/vbus_gpio.h>
19 #include <l4/vbus/vbus_i2c.h>
21 #include "lcd-omap3.h"
24 /* Beagleboard mode assumes that U-Boot has set up everything and we
25 * basically just need to set the framebuffer address */
32 static inline int is_omap3evm(void) { return lcd_mode == MODE_EVM; }
33 static inline int is_beagleboard(void) { return lcd_mode == MODE_BEAGLEBOARD; }
35 static inline int width(void)
44 static inline int height(void)
53 static inline int bytes_per_pixel(void)
56 static unsigned int fbmem_size(void)
57 { return height() * width() * bytes_per_pixel(); }
60 static l4_addr_t omap_dss_virt_base;
61 static void *fb_vaddr;
62 static l4_addr_t fb_paddr;
63 static l4_cap_idx_t vbus = L4_INVALID_CAP;
64 static l4vbus_device_handle_t i2c_handle;
65 static l4vbus_device_handle_t gpio_handle;
67 static l4_umword_t read_dss_reg(unsigned reg)
69 return *((volatile l4_umword_t *)(omap_dss_virt_base + reg));
72 static void write_dss_reg(unsigned reg, l4_umword_t val)
74 *((volatile l4_umword_t *)(omap_dss_virt_base + reg)) = val;
77 static int disable_dss(void)
79 l4_umword_t val = read_dss_reg(Reg_dispc_control);
81 /* check if digital output or the lcd output are enabled */
82 if (val & (Dispc_control_digitalenable | Dispc_control_lcdenable))
84 /*Disable the lcd output and digital output*/
85 val &= ~(Dispc_control_digitalenable | Dispc_control_lcdenable);
86 write_dss_reg(Reg_dispc_control, val);
87 write_dss_reg(Reg_dispc_irqstatus, Dispc_irqstatus_framedone);
90 if (!(read_dss_reg(Reg_dispc_irqstatus) & Dispc_irqstatus_framedone))
92 printf("OMAP LCD: Disable DSS timeout.\n");
99 static void reset_display_controller(void)
103 /* Reset the display controller. */
104 write_dss_reg(Reg_dispc_sysconfig, Dispc_sysconfig_softreset);
106 /* Wait until reset completes OR timeout occurs. */
108 if (!(read_dss_reg(Reg_dispc_sysstatus) & Dispc_sysstatus_resetdone))
110 printf("[LCD]: Warning: Reset DISPC timeout.\n");
113 l4_uint32_t reg_val = read_dss_reg(Reg_dispc_sysconfig);
114 reg_val &= ~Dispc_sysconfig_softreset;
115 write_dss_reg(Reg_dispc_sysconfig, reg_val);
118 static int enable_lcd_backlight(void)
123 if (l4vbus_i2c_write(vbus, i2c_handle, T2_I2C_LED_ADDR_GROUP, TRITON2_LED_LEDEN_REG, &val, 1))
127 if (l4vbus_i2c_write(vbus, i2c_handle, T2_I2C_LED_ADDR_GROUP, TRITON2_LED_PWMAON_REG, &val, 1))
131 if (l4vbus_i2c_write(vbus, i2c_handle, T2_I2C_LED_ADDR_GROUP, TRITON2_LED_PWMBON_REG, &val, 1))
135 if (l4vbus_i2c_write(vbus, i2c_handle, T2_I2C_LED_ADDR_GROUP, TRITON2_LED_PWMAOFF_REG, &val, 1))
139 if (l4vbus_i2c_write(vbus, i2c_handle, T2_I2C_LED_ADDR_GROUP, TRITON2_LED_PWMBOFF_REG, &val, 1))
143 if (l4vbus_i2c_write(vbus, i2c_handle, 0x4b, TRITON2_VDAC_DEDICATED, &val, 1))
147 if (l4vbus_i2c_write(vbus, i2c_handle, 0x4b, TRITON2_VDAC_DEV_GRP, &val, 1))
153 static int enable_lcd_power(void)
155 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_VDD, 0))
161 static int disable_lcd_power(void)
163 if (l4vbus_gpio_write(vbus, GPIO_NUM_VDD, 1))
169 static int configure_vga_mode(void)
171 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_QVGA_nVGA, 0))
176 static int configure_vert_scan_direction(int direction)
178 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_UD, direction))
183 static int configure_horiz_scan_direction(int direction)
185 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_LR, direction))
190 static int disable_lcd_reset(void)
192 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_RESB, 0))
198 static int enable_lcd_HVIF(void)
200 l4_umword_t val = read_dss_reg(Reg_dispc_pol_freq);
201 val |= ((0 << Dispc_pol_freq_rf_shift) |
202 (1 << Dispc_pol_freq_onoff_shift));
203 write_dss_reg(Reg_dispc_pol_freq, val);
208 static int enable_lcd_reset(void)
210 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_RESB, 1))
215 static int enable_INI(void)
217 if (l4vbus_gpio_write(vbus, gpio_handle, GPIO_NUM_INI, 1))
223 static int disble_INI(void)
225 if (l4vbus_gpio_write(vbus, GPIO_NUM_INI, 0))
231 static void issue_go_lcd(void)
233 l4_umword_t val = read_dss_reg(Reg_dispc_control);
234 val |= Dispc_control_golcd;
235 write_dss_reg(Reg_dispc_control, val);
238 if (read_dss_reg(Reg_dispc_control) & Dispc_control_golcd)
240 printf("[LCD] Info: Update DISPC timeout.\n");
244 static void configure_dss_omap3evm(l4_addr_t frame_buffer)
248 val = read_dss_reg(Reg_dss_control);
250 write_dss_reg(Reg_dss_control, val);
252 /* No standby, No idle,mormal mode, ocp clock free running */
253 //val = Dispc_sysconfig_midlemode_nstandby | Dispc_sysconfig_sidlemode_nidle;
254 //val &= ~Dispc_sysconfig_softreset ;
255 //write_dss_reg(Reg_dispc_sysconfig, val);
256 write_dss_reg(Reg_dispc_sysconfig, 0x2015);
258 /* Not enabling any interrupts */
259 write_dss_reg(Reg_dispc_irqenable, 0x00);
261 /* 2:1 - Frame Data only loaded every frame (10) */
262 write_dss_reg(Reg_dispc_config, Dispc_config_loadmode_frdatlefr);
264 /* Default Color is white */
265 write_dss_reg(Reg_dispc_default_colour0, 0xffffff & Default_colour_mask);
267 /* Default Transparency Color is black */
268 write_dss_reg(Reg_dispc_trans_colour0, 0xffffff & Transparency_colour_mask);
270 /*timing logic for HSYNC signal */
271 val = (38 << Dispc_timing_h_hbp_shift) |
272 (44 << Dispc_timing_h_hfp_shift) |
273 (2 << Dispc_timing_h_hsw_shift);
274 write_dss_reg(Reg_dispc_timing_h, val);
276 /*timing logic for VSYNC signal */
277 val = (1 << Dispc_timing_v_vbp_shift) |
278 (2 << Dispc_timing_v_vfp_shift) |
279 (1 << Dispc_timing_v_vsw_shift) ;
280 write_dss_reg(Reg_dispc_timing_v, val);
282 /*signal configuration*/
283 val = read_dss_reg(Reg_dispc_pol_freq);
284 val |= (0 << Dispc_pol_freq_rf_shift) |
285 (1 << Dispc_pol_freq_onoff_shift) |
286 (1 << Dispc_pol_freq_ipc_shift) |
287 (1 << Dispc_pol_freq_ihs_shift) |
288 (1 << Dispc_pol_freq_ivs_shift);
289 write_dss_reg(Reg_dispc_pol_freq, val);
291 /*configure the divisor*/
292 //val = (1 << Dispc_divisor_lcd_shift) | (3 << Dispc_divisor_pcd_shift);
293 //write_dss_reg(Dispc_divisor, val);
294 write_dss_reg(Reg_dispc_divisor, 0x10012);
297 val = (((width() - 1) << Dispc_size_lcd_ppl_shift) & Dispc_size_lcd_ppl) |
298 (((height() - 1) << Dispc_size_lcd_lpp_shift) & Dispc_size_lcd_lpp);
299 write_dss_reg(Reg_dispc_size_lcd, val);
301 /* Set tft interface width */
302 val = read_dss_reg(Reg_dispc_control);
303 val &= ~Dispc_control_tftdatalines_oalsb16b;
304 val |= Dispc_control_tftdatalines_oalsb18b;
305 write_dss_reg(Reg_dispc_control, val);
307 /* Configure Graphics Window. */
308 write_dss_reg(Reg_dispc_gfx_ba0, frame_buffer);
309 write_dss_reg(Reg_dispc_gfx_ba1, frame_buffer);
310 write_dss_reg(Reg_dispc_gfx_position, 0);
311 val = (((width() - 1) << Dispc_gfx_size_ppl_shift) & Dispc_gfx_size_ppl) |
312 (((height() - 1) << Dispc_gfx_size_lpp_shift) & Dispc_gfx_size_lpp);
313 write_dss_reg(Reg_dispc_gfx_size, val);
315 val = read_dss_reg(Reg_dispc_gfx_attributes);
317 write_dss_reg(Reg_dispc_gfx_attributes, val);
319 val = (252 << Dispc_gfx_fifo_threshold_high_shift) |
320 (192 << Dispc_gfx_fifo_threshold_low_shift);
321 write_dss_reg(Reg_dispc_gfx_fifo_threshold, val);
323 /* Default row inc = 1. */
324 write_dss_reg(Reg_dispc_gfx_row_inc, 1);
325 /* Default pixel inc = 1. */
326 write_dss_reg(Reg_dispc_gfx_pixel_inc, 1);
328 /* Enable GFX pipeline */
329 val = read_dss_reg(Reg_dispc_gfx_attributes);
330 val |= Attributes_enable;
331 write_dss_reg(Reg_dispc_gfx_attributes, val);
335 static void configure_dss_beagleboard(l4_addr_t frame_buffer)
337 // for beagleboard just set the framebuffer address and let it run,
338 // everything else is already configured by U-Boot
339 write_dss_reg(Reg_dispc_gfx_ba0, frame_buffer);
340 write_dss_reg(Reg_dispc_gfx_ba1, frame_buffer);
343 static void configure_dss(l4_addr_t frame_buffer)
346 configure_dss_omap3evm(frame_buffer);
348 if (is_beagleboard())
349 configure_dss_beagleboard(frame_buffer);
351 printf("[LCD] Info: Configured display controller.\n");
354 static void display_lcd_image(void)
360 /* Lcd output enabled, active display, 16-bit output */
361 val = Dispc_control_gpout1 |
362 Dispc_control_gpout0 |
363 Dispc_control_tftdatalines_oalsb18b |
364 Dispc_control_stntft |
365 Dispc_control_lcdenable;
366 val &= ~Dispc_control_rfbimode;
367 write_dss_reg(Reg_dispc_control, val);
373 static int configure_lcd(l4_addr_t frame_buffer)
377 reset_display_controller();
378 if (enable_lcd_backlight())
380 if (enable_lcd_power())
382 if (configure_vga_mode())
388 configure_vert_scan_direction(CONV_SCAN_DIRECTION);
389 configure_horiz_scan_direction(CONV_SCAN_DIRECTION);
392 configure_dss(frame_buffer);
394 //enable_replication_logic(GFX_PIPELINE);
405 vbus = l4re_get_env_cap("vbus");
407 if (l4_is_invalid_cap(vbus))
409 printf("[LCD] Error: Could not query <vbus> capability\n");
413 if (l4vbus_get_device_by_hid(vbus, 0, &i2c_handle, "i2c", 0, 0))
415 printf("[LCD] Error: Could not find <i2c> vbus device\n");
419 if (l4vbus_get_device_by_hid(vbus, 0, &gpio_handle, "gpio", 0, 0))
421 printf("[LCD] Error: Could not find <gpio> vbus device\n");
426 return configure_lcd(fb_paddr);
429 static void setup_memory(void)
438 ret = l4io_request_iomem(0x48050000, 0x1000, 0, &omap_dss_virt_base);
441 printf("[LCD] Error: Could not map device memory\n");
445 // get some frame buffer
446 l4re_ds_t mem = l4re_util_cap_alloc();
447 if (l4_is_invalid_cap(mem))
450 if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED))
452 printf("[LCD] Error: Could not allocate memory\n");
457 if (l4re_rm_attach(&fb_vaddr, fbmem_size(),
458 L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
459 mem, 0, L4_PAGESHIFT))
461 printf("[LCD] Error: Could not attach memory\n");
465 printf("[LCD] Info: Video memory is at virtual %p (size: 0x%x Bytes)\n",
466 fb_vaddr, fbmem_size());
468 // get physical address
469 if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size)
470 || phys_size != fbmem_size())
472 printf("[LCD] Error: Could not get physical address\n");
475 printf("[LCD] Info: Physical video memory is at %p\n", (void *)fb_paddr);
479 static int lcd_probe(const char *configstr)
481 lcd_mode = MODE_BEAGLEBOARD;
484 (strstr(configstr, "evm")
485 || strstr(configstr, "init")))
488 return !l4io_lookup_device("OMAP_LCD", NULL, 0, 0);
491 static void *lcd_get_fb(void)
499 static unsigned int lcd_fbmem_size(void) { return fbmem_size(); }
501 static const char *lcd_get_info(void)
503 if (is_beagleboard())
504 return "ARM OMAP3 Beagleboard LCD";
507 return "ARM OMAP3EVM LCD";
509 return "ARM OMAP3EVM unknown";
512 static int get_fbinfo(l4re_video_view_info_t *vinfo)
514 vinfo->width = width();
515 vinfo->height = height();
516 vinfo->bytes_per_line = bytes_per_pixel() * vinfo->width;
518 vinfo->pixel_info.bytes_per_pixel = bytes_per_pixel();
519 vinfo->pixel_info.r.shift = 0;
520 vinfo->pixel_info.r.size = 5;
521 vinfo->pixel_info.g.shift = 5;
522 vinfo->pixel_info.g.size = 6;
523 vinfo->pixel_info.b.shift = 11;
524 vinfo->pixel_info.b.size = 5;
525 vinfo->pixel_info.a.shift = 0;
526 vinfo->pixel_info.a.size = 0;
530 static void lcd_enable(void)
536 printf("CLCD init failed!\n");
541 static void lcd_disable(void)
543 printf("%s unimplemented.\n", __func__);
546 static struct arm_lcd_ops arm_lcd_ops_omap3 = {
548 .get_fb = lcd_get_fb,
549 .get_fbinfo = get_fbinfo,
550 .get_video_mem_size = lcd_fbmem_size,
551 .get_info = lcd_get_info,
552 .enable = lcd_enable,
553 .disable = lcd_disable,
556 arm_lcd_register(&arm_lcd_ops_omap3);