]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'karo-tx-merge'
authorLothar Waßmann <LW@KARO-electronics.de>
Fri, 25 Oct 2013 08:33:30 +0000 (10:33 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 25 Oct 2013 08:33:30 +0000 (10:33 +0200)
20 files changed:
arch/arm/cpu/arm926ejs/mxs/mxs.c
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/include/asm/arch-mx5/imx-regs.h
board/boundary/nitrogen6x/nitrogen6x.c
board/congatec/cgtqmx6eval/cgtqmx6eval.c
board/freescale/mx6sabresd/mx6sabresd.c
board/freescale/titanium/titanium.c
board/karo/common/fdt.c
board/karo/common/karo.h
board/karo/tx28/tx28.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/tx6qdl.c
board/wandboard/wandboard.c
common/Makefile
common/fdt_support.c
drivers/video/mxc_ipuv3_fb.c
include/configs/tx28.h

index 66d5169087140658859106b403077e9e41b9f2e0..bf29f0ae08b28e536f7c984bb0a68d592167d039 100644 (file)
@@ -276,6 +276,7 @@ int cpu_eth_init(bd_t *bis)
        writel(CLKCTRL_PLL2CTRL0_CLKGATE,
                &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
 
+       udelay(6000);
        return 0;
 }
 #endif
index 3ccea6738e2d2df7f127e936f3c4427eae31317f..978f8499ec4bec1d746582dd8c9ba92ecc5c9487 100644 (file)
@@ -137,7 +137,6 @@ void set_chipselect_size(int const cs_size)
        writel(reg, &iomuxc_regs->gpr1);
 }
 
-#if 1
 void cpu_cache_initialization(void)
 {
        printf("Enabling L2 cache\n");
@@ -148,7 +147,6 @@ void cpu_cache_initialization(void)
                : : : "r0", "memory"
                );
 }
-#endif
 
 #ifdef CONFIG_MX53
 void boot_mode_apply(unsigned cfg_val)
index b38a40caefd76b8715104b1148ff521c7b3b9fbd..d9a7018a00faeeb31140b2f819831889b5351eb5 100644 (file)
@@ -12,7 +12,6 @@
 #if defined(CONFIG_MX51)
 #define IRAM_BASE_ADDR         0x1FFE0000      /* internal ram */
 #define IPU_SOC_BASE_ADDR      0x40000000
-#define IPU_SOC_OFFSET         0x1E000000
 #define SPBA0_BASE_ADDR                0x70000000
 #define AIPS1_BASE_ADDR                0x73F00000
 #define AIPS2_BASE_ADDR                0x83F00000
@@ -21,8 +20,7 @@
 #define NFC_BASE_ADDR_AXI      0xCFFF0000
 #define CS1_BASE_ADDR          0xB8000000
 #elif defined(CONFIG_MX53)
-#define IPU_SOC_BASE_ADDR      0x18000000
-#define IPU_SOC_OFFSET         0x06000000
+#define IPU_SOC_BASE_ADDR      0x00000000
 #define SPBA0_BASE_ADDR                0x50000000
 #define AIPS1_BASE_ADDR                0x53F00000
 #define AIPS2_BASE_ADDR                0x63F00000
