]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/karo/tx48/tx48.c
net: cosmetic: Name ethaddr variables consistently
[karo-tx-uboot.git] / board / karo / tx48 / tx48.c
index a5f953635cf43500fd5dbd639753b66a8d964bf3..95a98a92362a7528805bcc14fc752a29705b2065 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * tx48.c
- * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
  *
  * based on evm.c
  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
@@ -35,7 +34,6 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
-#include <asm/arch/nand.h>
 #include <asm/arch/clock.h>
 #include <video_fb.h>
 #include <asm/arch/da8xx-fb.h>
@@ -49,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define TX48_LCD_RST_GPIO      AM33XX_GPIO_NR(1, 19)
 #define TX48_LCD_PWR_GPIO      AM33XX_GPIO_NR(1, 22)
 #define TX48_LCD_BACKLIGHT_GPIO        AM33XX_GPIO_NR(3, 14)
+#define TX48_MMC_CD_GPIO       AM33XX_GPIO_NR(3, 15)
 
 #define GMII_SEL               (CTRL_BASE + 0x650)
 
@@ -73,10 +72,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define NO_OF_MAC_ADDR         1
 #define ETH_ALEN               6
 
-#define MUX_CFG(value, offset) {                                       \
-       __raw_writel(value, (CTRL_BASE + (offset)));                    \
-       }
-
 /* PAD Control Fields */
 #define SLEWCTRL       (0x1 << 6)
 #define        RXACTIVE        (0x1 << 5)
@@ -316,7 +311,7 @@ static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
        int i;
 
        for (i = 0; i < num_pins; i++)
-               MUX_CFG(pin_mux[i].val, pin_mux[i].reg_offset);
+               writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
 }
 
 #define PRM_RSTST_GLOBAL_COLD_RST      (1 << 0)
@@ -330,6 +325,23 @@ static u32 prm_rstst __attribute__((section(".data")));
 /*
  * Basic board specific setup
  */
