]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'tx28-bugfix' into karo-tx-merge
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 21 Oct 2013 13:42:34 +0000 (15:42 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 21 Oct 2013 13:42:34 +0000 (15:42 +0200)
board/karo/common/fdt.c
board/karo/tx48/tx48.c
board/karo/tx51/lowlevel_init.S
board/karo/tx51/tx51.c
board/karo/tx53/tx53.c
board/karo/tx6/flash.c
board/karo/tx6/tx6qdl.c
common/cmd_bootce.c
include/wince.h
net/bootme.c

index 192e68816a4db9522e19ace6d55bbc420b5878e9..c942e8af52753b73fb70a3ecf41bb53a2b1474d7 100644 (file)
@@ -20,6 +20,7 @@
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <nand.h>
+#include <mxcfb.h>
 #include <linux/list.h>
 #include <linux/fb.h>
 #include <jffs2/load_kernel.h>
@@ -161,8 +162,8 @@ void karo_fdt_fixup_touchpanel(void *blob)
                                continue;
                }
                fdt_disable_tp_node(blob, karo_touchpanels[i]);
-               karo_set_fdtsize(blob);
        }
+       karo_set_fdtsize(blob);
 }
 
 void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy)
@@ -319,14 +320,14 @@ static int fdt_init_fb_mode(const void *blob, int off, struct fb_videomode *fb_m
        prop = fdt_getprop(blob, off, "vsync-active", NULL);
        if (prop)
                fb_mode->sync |= *prop ? FB_SYNC_VERT_HIGH_ACT : 0;
-#if 0
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
        prop = fdt_getprop(blob, off, "de-active", NULL);
        if (prop)
-               fb_mode->sync |= *prop ? FB_SYNC_DATA_ENABLE_HIGH_ACT : 0;
+               fb_mode->sync |= *prop ? 0 : FB_SYNC_OE_LOW_ACT;
 
        prop = fdt_getprop(blob, off, "pixelclk-active", NULL);
        if (prop)
-               fb_mode->sync |= *prop ? FB_SYNC_DOTCLK_FALLING_ACT : 0;
+               fb_mode->sync |= *prop ? 0 : FB_SYNC_CLK_LAT_FALL;
 #endif
        return 0;
 }
@@ -336,16 +337,12 @@ static int fdt_update_native_fb_mode(void *blob, int off)
        int ret;
        uint32_t ph;
 
+       ret = fdt_increase_size(blob, 32);
+       if (ret) {
+               printf("Warning: Failed to increase FDT size: %d\n", ret);
+       }
        debug("Creating phandle at offset %d\n", off);
        ph = fdt_create_phandle(blob, off);
-       if (!ph) {
-               ret = fdt_increase_size(blob, 512);
-               if (ret) {
-                       printf("Failed to increase FDT size: %d\n", ret);
-                       return ret;
-               }
-               ph = fdt_create_phandle(blob, off);
-       }
        if (!ph) {
                printf("Failed to create phandle for video timing\n");
                return -ENOMEM;
@@ -425,8 +422,7 @@ int karo_fdt_get_fb_mode(void *blob, const char *name, struct fb_videomode *fb_m
                }
        }
        if (off > 0) {
-               fdt_init_fb_mode(blob, off, fb_mode);
-               return fdt_update_native_fb_mode(blob, off);
+               return fdt_init_fb_mode(blob, off, fb_mode);
        }
        return -EINVAL;
 }