index 1a29b6f4bd0639ff06aef6056b70b1ca83b421db..72745f63e3bf8304cf5bdc4ae0a7837a994134ba 100644 (file)
@@ -130,7 +130,7 @@ iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_SD3_DAT5__GPIO_7_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
 };
 
 iomux_v3_cfg_t const usdhc4_pads[] = {
@@ -140,7 +140,7 @@ iomux_v3_cfg_t const usdhc4_pads[] = {
        MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO_2_6    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
 };
 
 iomux_v3_cfg_t const enet_pads1[] = {
@@ -154,20 +154,20 @@ iomux_v3_cfg_t const enet_pads1[] = {
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* pin 35 - 1 (PHY_AD2) on reset */
-       MX6_PAD_RGMII_RXC__GPIO_6_30            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RXC__GPIO_6_30,
        /* pin 32 - 1 - (MODE0) all */
-       MX6_PAD_RGMII_RD0__GPIO_6_25            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__GPIO_6_25,
        /* pin 31 - 1 - (MODE1) all */
-       MX6_PAD_RGMII_RD1__GPIO_6_27            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__GPIO_6_27,
        /* pin 28 - 1 - (MODE2) all */
-       MX6_PAD_RGMII_RD2__GPIO_6_28            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__GPIO_6_28,
        /* pin 27 - 1 - (MODE3) all */
-       MX6_PAD_RGMII_RD3__GPIO_6_29            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__GPIO_6_29,
        /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-       MX6_PAD_RGMII_RX_CTL__GPIO_6_24 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
        /* pin 42 PHY nRST */
-       MX6_PAD_EIM_D23__GPIO_3_23              | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_ENET_RXD0__GPIO_1_27            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D23__GPIO_3_23,
+       MX6_PAD_ENET_RXD0__GPIO_1_27,
 };
 
 iomux_v3_cfg_t const enet_pads2[] = {
@@ -229,7 +229,7 @@ static void setup_iomux_enet(void)
 }
 
 iomux_v3_cfg_t const usb_pads[] = {
-       MX6_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_GPIO_17__GPIO_7_12,
 };
 
 static void setup_iomux_uart(void)
@@ -408,11 +408,11 @@ int setup_sata(void)
 
 static iomux_v3_cfg_t const backlight_pads[] = {
        /* Backlight on RGB connector: J15 */
-       MX6_PAD_SD1_DAT3__GPIO_1_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_SD1_DAT3__GPIO_1_21,
 #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
 
        /* Backlight on LVDS connector: J6 */
-       MX6_PAD_SD1_CMD__GPIO_1_18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_SD1_CMD__GPIO_1_18,
 #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
 };
 
index d42152734d137c0fb8ebb771ab12fca243557096..0d07f1b8a349610e32c4a035522534e0e6d2b80d 100644 (file)
@@ -60,7 +60,7 @@ iomux_v3_cfg_t const usdhc4_pads[] = {
        MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO_2_6    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
 };
 
 static void setup_iomux_uart(void)
index 936f029b4ec88b5e4f9a4fba7fadb29c0bc91293..288da292d5b2538d8183822a920aee811f250af3 100644 (file)
@@ -61,7 +61,7 @@ iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_ENET_CRS_DV__GPIO_1_25          | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_ENET_CRS_DV__GPIO_1_25,
 };
 
 static void setup_iomux_enet(void)
@@ -85,7 +85,7 @@ iomux_v3_cfg_t const usdhc2_pads[] = {
        MX6_PAD_NANDF_D5__USDHC2_DAT5   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_NANDF_D6__USDHC2_DAT6   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_NANDF_D7__USDHC2_DAT7   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D2__GPIO_2_2      | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D2__GPIO_2_2, /* CD */
 };
 
 iomux_v3_cfg_t const usdhc3_pads[] = {
@@ -99,7 +99,7 @@ iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D0__GPIO_2_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D0__GPIO_2_0, /* CD */
 };
 
 iomux_v3_cfg_t const usdhc4_pads[] = {
index 6025eb73155fbd603e4be9b43bdaba43ea28c262..82e7f984eaf1a0f93910530728a83bf3fb18014c 100644 (file)
@@ -94,7 +94,7 @@ iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_SD3_DAT5__GPIO_7_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
 };
 
 iomux_v3_cfg_t const enet_pads1[] = {
@@ -108,19 +108,19 @@ iomux_v3_cfg_t const enet_pads1[] = {
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* pin 35 - 1 (PHY_AD2) on reset */
-       MX6_PAD_RGMII_RXC__GPIO_6_30            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RXC__GPIO_6_30,
        /* pin 32 - 1 - (MODE0) all */
-       MX6_PAD_RGMII_RD0__GPIO_6_25            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__GPIO_6_25,
        /* pin 31 - 1 - (MODE1) all */
-       MX6_PAD_RGMII_RD1__GPIO_6_27            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__GPIO_6_27,
        /* pin 28 - 1 - (MODE2) all */
-       MX6_PAD_RGMII_RD2__GPIO_6_28            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__GPIO_6_28,
        /* pin 27 - 1 - (MODE3) all */
-       MX6_PAD_RGMII_RD3__GPIO_6_29            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__GPIO_6_29,
        /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-       MX6_PAD_RGMII_RX_CTL__GPIO_6_24         | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
        /* pin 42 PHY nRST */
-       MX6_PAD_EIM_D23__GPIO_3_23              | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D23__GPIO_3_23,
 };
 
 iomux_v3_cfg_t const enet_pads2[] = {
@@ -133,25 +133,25 @@ iomux_v3_cfg_t const enet_pads2[] = {
 };
 
 iomux_v3_cfg_t nfc_pads[] = {
-       MX6_PAD_NANDF_CLE__RAWNAND_CLE          | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_ALE__RAWNAND_ALE          | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_WP_B__RAWNAND_RESETN      | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_RB0__RAWNAND_READY0       | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_CS0__RAWNAND_CE0N         | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_CS1__RAWNAND_CE1N         | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_CS2__RAWNAND_CE2N         | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_CS3__RAWNAND_CE3N         | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_SD4_CMD__RAWNAND_RDN            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_SD4_CLK__RAWNAND_WRN            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D0__RAWNAND_D0            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D1__RAWNAND_D1            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D2__RAWNAND_D2            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D3__RAWNAND_D3            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D4__RAWNAND_D4            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D5__RAWNAND_D5            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D6__RAWNAND_D6            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_NANDF_D7__RAWNAND_D7            | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_SD4_DAT0__RAWNAND_DQS           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_NANDF_CLE__RAWNAND_CLE,
+       MX6_PAD_NANDF_ALE__RAWNAND_ALE,
+       MX6_PAD_NANDF_WP_B__RAWNAND_RESETN,
+       MX6_PAD_NANDF_RB0__RAWNAND_READY0,
+       MX6_PAD_NANDF_CS0__RAWNAND_CE0N,
+       MX6_PAD_NANDF_CS1__RAWNAND_CE1N,
+       MX6_PAD_NANDF_CS2__RAWNAND_CE2N,
+       MX6_PAD_NANDF_CS3__RAWNAND_CE3N,
+       MX6_PAD_SD4_CMD__RAWNAND_RDN,
+       MX6_PAD_SD4_CLK__RAWNAND_WRN,
+       MX6_PAD_NANDF_D0__RAWNAND_D0,
+       MX6_PAD_NANDF_D1__RAWNAND_D1,
+       MX6_PAD_NANDF_D2__RAWNAND_D2,
+       MX6_PAD_NANDF_D3__RAWNAND_D3,
+       MX6_PAD_NANDF_D4__RAWNAND_D4,
+       MX6_PAD_NANDF_D5__RAWNAND_D5,
+       MX6_PAD_NANDF_D6__RAWNAND_D6,
+       MX6_PAD_NANDF_D7__RAWNAND_D7,
+       MX6_PAD_SD4_DAT0__RAWNAND_DQS,
 };
 
 static void setup_gpmi_nand(void)
index c942e8af52753b73fb70a3ecf41bb53a2b1474d7..9c154eadb98f17504d9ec20d6effd8e4d58e75a8 100644 (file)
@@ -237,6 +237,81 @@ out:
        karo_set_fdtsize(blob);
 }
 
+static int karo_fdt_flexcan_enabled(void *blob)
+{
+       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 (status && strcmp(status, "okay") == 0) {
+                       debug("%s is enabled\n", can_ifs[i]);
+                       return 1;
+               }
+       }
+       debug("can driver is disabled\n");
+       return 0;
+}
+
+static void karo_fdt_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;
+
+       ph = fdt_create_phandle(blob, off);
+       if (!ph)
+               return;
+
+       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);
+}
+
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+       const char *xcvr_status = "disabled";
+
+       if (xcvr_present) {
+               if (karo_fdt_flexcan_enabled(blob)) {
+                       karo_fdt_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+                       xcvr_status = "okay";
+               } else {
+                       karo_fdt_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);
+
+               karo_fdt_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 karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
                        const char *prop)
 {
@@ -320,7 +395,7 @@ 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 defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+
        prop = fdt_getprop(blob, off, "de-active", NULL);
        if (prop)
                fb_mode->sync |= *prop ? 0 : FB_SYNC_OE_LOW_ACT;
@@ -328,7 +403,7 @@ static int fdt_init_fb_mode(const void *blob, int off, struct fb_videomode *fb_m
        prop = fdt_getprop(blob, off, "pixelclk-active", NULL);
        if (prop)
                fb_mode->sync |= *prop ? 0 : FB_SYNC_CLK_LAT_FALL;
-#endif
+
        return 0;
 }
 
@@ -337,7 +412,7 @@ static int fdt_update_native_fb_mode(void *blob, int off)
        int ret;
        uint32_t ph;
 
-       ret = fdt_increase_size(blob, 32);
+       ret = fdt_increase_size(blob, 64);
        if (ret) {
                printf("Warning: Failed to increase FDT size: %d\n", ret);
        }
@@ -510,25 +585,12 @@ int karo_fdt_create_fb_mode(void *blob, const char *name,
                        fb_mode->sync & FB_SYNC_VERT_HIGH_ACT ? 1 : 0);
        if (ret)
                goto out;
-
-#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;
-#endif
 out:
        karo_set_fdtsize(blob);
        return ret;
@@ -543,16 +605,11 @@ int karo_fdt_update_fb_mode(void *blob, const char *name)
                return off;
 
        if (name == NULL) {
-               int parent = fdt_parent_offset(blob, off);
                int ret;
 
-               if (parent < 0) {
-                       printf("Failed to find parent of node '%s'\n",
-                               fdt_get_name(blob, off, NULL));
-                       return parent;
-               }
-               debug("parent offset=%06x\n", parent);
-               ret = fdt_set_node_status(blob, parent, FDT_STATUS_DISABLED, 0);
+               debug("Disabling node '%s' at %03x\n",
+                       fdt_get_name(blob, off, NULL), off);
+               ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
                return ret;
        }
 
@@ -617,8 +674,7 @@ static int karo_load_part(const char *part, void *addr, size_t len)
                return ret;
 
        debug("Trying to find NAND partition '%s'\n", part);
-       ret = find_dev_and_part(part, &dev, &part_num,
-                               &part_info);
+       ret = find_dev_and_part(part, &dev, &part_num, &part_info);
        if (ret) {
                printf("Failed to find flash partition '%s': %d\n",
                        part, ret);
index dbfa58e56649431e531a2be725e7bb170edeff89..ba4ef467edcee8e416a7d53d4392415c40044aab 100644 (file)
@@ -21,6 +21,7 @@ void karo_fdt_remove_node(void *blob, const char *node);
 void karo_fdt_move_fdt(void);
 void karo_fdt_fixup_touchpanel(void *blob);
 void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy);
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present);
 void karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
                const char *prop);
 void karo_fdt_enable_node(void *blob, const char *node, int enable);
