]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
karo: tx51: update video mode handling code
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 21 Oct 2013 13:24:49 +0000 (15:24 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 21 Oct 2013 13:24:49 +0000 (15:24 +0200)
board/karo/tx51/tx51.c

index 4bd44fea04685a867d16408d5d5147613698e085..618110bd1fe2a68bc13211dc7db38d34bf51a48e 100644 (file)
@@ -1,14 +1,13 @@
 /*
- * Copyright (C) 2011 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
  * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -545,14 +544,12 @@ static const struct gpio stk5_gpios[] = {
 };
 
 #ifdef CONFIG_LCD
-static ushort tx51_cmap[256];
 vidinfo_t panel_info = {
        /* set to max. size supported by SoC */
        .vl_col = 1600,
        .vl_row = 1200,
 
        .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
-       .cmap = tx51_cmap,
 };
 
 static struct fb_videomode tx51_fb_modes[] = {
@@ -698,8 +695,9 @@ void lcd_enable(void)
         */
        lcd_is_enabled = 0;
 
-       karo_load_splashimage(1);
        if (lcd_enabled) {
+               karo_load_splashimage(1);
+
                debug("Switching LCD on\n");
                gpio_set_value(TX51_LCD_PWR_GPIO, 1);
                udelay(100);
@@ -711,7 +709,10 @@ void lcd_enable(void)
 
 void lcd_disable(void)
 {
-       printf("Disabling LCD\n");
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
 }
 
 void lcd_panel_disable(void)
@@ -788,6 +789,7 @@ void lcd_ctrl_init(void *lcdbase)
        if (tstc() || (wrsr & WRSR_TOUT)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
@@ -803,10 +805,14 @@ void lcd_ctrl_init(void *lcdbase)
                p = &fb_mode;
                debug("Using video mode from FDT\n");
                vm += strlen(vm);
-               if (fb_mode.xres < panel_info.vl_col)
-                       panel_info.vl_col = fb_mode.xres;
-               if (fb_mode.yres < panel_info.vl_row)
-                       panel_info.vl_row = fb_mode.yres;
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
        }
        if (p->name != NULL)
                debug("Trying compiled-in video modes\n");
@@ -843,6 +849,7 @@ void lcd_ctrl_init(void *lcdbase)
                                        case 8:
                                        case 16:
                                        case 24:
+                                       case 32:
                                                color_depth = val;
                                                break;
 
@@ -896,6 +903,28 @@ void lcd_ctrl_init(void *lcdbase)
                printf("\n");
                return;
        }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch(color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR24;
+       }
+       printf("xres=%d left_margin=%d right_margin=%d hsync_len=%d yres=%d upper_margin=%d lower_margin=%d vsync_len=%d\n",
+               p->xres, p->left_margin, p->right_margin, p->hsync_len,
+               p->yres, p->upper_margin, p->lower_margin, p->vsync_len);
 
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
@@ -905,6 +934,18 @@ void lcd_ctrl_init(void *lcdbase)
                PICOS2KHZ(p->pixclock) / 1000,
                PICOS2KHZ(p->pixclock) % 1000);
 
+       if (p != &fb_mode) {
+               int ret;
+               char *modename = getenv("video_mode");
+
+               printf("Creating new display-timing node from '%s'\n",
+                       modename);
+               ret = karo_fdt_create_fb_mode(working_fdt, modename, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               modename, ret);
+       }
+
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
        imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
                                        ARRAY_SIZE(stk5_lcd_pads));
@@ -914,16 +955,22 @@ void lcd_ctrl_init(void *lcdbase)
                pix_fmt = IPU_PIX_FMT_RGB24;
 
        if (karo_load_splashimage(0) == 0) {
+               int ret;
                struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
                u32 ccgr4 = readl(&ccm_regs->CCGR4);
 
                /* MIPI HSC clock is required for initialization */
                writel(ccgr4 | (3 << 12), &ccm_regs->CCGR4);
 
-               debug("Initializing LCD controller\n");
-               ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3DEX;
 
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
                writel(ccgr4 & ~(3 << 12), &ccm_regs->CCGR4);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
        } else {
                debug("Skipping initialization of LCD controller\n");
        }
@@ -1029,5 +1076,6 @@ void ft_board_setup(void *blob, bd_t *bd)
 
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "fsl,imx-otg", "fsl,usbphy");
+       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
 }
 #endif