@@ -515,16 +511,24 @@ int karo_fdt_create_fb_mode(void *blob, const char *name,
        if (ret)
                goto out;
 
-       /* TOTO: make these configurable */
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       ret = SET_FB_PROP("de-active",
+                       !(fb_mode->sync & FB_SYNC_OE_LOW_ACT));
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("pixelclk-active",
+                       !(fb_mode->sync & FB_SYNC_CLK_LAT_FALL));
+       if (ret)
+               goto out;
+#else
+       /* TODO: make these configurable */
        ret = SET_FB_PROP("de-active", 1);
        if (ret)
                goto out;
        ret = SET_FB_PROP("pixelclk-active", 1);
        if (ret)
                goto out;
-
-       return fdt_update_native_fb_mode(blob, off);
-
+#endif
 out:
        karo_set_fdtsize(blob);
        return ret;
index d035e188946065886f97f819a818b43847a3b968..9bf75f8962cc726e3d33a3a92663c3d7cadcefb0 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  *
  * 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 version 2.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
  *
  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  * kind, whether express or implied; without even the implied warranty
index 379003ef1d08e1e9443b3979a1647013cf8b6f74..0b695520b2006d72591dfa48f91b83fd1656c942 100644 (file)
@@ -125,15 +125,6 @@ dcd_data:
 dcd_len:
        .long   dcd_end - dcd_start
 dcd_start:
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR0, 0xffcffffc);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR1, 0x003fffff);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR2, 0x030c003c);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR3, 0x000000ff);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR4, 0x00000000);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR5, 0x003fc003);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CCGR6, 0x00000000);
-       DCDGEN(4, CCM_BASE_ADDR + REG_CMEOR, 0x00000000);
-
        DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCTL0, 0x80000000)
        DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x04008008)
        DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00008010)
index bdf1d101caceb36196eadec9bbd25a7154d54025..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
@@ -57,7 +56,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define FEC_PAD_CTRL           MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
                                        PAD_CTL_SRE_FAST)
 #define FEC_PAD_CTRL2          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_SRE_FAST)