@@ -44,6 +45,9 @@ static inline void karo_fdt_fixup_usb_otg(void *blob, const char *node,
                                        const char *phy)
 {
 }
+static inline void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+}
 static inline void karo_fdt_del_prop(void *blob, const char *compat,
                                phys_addr_t offs, const char *prop)
 {
index c56876b76698f70664f260ab521f3ad3dc2674b6..327e3b0f80d3b8d8dbb945ba6f9a678f72242c63 100644 (file)
@@ -235,11 +235,12 @@ static int fec_get_mac_addr(int index)
        if (!is_valid_ether_addr(mac))
                return 0;
 
-       if (index == 0)
+       if (index == 0) {
+               printf("MAC addr from fuse: %pM\n", mac);
                snprintf(env_name, sizeof(env_name), "ethaddr");
-       else
+       } else {
                snprintf(env_name, sizeof(env_name), "eth%daddr", index);
-
+       }
        eth_setenv_enetaddr(env_name, mac);
        return 0;
 }
@@ -279,11 +280,6 @@ int board_eth_init(bd_t *bis)
                return ret;
        }
 
-       ret = fec_get_mac_addr(0);
-       if (ret < 0) {
-               printf("Failed to read FEC0 MAC address from OCOTP\n");
-               return ret;
-       }
 #ifdef CONFIG_FEC_MXC_MULTI
        if (getenv("ethaddr")) {
                ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
@@ -293,11 +289,6 @@ int board_eth_init(bd_t *bis)
                }
        }
 