+static const struct pin_mux tx48_pads[] = {
+       { OFFSET(i2c0_sda), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(emu1), MODE(7), }, /* ETH PHY Reset */
+};
+
+static const struct pin_mux tx48_i2c_pads[] = {
+       { OFFSET(i2c0_sda), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+};
+
+static const struct gpio tx48_gpios[] = {
+       { AM33XX_GPIO_NR(3, 5), GPIOFLAG_INPUT, "I2C1_SDA", },
+       { AM33XX_GPIO_NR(3, 6), GPIOFLAG_INPUT, "I2C1_SCL", },
+       { AM33XX_GPIO_NR(3, 8), GPIOFLAG_OUTPUT_INIT_LOW, "ETH_PHY_RESET", },
+};
+
 static const struct pin_mux stk5_pads[] = {
        /* heartbeat LED */
        { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
@@ -339,6 +351,13 @@ static const struct pin_mux stk5_pads[] = {
        { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
        /* LCD Backlight (PWM) */
        { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
+       /* MMC CD */
+       { OFFSET(mcasp0_fsx), MODE(7) | PULLUDEN | PULLUP_EN, },
+};
+
+static const struct gpio stk5_gpios[] = {
+       { TX48_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+       { TX48_MMC_CD_GPIO, GPIOFLAG_INPUT, "MMC0 CD", },
 };
 
 static const struct pin_mux stk5_lcd_pads[] = {
@@ -366,14 +385,10 @@ static const struct pin_mux stk5_lcd_pads[] = {
        { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
 };
 
-static const struct gpio stk5_gpios[] = {
-       { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
-};
-
 static const struct gpio stk5_lcd_gpios[] = {
-       { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
-       { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
-       { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+       { AM33XX_GPIO_NR(1, 19), GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { AM33XX_GPIO_NR(1, 22), GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { AM33XX_GPIO_NR(3, 14), GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
 };
 
 static const struct pin_mux stk5v5_pads[] = {
@@ -382,7 +397,7 @@ static const struct pin_mux stk5v5_pads[] = {
 };
 
 static const struct gpio stk5v5_gpios[] = {
-       { AM33XX_GPIO_NR(0, 22), GPIOF_OUTPUT_INIT_HIGH, "CAN XCVR", },
+       { AM33XX_GPIO_NR(0, 22), GPIOFLAG_OUTPUT_INIT_HIGH, "CAN XCVR", },
 };
 
 #ifdef CONFIG_LCD
@@ -392,7 +407,7 @@ vidinfo_t panel_info = {
        .vl_col = 1366,
        .vl_row = 768,
 
-       .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
        .cmap = tx48_cmap,
 };
 
@@ -540,6 +555,12 @@ short console_col;
 short console_row;
 
 static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
 
 void lcd_initcolregs(void)
 {
@@ -566,7 +587,8 @@ void lcd_enable(void)
                udelay(100);
                gpio_set_value(TX48_LCD_RST_GPIO, 1);
                udelay(300000);
-               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
+               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
        }
 }
 
@@ -601,7 +623,8 @@ 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_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
                gpio_set_value(TX48_LCD_PWR_GPIO, 0);
                gpio_set_value(TX48_LCD_RST_GPIO, 0);
        }
@@ -610,7 +633,8 @@ void lcd_panel_disable(void)
 void lcd_ctrl_init(void *lcdbase)
 {
        int color_depth = 24;
-       char *vm, *v;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
        unsigned long val;
        int refresh = 60;
        struct fb_videomode *p = &tx48_fb_modes[0];
@@ -622,7 +646,7 @@ void lcd_ctrl_init(void *lcdbase)
                return;
        }
 
-       if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
                setenv("splashimage", NULL);
@@ -631,17 +655,15 @@ void lcd_ctrl_init(void *lcdbase)
 
        karo_fdt_move_fdt();
 
-       vm = getenv("video_mode");
-       if (vm == NULL) {
+       if (video_mode == NULL) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
                return;
        }
 
-       if ((v = strstr(vm, ":")))
-               vm = v + 1;
-
-       if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
                p = &fb_mode;
                debug("Using video mode from FDT\n");
                vm += strlen(vm);
@@ -751,7 +773,7 @@ void lcd_ctrl_init(void *lcdbase)
                panel_info.vl_bpix = LCD_COLOR16;
                break;
        default:
-               panel_info.vl_bpix = LCD_COLOR24;
+               panel_info.vl_bpix = LCD_COLOR32;
        }
 
        p->pixclock = KHZ2PICOS(refresh *
@@ -764,14 +786,13 @@ void lcd_ctrl_init(void *lcdbase)
 
        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);
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
                if (ret)
                        printf("Failed to create new display-timing node from '%s': %d\n",
-                               modename, ret);
+                               video_mode, ret);
        }
 
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
@@ -796,6 +817,7 @@ void lcd_ctrl_init(void *lcdbase)
 
 static void stk5_board_init(void)
 {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
        tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
 }
 
@@ -807,13 +829,16 @@ static void stk5v3_board_init(void)
 static void stk5v5_board_init(void)
 {
        stk5_board_init();
-       tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
+
        gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
+       tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
 }
 
 /* called with default environment! */
 int board_init(void)
 {
+       int i;
+
        /* mach type passed to kernel */
 #ifdef CONFIG_OF_LIBFDT
        gd->bd->bi_arch_number = -1;
@@ -821,6 +846,24 @@ int board_init(void)
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
+       if (ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               if (prm_rstst & PRM_RSTST_WDT1_RST)
+                       printf("WDOG RESET detected\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+       }
+
+       gpio_request_array(tx48_gpios, ARRAY_SIZE(tx48_gpios));
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_pads));
+
+       for (i = 0; i < ARRAY_SIZE(tx48_gpios); i++) {
+               int gpio = tx48_gpios[i].gpio;
+
+               if (gpio_get_value(gpio) == 0)
+                       gpio_direction_output(gpio, 1);
+       }
+
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_i2c_pads));
        return 0;
 }
 
@@ -861,11 +904,8 @@ int checkboard(void)
        prm_rstst = readl(PRM_RSTST);
        show_reset_cause(prm_rstst);
 
-#ifdef CONFIG_OF_LIBFDT
-       printf("Board: Ka-Ro TX48-7020 with FDT support\n");
-#else
        printf("Board: Ka-Ro TX48-7020\n");
-#endif
+
        timer_init();
        return 0;
 }
@@ -873,18 +913,29 @@ int checkboard(void)
 static void tx48_set_cpu_clock(void)
 {
        unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       unsigned long act_cpu_clk;
 
-       if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST))
+       if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
                return;
 
-       if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (prm_rstst & PRM_RSTST_WDT1_RST) ?
+                       "WDOG RESET" : "<CTRL-C>");
                return;
+       }
 
        mpu_pll_config_val(cpu_clk);
 
-       printf("CPU clock set to %lu.%03lu MHz\n",
-               mpu_clk_rate() / 1000000,
-               mpu_clk_rate() / 1000 % 1000);
+       act_cpu_clk = mpu_clk_rate();
+       if (cpu_clk * 1000000 != act_cpu_clk) {
+               printf("Failed to set CPU clock to %lu MHz; using %lu.%03lu MHz instead\n",
+                       cpu_clk, act_cpu_clk / 1000000,
+                       act_cpu_clk / 1000 % 1000);
+       } else {
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       act_cpu_clk / 1000000, act_cpu_clk / 1000 % 1000);
+       }
 }
 
 static void tx48_init_mac(void)
@@ -903,7 +954,7 @@ static void tx48_init_mac(void)
        mac_addr[4] = mac_lo & 0xFF;
        mac_addr[5] = (mac_lo & 0xFF00) >> 8;
 
-       if (!is_valid_ether_addr(mac_addr)) {
+       if (!is_valid_ethaddr(mac_addr)) {
                printf("No valid MAC address programmed\n");
                return;
        }
@@ -917,8 +968,16 @@ int board_late_init(void)
        int ret = 0;
        const char *baseboard;
 
+       env_cleanup();
+
        tx48_set_cpu_clock();
-       karo_fdt_move_fdt();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (prm_rstst & PRM_RSTST_WDT1_RST)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
 
        baseboard = getenv("baseboard");
        if (!baseboard)
@@ -940,13 +999,15 @@ int board_late_init(void)
                        baseboard);
                ret = -EINVAL;
        }
+
 exit:
        tx48_init_mac();
+       clear_ctrlc();
        return ret;
 }
 
 #ifdef CONFIG_DRIVER_TI_CPSW
-static void tx48_phy_init(char *name, int addr)
+static void tx48_phy_init(void)
 {
        debug("%s: Resetting ethernet PHY\n", __func__);
 
@@ -995,7 +1056,6 @@ static struct cpsw_platform_data cpsw_data = {
        .hw_stats_reg_ofs       = 0x900,
        .mac_control            = (1 << 5) /* MIIEN */,
        .control                = cpsw_control,
-       .phy_init               = tx48_phy_init,
        .gigabit_en             = 0,
        .host_port_num          = 0,
        .version                = CPSW_CTRL_VERSION_2,
@@ -1005,10 +1065,18 @@ int board_eth_init(bd_t *bis)
 {
        __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
        __raw_writel(0x5D, GMII_SEL);
+       tx48_phy_init();
        return cpsw_register(&cpsw_data);
 }
 #endif /* CONFIG_DRIVER_TI_CPSW */
 
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int cpu_mmc_init(bd_t *bis)
+{
+       return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1);
+}
+#endif
+
 void tx48_disable_watchdog(void)
 {
        struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
@@ -1053,25 +1121,51 @@ void show_activity(int arg)
 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
 #include <jffs2/jffs2.h>
 #include <mtd_node.h>
-struct node_info nodes[] = {
+static struct node_info nodes[] = {
        { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
+       { "ti,am3352-gpmc", MTD_DEV_TYPE_NAND, },
 };
 
 #else
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
 
-void ft_board_setup(void *blob, bd_t *bd)
+static const char *tx48_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "ti,am3359-tscadc",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
        int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
 
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
        fdt_fixup_ethernet(blob);
 
-       karo_fdt_fixup_touchpanel(blob);
+       karo_fdt_fixup_touchpanel(blob, tx48_touchpanels,
+                               ARRAY_SIZE(tx48_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usb0", "phys", "vcc-supply");
        karo_fdt_fixup_flexcan(blob, stk5_v5);
 
+       karo_fdt_update_fb_mode(blob, video_mode);
+
        tx48_disable_watchdog();
+
+       if (get_cpu_rev() == 0) {
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34, "interrupts");
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34,
+                               "interrupt-parent");
+       }
+
+       return 0;
 }
 #endif /* CONFIG_OF_BOARD_SETUP */