-#define GPIO_PAD_CTRL          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+#define GPIO_PAD_CTRL          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP)
 
 static iomux_v3_cfg_t tx51_pads[] = {
        /* NAND flash pads are set up in lowlevel_init.S */
@@ -226,14 +225,8 @@ static void tx51_print_cpuinfo(void)
 
 int board_early_init_f(void)
 {
-       struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
+       struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
 
-#ifdef CONFIG_CMD_BOOTCE
-       /* WinCE fails to enable these clocks */
-       writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
-       writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
-       writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
-#endif
        gpio_request_array(tx51_gpios, ARRAY_SIZE(tx51_gpios));
        imx_iomux_v3_setup_multiple_pads(tx51_pads, ARRAY_SIZE(tx51_pads));
 
@@ -255,6 +248,20 @@ int board_early_init_f(void)
        writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
        writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
 
+       writel(0xffcffffc, &ccm_regs->CCGR0);
+       writel(0x003fffff, &ccm_regs->CCGR1);
+       writel(0x030c003c, &ccm_regs->CCGR2);
+       writel(0x000000ff, &ccm_regs->CCGR3);
+       writel(0x00000000, &ccm_regs->CCGR4);
+       writel(0x003fc003, &ccm_regs->CCGR5);
+       writel(0x00000000, &ccm_regs->CCGR6);
+       writel(0x00000000, &ccm_regs->cmeor);
+#ifdef CONFIG_CMD_BOOTCE
+       /* WinCE fails to enable these clocks */
+       writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
+       writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
+       writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
+#endif
        return 0;
 }
 
@@ -307,7 +314,7 @@ static const iomux_v3_cfg_t mmc0_pads[] = {
        MX51_PAD_SD1_DATA2__SD1_DATA2,
        MX51_PAD_SD1_DATA3__SD1_DATA3,
        /* SD1 CD */
-       MX51_PAD_DISPB2_SER_RS__GPIO3_8 | MUX_PAD_CTRL(PAD_CTL_PUE | PAD_CTL_PKE),
+       MX51_PAD_DISPB2_SER_RS__GPIO3_8 | GPIO_PAD_CTRL,
 };
 
 static const iomux_v3_cfg_t mmc1_pads[] = {
@@ -318,7 +325,7 @@ static const iomux_v3_cfg_t mmc1_pads[] = {
        MX51_PAD_SD2_DATA2__SD2_DATA2,
        MX51_PAD_SD2_DATA3__SD2_DATA3,
        /* SD2 CD */
-       MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | MUX_PAD_CTRL(PAD_CTL_PUE | PAD_CTL_PKE),
+       MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | GPIO_PAD_CTRL,
 };
 
 static struct tx51_esdhc_cfg {
@@ -332,6 +339,7 @@ static struct tx51_esdhc_cfg {
                .num_pads = ARRAY_SIZE(mmc0_pads),
                .cfg = {
                        .esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
                },
                .cd_gpio = IMX_GPIO_NR(3, 8),
        },
@@ -340,15 +348,13 @@ static struct tx51_esdhc_cfg {
                .num_pads = ARRAY_SIZE(mmc1_pads),
                .cfg = {
                        .esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
                },
                .cd_gpio = IMX_GPIO_NR(3, 6),
        },
 };
 
-static struct tx51_esdhc_cfg *to_tx51_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
-{
-       return container_of(cfg, struct tx51_esdhc_cfg, cfg);
-}
+#define to_tx51_esdhc_cfg(p) container_of(p, struct tx51_esdhc_cfg, cfg)
 
 int board_mmc_getcd(struct mmc *mmc)
 {
@@ -513,18 +519,18 @@ void show_activity(int arg)
 
 static const iomux_v3_cfg_t stk5_pads[] = {
        /* SW controlled LED on STK5 baseboard */
-       MX51_PAD_CSI2_D13__GPIO4_10,
+       MX51_PAD_CSI2_D13__GPIO4_10 | GPIO_PAD_CTRL,
 
        /* USB PHY reset */
-       MX51_PAD_GPIO1_4__GPIO1_4,
+       MX51_PAD_GPIO1_4__GPIO1_4 | GPIO_PAD_CTRL,
        /* USBOTG OC */
-       MX51_PAD_GPIO1_6__GPIO1_6,
+       MX51_PAD_GPIO1_6__GPIO1_6 | GPIO_PAD_CTRL,
        /* USB PHY clock enable */
-       MX51_PAD_GPIO1_7__GPIO1_7,
+       MX51_PAD_GPIO1_7__GPIO1_7 | GPIO_PAD_CTRL,
        /* USBH1 VBUS enable */
-       MX51_PAD_GPIO1_8__GPIO1_8,
+       MX51_PAD_GPIO1_8__GPIO1_8 | GPIO_PAD_CTRL,
        /* USBH1 OC */
-       MX51_PAD_GPIO1_9__GPIO1_9,
+       MX51_PAD_GPIO1_9__GPIO1_9 | GPIO_PAD_CTRL,
 };
 
 static const struct gpio stk5_gpios[] = {
@@ -538,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[] = {
@@ -691,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);
@@ -704,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)
@@ -781,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;
        }
 
@@ -796,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");
@@ -836,6 +849,7 @@ void lcd_ctrl_init(void *lcdbase)
                                        case 8:
                                        case 16:
                                        case 24:
+                                       case 32:
                                                color_depth = val;
                                                break;
 
@@ -889,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) *
@@ -898,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));
@@ -907,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");
        }
@@ -1022,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
index 51845f8ac4168d0d87ec7b9db04f48786ff93718..2684bd9611ce94ed55bbb3f1370319df5090881d 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
@@ -314,16 +313,7 @@ static struct tx53_esdhc_cfg {
        },
 };
 
-#if 1
 #define to_tx53_esdhc_cfg(p) container_of(p, struct tx53_esdhc_cfg, cfg)