-       ret = fec_get_mac_addr(1);
-       if (ret < 0) {
-               printf("Failed to read FEC1 MAC address from OCOTP\n");
-               return ret;
-       }
        if (getenv("eth1addr")) {
                ret = fecmxc_initialize_multi(bis, 1, 1, MXS_ENET1_BASE);
                if (ret) {
@@ -305,13 +296,16 @@ int board_eth_init(bd_t *bis)
                        return ret;
                }
        }
-       return 0;
 #else
        if (getenv("ethaddr")) {
                ret = fecmxc_initialize(bis);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC\n");
+                       return ret;
+               }
        }
-       return ret;
 #endif
+       return 0;
 }
 #endif /* CONFIG_FEC_MXC */
 
@@ -686,6 +680,20 @@ void lcd_ctrl_init(void *lcdbase)
                printf("\n");
                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;
+       }
+
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
                (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
@@ -701,8 +709,16 @@ void lcd_ctrl_init(void *lcdbase)
                color_depth, refresh);
 
        if (karo_load_splashimage(0) == 0) {
+               char vmode[32];
+
+               /* setup env variable for mxsfb display driver */
+               snprintf(vmode, sizeof(vmode), "%dx%dMR-%d@%d",
+                       p->xres, p->yres, color_depth, refresh);
+               setenv("videomode", vmode);
+
                debug("Initializing LCD controller\n");
                video_hw_init(lcdbase);
+               setenv("videomode", NULL);
        } else {
                debug("Skipping initialization of LCD controller\n");
        }
@@ -732,8 +748,25 @@ static void stk5v5_board_init(void)
        mxs_iomux_setup_pad(MX28_PAD_LCD_D00__GPIO_1_0);
 }
 
+int tx28_fec1_enabled(void)
+{
+       const char *status;
+       int off;
+
+       if (!gd->fdt_blob)
+               return 0;
+
+       off = fdt_path_offset(gd->fdt_blob, "ethernet1");
+       if (off < 0)
+               return 0;
+
+       status = fdt_getprop(gd->fdt_blob, off, "status", NULL);
+       return status && (strcmp(status, "okay") == 0);
+}
+
 int board_late_init(void)
 {
+       int ret;
        const char *baseboard;
 
        karo_fdt_move_fdt();
@@ -766,6 +799,20 @@ int board_late_init(void)
                return -EINVAL;
        }
 
+       ret = fec_get_mac_addr(0);
+       if (ret < 0) {
+               printf("Failed to read FEC0 MAC address from OCOTP\n");
+               return ret;
+       }
+#ifdef CONFIG_FEC_MXC_MULTI
+       if (tx28_fec1_enabled()) {
+               ret = fec_get_mac_addr(1);
+               if (ret < 0) {
+                       printf("Failed to read FEC1 MAC address from OCOTP\n");
+                       return ret;
+               }
+       }
+#endif
        return 0;
 }
 
@@ -937,11 +984,6 @@ static void tx28_fixup_flexcan(void *blob, int stk5_v5)
                        can_xcvr, strlen(can_xcvr) + 1, 1);
 }
 
-static void tx28_fixup_fec(void *blob)
-{
-       karo_fdt_enable_node(blob, "ethernet1", 0);
-}
-
 void ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
@@ -956,8 +998,6 @@ void ft_board_setup(void *blob, bd_t *bd)
 #endif
        if (stk5_v5) {
                karo_fdt_remove_node(blob, "stk5led");
-       } else {
-               tx28_fixup_fec(blob);
        }
        tx28_fixup_flexcan(blob, stk5_v5);
 
index d035e188946065886f97f819a818b43847a3b968..a5f953635cf43500fd5dbd639753b66a8d964bf3 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
@@ -26,6 +26,7 @@
 #include <nand.h>
 #include <net.h>
 #include <linux/mtd/nand.h>
+#include <linux/fb.h>
 #include <asm/gpio.h>
 #include <asm/cache.h>
 #include <asm/omap_common.h>
@@ -395,18 +396,138 @@ vidinfo_t panel_info = {
        .cmap = tx48_cmap,
 };
 
-static struct da8xx_panel tx48_lcd_panel = {
-       .name = "640x480MR@60",
-       .width = 640,
-       .height = 480,
-       .hfp = 12,
-       .hbp = 144,
-       .hsw = 30,
-       .vfp = 10,
-       .vbp = 35,
-       .vsw = 3,
-       .pxl_clk = 25000000,
-       .invert_pxl_clk = 1,
+#define FB_SYNC_OE_LOW_ACT     (1 << 31)
+#define FB_SYNC_CLK_LAT_FALL   (1 << 30)
+
+static struct fb_videomode tx48_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
 };
 
 void *lcd_base;                        /* Start of framebuffer memory  */
@@ -440,7 +561,9 @@ void lcd_enable(void)
        if (lcd_enabled) {
                karo_load_splashimage(1);
 
+               debug("Switching LCD on\n");
                gpio_set_value(TX48_LCD_PWR_GPIO, 1);
+               udelay(100);
                gpio_set_value(TX48_LCD_RST_GPIO, 1);
                udelay(300000);
                gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
@@ -450,14 +573,34 @@ void lcd_enable(void)
 void lcd_disable(void)
 {
        if (lcd_enabled) {
+               printf("Disabling LCD\n");
                da8xx_fb_disable();
                lcd_enabled = 0;
        }
 }
 
+static void tx48_lcd_panel_setup(struct da8xx_panel *p,
+                               struct fb_videomode *fb)
+{
+       p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
+
+       p->width = fb->xres;
+       p->hbp = fb->left_margin;
+       p->hsw = fb->hsync_len;
+       p->hfp = fb->right_margin;
+
+       p->height = fb->yres;
+       p->vbp = fb->upper_margin;
+       p->vsw = fb->vsync_len;
+       p->vfp = fb->lower_margin;
+
+       p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
+}
+
 void lcd_panel_disable(void)
 {
        if (lcd_enabled) {
+               debug("Switching LCD off\n");
                gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1);
                gpio_set_value(TX48_LCD_PWR_GPIO, 0);
                gpio_set_value(TX48_LCD_RST_GPIO, 0);
@@ -469,21 +612,28 @@ void lcd_ctrl_init(void *lcdbase)
        int color_depth = 24;
        char *vm, *v;
        unsigned long val;
-       struct da8xx_panel *p = &tx48_lcd_panel;
        int refresh = 60;
+       struct fb_videomode *p = &tx48_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
 
        if (!lcd_enabled) {
-               printf("LCD disabled\n");
+               debug("LCD disabled\n");
                return;
        }
 
        if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
+       karo_fdt_move_fdt();
+
        vm = getenv("video_mode");
        if (vm == NULL) {
+               debug("Disabling LCD\n");
                lcd_enabled = 0;
                return;
        }
@@ -491,72 +641,149 @@ void lcd_ctrl_init(void *lcdbase)
        if ((v = strstr(vm, ":")))
                vm = v + 1;
 
-       strncpy((char *)p->name, vm, sizeof(p->name));
-
-       val = simple_strtoul(vm, &vm, 10);
-       if (val != 0) {
-               if (val > panel_info.vl_col)
-                       val = panel_info.vl_col;
-               p->width = val;
-               panel_info.vl_col = val;
+       if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               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 (*vm == 'x') {
-               val = simple_strtoul(vm + 1, &vm, 10);
-               if (val > panel_info.vl_row)
-                       val = panel_info.vl_row;
-               p->height = val;
-               panel_info.vl_row = val;
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
        }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
        while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 24:
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
                switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
                case 'M':
                case 'R':
                        vm++;
                        break;
 
-               case '-':
-                       color_depth = simple_strtoul(vm + 1, &vm, 10);
-                       break;
-
-               case '@':
-                       refresh = simple_strtoul(vm + 1, &vm, 10);
-                       break;
-
                default:
-                       debug("Ignoring '%c'\n", *vm);
-                       vm++;
+                       if (*vm != '\0')
+                               vm++;
                }
        }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               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 = 3;
+               panel_info.vl_bpix = LCD_COLOR8;
                break;
-
        case 16:
-               panel_info.vl_bpix = 4;
+               panel_info.vl_bpix = LCD_COLOR16;
                break;
-
-       case 24:
-               panel_info.vl_bpix = 5;
-               break;
-
        default:
-               printf("Invalid color_depth %u from video_mode '%s'; using default: %u\n",
-                       color_depth, getenv("video_mode"), 24);
+               panel_info.vl_bpix = LCD_COLOR24;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len)
+               / 1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               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);
        }