-#else
-static struct tx53_esdhc_cfg *to_tx53_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
-{
-       void *p = cfg;
-
-       return p - offsetof(struct tx53_esdhc_cfg, cfg);
-}
-#endif
 
 int board_mmc_getcd(struct mmc *mmc)
 {
@@ -489,14 +479,12 @@ static const struct gpio stk5_gpios[] = {
 };
 
 #ifdef CONFIG_LCD
-static ushort tx53_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 = tx53_cmap,
 };
 
 static struct fb_videomode tx53_fb_modes[] = {
@@ -642,8 +630,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(TX53_LCD_PWR_GPIO, 1);
                udelay(100);
@@ -655,7 +644,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)
@@ -746,6 +738,7 @@ void lcd_ctrl_init(void *lcdbase)
        if (tstc() || (wrsr & WRSR_TOUT)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
@@ -878,6 +871,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));
@@ -898,8 +903,16 @@ void lcd_ctrl_init(void *lcdbase)
        }
 
        if (karo_load_splashimage(0) == 0) {
+               int ret;
+
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3M;
+
                debug("Initializing LCD controller\n");
-               ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
        } else {
                debug("Skipping initialization of LCD controller\n");
        }
@@ -1026,17 +1039,17 @@ void tx53_fixup_rtc(void *blob)
 static inline void tx53_fixup_rtc(void *blob)
 {
 }
-#endif
+#endif /* CONFIG_SYS_TX53_HWREV_2 */
 
 void ft_board_setup(void *blob, bd_t *bd)
 {
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
        fdt_fixup_ethernet(blob);
 
-       karo_fdt_enable_node(blob, "ipu", getenv("video_mode") != NULL);
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "fsl,imx-otg", "fsl,usbphy");
        tx53_fixup_flexcan(blob);
        tx53_fixup_rtc(blob);
+       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
 }
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
index 540b360e46507e1ca0b04ca62e404cf09b3e7838..1ac189b16b0a129cab6bd1bb086ac6b1ab4fd9c0 100644 (file)
@@ -650,7 +650,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 }
 
 U_BOOT_CMD(romupdate, 11, 0, do_update,
-       "Creates an FCB data structure and writes an U-Boot image to flash\n",
+       "Creates an FCB data structure and writes an U-Boot image to flash",
        "[-f #] [-r [#]] [-e #] [<address>] [<length>]\n"
        "\t-f #\twrite bootloader image at block #\n"
        "\t-r\twrite redundant bootloader image at next free block after first image\n"
index c979c476c95c6fb5f05fadacb336d8edb1411fd4..15324068d4c412c82287b5f2242b89da8071bf0a 100644 (file)
@@ -1,23 +1,18 @@
 /*
- * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2012,2013 Lothar Waßmann <LW@KARO-electronics.de>
  *
  * 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
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
  */
 
 #include <common.h>
@@ -753,7 +748,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)
@@ -964,6 +962,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));
@@ -1067,6 +1077,13 @@ int board_late_init(void)
                        strcmp(baseboard, "stk5-v3") == 0) {
                        stk5v3_board_init();
                } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
                        stk5v5_board_init();
                } else {
                        printf("WARNING: Unsupported STK5 board rev.: %s\n",
@@ -1123,25 +1140,94 @@ struct node_info nodes[] = {
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif
 
-static void tx6qdl_fixup_flexcan(void *blob)
+static int flexcan_enabled(void *blob)
 {
-       const char *baseboard = getenv("baseboard");
+       const char *can_ifs[] = {
+               "can0",
+               "can1",
+       };
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(can_ifs); i++) {
+               const char *status;
+               int off = fdt_path_offset(blob, can_ifs[i]);
+
+               if (off < 0) {
+                       debug("node '%s' not found\n", can_ifs[i]);
+                       continue;
+               }
+               status = fdt_getprop(blob, off, "status", NULL);
+               if (strcmp(status, "okay") == 0) {
+                       debug("%s is enabled\n", can_ifs[i]);
+                       return 1;
+               }
+       }
+       debug("can driver is disabled\n");
+       return 0;
+}
+
+static void tx6qdl_set_lcd_pins(void *blob, const char *name)
+{
+       int off = fdt_path_offset(blob, name);
+       u32 ph;
+       const struct fdt_property *pc;
+       int len;
+
+       if (off < 0)
+               return;
 
-       if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
+       ph = fdt_create_phandle(blob, off);
+       if (!ph)
                return;
 
-       karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x02090000, "transceiver-switch");
-       karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x02094000, "transceiver-switch");
+       off = fdt_path_offset(blob, "display");
+       if (off < 0)
+               return;
+
+       pc = fdt_get_property(blob, off, "pinctrl-0", &len);
+       if (!pc || len < sizeof(ph))
+               return;
+
+       memcpy((void *)pc->data, &ph, sizeof(ph));
+       fdt_setprop_cell(blob, off, "pinctrl-0", ph);
+}
+
+static void tx6qdl_fixup_flexcan(void *blob, int stk5_v5)
+{
+       const char *xcvr_status = "disabled";
+
+       if (stk5_v5) {
+               if (flexcan_enabled(blob)) {
+                       tx6qdl_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+                       xcvr_status = "okay";
+               } else {
+                       tx6qdl_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+               }
+       } else {
+               const char *otg_mode = getenv("otg_mode");
+
+               if (otg_mode && (strcmp(otg_mode, "host") == 0))
+                       karo_fdt_enable_node(blob, "can1", 0);
+
+               tx6qdl_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+       }
+       fdt_find_and_setprop(blob, "/regulators/can-xcvr", "status",
+                       xcvr_status, strlen(xcvr_status) + 1, 1);
 }
 
 void ft_board_setup(void *blob, bd_t *bd)
 {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+
+       karo_fdt_enable_node(blob, "stk5led", !stk5_v5);
+
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
        fdt_fixup_ethernet(blob);
 
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
-       tx6qdl_fixup_flexcan(blob);
+       tx6qdl_fixup_flexcan(blob, stk5_v5);
        karo_fdt_update_fb_mode(blob, getenv("video_mode"));
 }
 #endif
index 002acf905b259951cc4813dd3186e0e40094c3d8..eca5df88488bd936ce91189271cf920fc7c89c58 100644 (file)
@@ -452,9 +452,9 @@ static int do_bootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 }
 U_BOOT_CMD(
        bootce, 2, 0, do_bootce,
-       "Boot a Windows CE image from RAM\n",
+       "Boot a Windows CE image from RAM",
        "[addr]\n"
-       "\taddr\t\tboot image from address addr (default ${fileaddr})\n"
+       "\taddr\t\tboot image from address addr (default ${fileaddr})"
 );
 
 static int ce_nand_load(ce_bin *bin, loff_t *offset, void *buf, size_t max_len)
@@ -554,10 +554,10 @@ static int do_nbootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                break;
                        }
                } while (ret == CE_PR_MORE);
+               free(buffer);
                if (ret != CE_PR_EOF)
                        return CMD_RET_FAILURE;
 
-               free(buffer);
                if (getenv_yesno("autostart") != 1) {
                        /*
                         * just use bootce to load the image to SDRAM;
@@ -576,10 +576,10 @@ err:
 }
 U_BOOT_CMD(
        nbootce, 2, 0, do_nbootce,
-       "Boot a Windows CE image from NAND\n",
+       "Boot a Windows CE image from NAND",
        "off|partitition\n"
        "\toff\t\t- flash offset (hex)\n"
-       "\tpartition\t- partition name\n"
+       "\tpartition\t- partition name"
 );
 
 static int ce_send_write_ack(ce_net *net)
@@ -625,8 +625,9 @@ static enum bootme_state ce_process_download(ce_net *net, ce_bin *bin)
                        } else {
                                int rc = ce_send_write_ack(net);
 
-                               printf("Dropping out of sequence packet with ID %d (expected %d)\n",
-                                       blknum, nxt);
+                               if (net->verbose)
+                                       printf("Dropping out of sequence packet with ID %d (expected %d)\n",
+                                               blknum, nxt);
                                if (rc != 0)
                                        return rc;
 
@@ -739,20 +740,18 @@ static enum bootme_state ce_process_edbg(ce_net *net, ce_bin *bin)
                net->state = BOOTME_DEBUG;
        }
 
-debug("%s@%d\n", __func__, __LINE__);
        switch (header.cmd) {
        case EDBG_CMD_JUMPIMG:
-debug("%s@%d\n", __func__, __LINE__);
                net->gotJumpingRequest = 1;
 
                if (net->verbose) {
                        printf("Received JUMPING command\n");
                }
                /* Just pass through and copy CONFIG structure */
+               ret = BOOTME_DONE;
        case EDBG_CMD_OS_CONFIG:
-debug("%s@%d\n", __func__, __LINE__);
                /* Copy config structure */
-               memcpy(&bin->edbgConfig, header.data,
+               memcpy(&bin->edbgConfig, &net->data[sizeof(header)],
                        sizeof(edbg_os_config_data));
                if (net->verbose) {
                        printf("Received CONFIG command\n");
@@ -778,7 +777,6 @@ debug("%s@%d\n", __func__, __LINE__);
                                printf("--> Force clean boot\n");
                        }
                }
-               ret = BOOTME_DEBUG;
                break;
 
        default:
@@ -790,11 +788,18 @@ debug("%s@%d\n", __func__, __LINE__);
 
        /* Respond with ack */
        header.flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
+       memcpy(net->data, &header, sizeof(header));
        net->dataLen = EDBG_DATA_OFFSET;
-debug("%s@%d: sending packet %p len %u\n", __func__, __LINE__,
-       net->data, net->dataLen);
-       bootme_send_frame(net->data, net->dataLen);
-       return ret;
+
+       int retries = 10;
+       int rc;
+       do {
+               rc = bootme_send_frame(net->data, net->dataLen);
+               if (rc != 0) {
+                       printf("Failed to send ACK: %d\n", rc);
+               }
+       } while (rc && retries-- > 0);
+       return rc ?: ret;
 }
 
 static enum bootme_state ce_edbg_handler(const void *buf, size_t len)