-       lcd_line_length = NBITS(panel_info.vl_bpix) / 8 * panel_info.vl_col;
-       p->pxl_clk = refresh *
-               (p->width + p->hfp + p->hbp + p->hsw) *
-               (p->height + p->vfp + p->vbp + p->vsw);
-       debug("Pixel clock set to %u.%03uMHz\n",
-               p->pxl_clk / 1000000, p->pxl_clk / 1000 % 1000);
 
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
        tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
-       debug("Initializing FB driver\n");
-       da8xx_video_init(&tx48_lcd_panel, color_depth);
 
        if (karo_load_splashimage(0) == 0) {
+               struct da8xx_panel da8xx_panel = { };
+
+               debug("Initializing FB driver\n");
+               tx48_lcd_panel_setup(&da8xx_panel, p);
+               da8xx_video_init(&da8xx_panel, color_depth);
+
                debug("Initializing LCD controller\n");
                video_hw_init();
        } else {
@@ -660,18 +887,42 @@ static void tx48_set_cpu_clock(void)
                mpu_clk_rate() / 1000 % 1000);
 }
 
+static void tx48_init_mac(void)
+{
+       uint8_t mac_addr[ETH_ALEN];
+       uint32_t mac_hi, mac_lo;
+
+       /* try reading mac address from efuse */
+       mac_lo = __raw_readl(MAC_ID0_LO);
+       mac_hi = __raw_readl(MAC_ID0_HI);
+
+       mac_addr[0] = mac_hi & 0xFF;
+       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       mac_addr[4] = mac_lo & 0xFF;
+       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       if (!is_valid_ether_addr(mac_addr)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+       printf("MAC addr from fuse: %pM\n", mac_addr);
+       eth_setenv_enetaddr("ethaddr", mac_addr);
+}
+
 /* called with environment from NAND or MMC */
 int board_late_init(void)
 {
+       int ret = 0;
        const char *baseboard;
 
        tx48_set_cpu_clock();
-#ifdef CONFIG_OF_BOARD_SETUP
        karo_fdt_move_fdt();
-#endif
+
        baseboard = getenv("baseboard");
        if (!baseboard)
-               return 0;
+               goto exit;
 
        if (strncmp(baseboard, "stk5", 4) == 0) {
                printf("Baseboard: %s\n", baseboard);
@@ -687,10 +938,11 @@ int board_late_init(void)
        } else {
                printf("WARNING: Unsupported baseboard: '%s'\n",
                        baseboard);
-               return -EINVAL;
+               ret = -EINVAL;
        }
-
-       return 0;
+exit:
+       tx48_init_mac();
+       return ret;
 }
 
 #ifdef CONFIG_DRIVER_TI_CPSW
@@ -751,27 +1003,6 @@ static struct cpsw_platform_data cpsw_data = {
 
 int board_eth_init(bd_t *bis)
 {
-       uint8_t mac_addr[ETH_ALEN];
-       uint32_t mac_hi, mac_lo;
-
-       /* try reading mac address from efuse */
-       mac_lo = __raw_readl(MAC_ID0_LO);
-       mac_hi = __raw_readl(MAC_ID0_HI);
-
-       mac_addr[0] = mac_hi & 0xFF;
-       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
-       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
-       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
-       mac_addr[4] = mac_lo & 0xFF;
-       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-
-       if (is_valid_ether_addr(mac_addr)) {
-               printf("MAC addr from fuse: %pM\n", mac_addr);
-               eth_setenv_enetaddr("ethaddr", mac_addr);
-       } else {
-               printf("ERROR: Did not find a valid mac address in e-fuse\n");
-       }
-
        __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
        __raw_writel(0x5D, GMII_SEL);
        return cpsw_register(&cpsw_data);
@@ -830,24 +1061,16 @@ struct node_info nodes[] = {
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
 
-static void tx48_fixup_flexcan(void *blob)
+void ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
 
-       if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
-               return;
-
-       karo_fdt_del_prop(blob, "ti,dcan", 0x481cc000, "can-xcvr-enable");
-       karo_fdt_del_prop(blob, "ti,dcan", 0x481d0000, "can-xcvr-enable");
-}
-
-void ft_board_setup(void *blob, bd_t *bd)
-{
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
        fdt_fixup_ethernet(blob);
 
        karo_fdt_fixup_touchpanel(blob);
-       tx48_fixup_flexcan(blob);
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
 
        tx48_disable_watchdog();
 }
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..11ec4f6291ebf0e4be0bcbc31789f89514d7c453 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)
 {
@@ -451,7 +457,6 @@ static struct gpio tx51_fec_gpios[] = {
 int board_eth_init(bd_t *bis)
 {
        int ret;
-       unsigned char mac[ETH_ALEN];
 
        /* Power up the external phy and assert strap options */
        gpio_request_array(tx51_fec_gpios, ARRAY_SIZE(tx51_fec_gpios));
@@ -470,15 +475,8 @@ int board_eth_init(bd_t *bis)
                                        ARRAY_SIZE(tx51_fec_pads));
 
        ret = cpu_eth_init(bis);
-       if (ret) {
+       if (ret)
                printf("cpu_eth_init() failed: %d\n", ret);
-               return ret;
-       }
-
-       imx_get_mac_from_fuse(0, mac);
-       eth_setenv_enetaddr("ethaddr", mac);
-       printf("MAC addr from fuse: %pM\n", mac);
-
        return ret;
 }
 #endif /* CONFIG_FEC_MXC */
@@ -513,18 +511,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 +536,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 +687,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 +701,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 +781,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 +797,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 +841,7 @@ void lcd_ctrl_init(void *lcdbase)
                                        case 8:
                                        case 16:
                                        case 24:
+                                       case 32:
                                                color_depth = val;
                                                break;
 
@@ -889,6 +895,25 @@ 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;
+       }
 
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
@@ -898,6 +923,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 +944,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");
        }
@@ -957,6 +1000,20 @@ static void tx51_set_cpu_clock(void)
                mxc_get_clock(MXC_ARM_CLK) / 1000 % 1000);
 }
 
+static void tx51_init_mac(void)
+{
+       u8 mac[ETH_ALEN];
+
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+
+       eth_setenv_enetaddr("ethaddr", mac);
+       printf("MAC addr from fuse: %pM\n", mac);
+}
+
 int board_late_init(void)
 {
        int ret = 0;
@@ -989,6 +1046,7 @@ int board_late_init(void)
        }
 
 exit:
+       tx51_init_mac();
        gpio_set_value(TX51_RESET_OUT_GPIO, 1);
        return ret;
 }
@@ -1022,5 +1080,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..6ab338ffc9a473a07a4f2ec487bb67139222a3fe 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)
 {
@@ -402,7 +392,6 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 int board_eth_init(bd_t *bis)
 {
        int ret;
-       unsigned char mac[ETH_ALEN];
 
        /* delay at least 21ms for the PHY internal POR signal to deassert */
        udelay(22000);
@@ -411,15 +400,8 @@ int board_eth_init(bd_t *bis)
        gpio_set_value(TX53_FEC_RST_GPIO, 1);
 
        ret = cpu_eth_init(bis);
-       if (ret) {
+       if (ret)
                printf("cpu_eth_init() failed: %d\n", ret);
-               return ret;
-       }
-
-       imx_get_mac_from_fuse(0, mac);
-       eth_setenv_enetaddr("ethaddr", mac);
-       printf("MAC addr from fuse: %pM\n", mac);
-
        return ret;
 }
 #endif /* CONFIG_FEC_MXC */
@@ -489,14 +471,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 +622,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 +636,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 +730,7 @@ void lcd_ctrl_init(void *lcdbase)
        if (tstc() || (wrsr & WRSR_TOUT)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
@@ -761,10 +746,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");
@@ -869,6 +858,25 @@ 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;
+       }
 
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
@@ -878,6 +886,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 +918,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");
        }
@@ -949,6 +977,20 @@ static void tx53_set_cpu_clock(void)
                mxc_get_clock(MXC_ARM_CLK) / 1000 % 1000);
 }
 
+static void tx53_init_mac(void)
+{
+       u8 mac[ETH_ALEN];
+
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+
+       eth_setenv_enetaddr("ethaddr", mac);
+       printf("MAC addr from fuse: %pM\n", mac);
+}
+
 int board_late_init(void)
 {
        int ret = 0;
@@ -979,6 +1021,7 @@ int board_late_init(void)
        }
 
 exit:
+       tx53_init_mac();
        gpio_set_value(TX53_RESET_OUT_GPIO, 1);
        return ret;
 }
@@ -1005,17 +1048,6 @@ struct node_info nodes[] = {
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif
 
-static void tx53_fixup_flexcan(void *blob)
-{
-       const char *baseboard = getenv("baseboard");
-
-       if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
-               return;
-
-       karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x53fc8000, "transceiver-switch");
-       karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x53fcc000, "transceiver-switch");
-}
-
 #ifdef CONFIG_SYS_TX53_HWREV_2
 void tx53_fixup_rtc(void *blob)
 {
@@ -1026,17 +1058,20 @@ 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)
 {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+
        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);
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
        tx53_fixup_rtc(blob);