@@ -1002,7 +1007,7 @@ static int do_ceconnect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]
                        i++;
                        if (argc > i) {
                                timeout = simple_strtoul(argv[i],
-                                                       NULL, 10);
+                                                       NULL, 0);
                                if (timeout >= UINT_MAX / CONFIG_SYS_HZ) {
                                        printf("Timeout value %lu out of range (max.: %lu)\n",
                                                timeout, UINT_MAX / CONFIG_SYS_HZ - 1);
@@ -1019,7 +1024,7 @@ static int do_ceconnect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]
                                server_ip = string_to_ip(argv[i]);
                                printf("Using server %pI4\n", &server_ip);
                        } else {
-                               printf("Option requires an argument - t\n");
+                               printf("Option requires an argument - h\n");
                                return CMD_RET_USAGE;
                        }
                }
@@ -1055,7 +1060,7 @@ err:
 }
 U_BOOT_CMD(
        ceconnect, 6, 1, do_ceconnect,
-       "Set up a connection to the CE host PC over TCP/IP and download the run-time image\n",
+       "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
        "[-v] [-t <timeout>] [-h host]\n"
        "  -v            - verbose operation\n"
        "  -t <timeout>  - max wait time (#sec) for the connection\n"
index 1efd14f1a61f39cdf020c0854a934cdad24e7037..c853fc8d768a8433dc6a6711133eb59db5aeb12c 100644 (file)
@@ -291,6 +291,7 @@ struct sockaddr_in {
 enum bootme_state {
        BOOTME_INIT,
        BOOTME_DOWNLOAD,
+       BOOTME_DEBUG_INIT,
        BOOTME_DEBUG,
        BOOTME_DONE,
        BOOTME_ERROR,
index 56ae37834707f2e55c3bcd7d1b015aa60df3ed68..af2ab9f57ec4a021cddf506ba171bfd9d8c13d8c 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define WINCE_VRAM_BASE                0x80000000
-#define CE_FIX_ADDRESS(a)      ((void *)((a) - WINCE_VRAM_BASE + CONFIG_SYS_SDRAM_BASE))
-
-#ifndef INT_MAX
-#define INT_MAX                        ((int)(~0 >> 1))
-#endif
-
-/* Bin image parse states */
-#define CE_PS_RTI_ADDR         0
-#define CE_PS_RTI_LEN          1
-#define CE_PS_E_ADDR           2
-#define CE_PS_E_LEN            3
-#define CE_PS_E_CHKSUM         4
-#define CE_PS_E_DATA           5
-
-#define CE_MIN(a, b)           (((a) < (b)) ? (a) : (b))
-#define CE_MAX(a, b)           (((a) > (b)) ? (a) : (b))
-
-#define _STRMAC(s)             #s
-#define STRMAC(s)              _STRMAC(s)
-
 static enum bootme_state bootme_state;
 static int bootme_src_port = 0xdeadface;
 static int bootme_dst_port = 0xdeadbeef;
 static uchar bootme_ether[ETH_ALEN];
 static IPaddr_t bootme_ip;
 static int bootme_timed_out;
-//static size_t input_len, input_size;
-//static void *input_packet;
 static const char *output_packet; /* used by first send udp */
 static int output_packet_len;
 static unsigned long bootme_timeout;
@@ -97,6 +74,7 @@ static inline void ce_dump_block(void *ptr, int length)
 
 static void bootme_timeout_handler(void)
 {
+       printf("%s\n", __func__);
        net_set_state(NETLOOP_SUCCESS);
        bootme_timed_out++;
 }
@@ -196,12 +174,12 @@ static void bootme_handler(uchar *pkt, unsigned dest_port, IPaddr_t src_ip,
        uchar *eth_pkt = pkt;
        unsigned eth_len = len;
        static char cursor = '|';
-       enum bootme_state last_state = BOOTME_INIT;
-#if 1
+       enum bootme_state last_state = bootme_state;
+
        debug("received packet of len %d from %pI4:%d to port %d\n",
                len, &src_ip, src_port, dest_port);
        ce_dump_block(pkt, len);
-#endif
+
        if (!bootme_packet_handler) {
                printf("No packet handler set for BOOTME protocol; dropping packet\n");
                return;
@@ -212,27 +190,37 @@ static void bootme_handler(uchar *pkt, unsigned dest_port, IPaddr_t src_ip,
        printf("%c\x08", cursor);
        cursor = next_cursor(cursor);
 
-       if (is_broadcast(bootme_ip)) {
-               bootme_ip = src_ip;
-       } else if (src_ip != bootme_ip) {
+       if (!is_broadcast(bootme_ip) && src_ip != bootme_ip) {
                debug("src_ip %pI4 does not match destination IP %pI4\n",
                        &src_ip, &bootme_ip);
                return; /* not from our server */
        }
-
-       last_state = bootme_state;
-       bootme_dst_port = src_port;
-       debug("bootme_dst_port set to %d\n", bootme_dst_port);
+       if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT) {
+               struct ethernet_hdr *eth = (struct ethernet_hdr *)(pkt -
+                                       NetEthHdrSize() - IP_UDP_HDR_SIZE);
+               memcpy(bootme_ether, eth->et_src, sizeof(bootme_ether));
+               printf("Target MAC address set to %pM\n", bootme_ether);
+
+               if (is_broadcast(bootme_ip)) {
+                       NetCopyIP(&bootme_ip, &src_ip);
+               }
+       }
        if (bootme_state == BOOTME_INIT) {
                bootme_src_port = EDBG_SVC_PORT;
                debug("%s: bootme_src_port set to %d\n", __func__, bootme_src_port);
        }
+
+       debug("bootme_dst_port %d -> %d\n", bootme_dst_port, src_port);
+       bootme_dst_port = src_port;
+
        bootme_state = bootme_packet_handler(eth_pkt, eth_len);
        debug("bootme_packet_handler() returned %d\n", bootme_state);
        if (bootme_state != last_state)
-               debug("bootme_state: %d -> %d\n", last_state, bootme_state);
+               debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+                       last_state, bootme_state);
        switch (bootme_state) {
        case BOOTME_INIT:
+       case BOOTME_DEBUG_INIT:
                break;
 
        case BOOTME_DOWNLOAD:
@@ -240,9 +228,9 @@ static void bootme_handler(uchar *pkt, unsigned dest_port, IPaddr_t src_ip,
                        NetBootFileXferSize += len - 4;
                /* fallthru */
        case BOOTME_DEBUG:
-               if (last_state == BOOTME_INIT) {
+               if (last_state == BOOTME_INIT ||
+                       last_state == BOOTME_DEBUG_INIT)
                        bootme_timeout = 3 * 1000;
-               }
                NetSetTimeout(bootme_timeout, bootme_timeout_handler);
                break;
 
@@ -276,8 +264,11 @@ void BootmeStart(void)
                assert(NetTxPacket != NULL);
                pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
                memcpy(pkt, output_packet, output_packet_len);
+               debug("%s@%d: Sending ARP request:\n", __func__, __LINE__);
+               ce_dump_block(pkt, output_packet_len);
                NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
                                bootme_src_port, output_packet_len);
+               output_packet_len = 0;
        }
 }
 
@@ -285,23 +276,20 @@ int bootme_send_frame(const void *buf, size_t len)
 {
        int ret;
        struct eth_device *eth;
-       int inited = 0;
        uchar *pkt;
 
        eth = eth_get_dev();
        if (eth == NULL)
                return -EINVAL;
 
-       if (bootme_state == BOOTME_INIT)
+       if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT)
                check_net_config();
 
        debug("%s: buf: %p len: %u from %pI4:%d to %pI4:%d\n",
-               __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip, bootme_dst_port);
+               __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip,
+               bootme_dst_port);
 
        if (memcmp(bootme_ether, NetEtherNullAddr, ETH_ALEN) == 0) {
-               if (eth->state == ETH_STATE_ACTIVE)
-                       return 0;       /* inside net loop */
-
                output_packet = buf;
                output_packet_len = len;
                /* wait for arp reply and send packet */
@@ -316,36 +304,22 @@ int bootme_send_frame(const void *buf, size_t len)
                return 0;
        }
 
-       if (eth->state != ETH_STATE_ACTIVE) {
-               if (eth_is_on_demand_init()) {
-                       ret = eth_init(gd->bd);
-                       if (ret < 0)
-                               return ret;
-                       eth_set_last_protocol(BOOTME);
-               } else {
-                       eth_init_state_only(gd->bd);
-               }
-               inited = 1;
-       }
-
        assert(NetTxPacket != NULL);
        pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
        memcpy(pkt, buf, len);
 
        ret = NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
                        bootme_src_port, len);
-       if (inited) {
-               debug("Stopping network\n");
-               if (eth_is_on_demand_init())
-                       eth_halt();
-               else
-                       eth_halt_state_only();
-       }
+       if (ret)
+               printf("Failed to send packet: %d\n", ret);
+
        return ret;
 }
 
 static void bootme_init(IPaddr_t server_ip)
 {
+       debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+               bootme_state, BOOTME_INIT);
        bootme_state = BOOTME_INIT;
        bootme_ip = server_ip;
        /* force reconfiguration in check_net_config() */
@@ -374,7 +348,10 @@ int BootMeDebugStart(bootme_hand_f *handler)
        bootme_packet_handler = handler;
 
        bootme_init(bootme_ip);
-       bootme_state = BOOTME_DEBUG;
+       debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+               bootme_state, BOOTME_DEBUG_INIT);
+       bootme_state = BOOTME_DEBUG_INIT;
+
        bootme_timeout = 3 * 1000;
        NetSetTimeout(bootme_timeout, bootme_timeout_handler);