+       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
 }
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
index 15324068d4c412c82287b5f2242b89da8071bf0a..239032a697d9f0d4e6fae354fe94084cd5f361a0 100644 (file)
@@ -845,10 +845,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");
@@ -953,6 +957,25 @@ 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;
+       }
 
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
@@ -1140,81 +1163,6 @@ struct node_info nodes[] = {
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif
 
-static int flexcan_enabled(void *blob)
-{
-       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;
-
-       ph = fdt_create_phandle(blob, off);
-       if (!ph)
-               return;
-
-       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");
@@ -1227,7 +1175,7 @@ void ft_board_setup(void *blob, bd_t *bd)
 
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
-       tx6qdl_fixup_flexcan(blob, stk5_v5);
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
        karo_fdt_update_fb_mode(blob, getenv("video_mode"));
 }
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
index 2f7d93b915daced42f03d8306685a8723c61d866..2b9d4baaa0b1a0f3076cb5a9d375a76a8daad173 100644 (file)
@@ -63,7 +63,7 @@ iomux_v3_cfg_t const usdhc1_pads[] = {
        MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* Carrier MicroSD Card Detect */
-       MX6_PAD_GPIO_2__GPIO_1_2      | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_GPIO_2__GPIO_1_2,
 };
 
 static iomux_v3_cfg_t const usdhc3_pads[] = {
@@ -74,7 +74,7 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* SOM MicroSD Card Detect */
-       MX6_PAD_EIM_DA9__GPIO_3_9     | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_DA9__GPIO_3_9,
 };
 
 static iomux_v3_cfg_t const enet_pads[] = {
@@ -94,7 +94,7 @@ static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_EIM_D29__GPIO_3_29              | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D29__GPIO_3_29,
 };
 
 static void setup_iomux_uart(void)
index 1ced298fe2bfed8ab2a159c09f0b9fbef36c2cca..ca8b5f6931a446ad9ba376be75b091ba02b8fb9a 100644 (file)
@@ -259,8 +259,12 @@ $(obj)../tools/envcrc:
        $(MAKE) -C ../tools
 
 # SEE README.arm-unaligned-accesses
-$(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+$(obj)cmd_bmp.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
 $(obj)fdt_support.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+$(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+ifneq ($(CONFIG_CMD_BMP)$(CONFIG_SPLASH_SCREEN),)
+$(obj)lcd.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+endif
 
 #########################################################################
 
index 18af0fa312339026cc0d3dedb3e80166a002d3b7..ce7527a931563f49fa585964451b60c1415a2816 100644 (file)
@@ -515,7 +515,8 @@ int fdt_resize(void *blob)
        ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
        if (ret < 0)
                return ret;
-
+       if (getenv("fdtsize"))
+               setenv_hex("fdtsize", actualsize);
        return actualsize;
 }
 
index d4f12e931e491881da0b84357d6475ef8cd4cbcc..017f6220d10acc01a16b3ebea69ba1b738afebb9 100644 (file)
@@ -437,30 +437,6 @@ static int mxcfb_unmap_video_memory(struct fb_info *fbi)
        return 0;
 }
 
-void ipuv3_fb_shutdown(void)
-{
-       int i;
-       struct ipu_stat *stat = (struct ipu_stat *)IPU_STAT;
-
-       for (i = 0; i < ARRAY_SIZE(mxcfb_info); i++) {
-               struct fb_info *fbi = mxcfb_info[i];
-
-               if (fbi) {
-                       struct mxcfb_info *mxc_fbi = fbi->par;
-
-                       ipu_disable_channel(mxc_fbi->ipu_ch);
-                       ipu_uninit_channel(mxc_fbi->ipu_ch);
-               }
-       }
-
-       clk_enable(g_ipu_clk);
-       for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
-               __raw_writel(__raw_readl(&stat->int_stat[i]),
-                       &stat->int_stat[i]);
-       }
-       clk_disable(g_ipu_clk);
-}
-
 /*
  * Initializes the framebuffer information pointer. After allocating
  * sufficient memory for the framebuffer structure, the fields are
@@ -590,6 +566,27 @@ ulong calc_fbsize(void)
                NBITS(panel_info.vl_bpix)) / 8;
 }
 
+void ipuv3_fb_shutdown(void)
+{
+       int i;
+       struct ipu_stat *stat = (struct ipu_stat *)IPU_STAT;
+
+       for (i = 0; i < ARRAY_SIZE(mxcfb_info); i++) {
+               struct fb_info *fbi = mxcfb_info[i];
+               if (fbi) {
+                       struct mxcfb_info *mxc_fbi = fbi->par;
+                       ipu_disable_channel(mxc_fbi->ipu_ch);
+                       ipu_uninit_channel(mxc_fbi->ipu_ch);
+               }
+       }
+       clk_enable(g_ipu_clk);
+       for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
+               __raw_writel(__raw_readl(&stat->int_stat[i]),
+                            &stat->int_stat[i]);
+       }
+       clk_disable(g_ipu_clk);
+}
+
 int ipuv3_fb_init(struct fb_videomode *mode, int di, unsigned int interface_pix_fmt,
                ipu_di_clk_parent_t di_clk_parent, unsigned long di_clk_val, int bpp)
 {
index 145e0a74b68649108e44d5c05b8d7776d88c6888..43b72183aad9218805c07221757ba4df7b2e68e4 100644 (file)
 #define CONFIG_FEC_MXC_PHYADDR         0x00
 #endif
 
+#define CONFIG_PHY_SMSC
+#define CONFIG_PHYLIB
 #define CONFIG_MII
 #define CONFIG_FEC_XCV_TYPE            RMII
 #define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM