X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=board%2Fkaro%2Ftx48%2Ftx48.c;h=10b939095d350b63c1715946430fc8525f29f08c;hp=59df3a706a175278ba446ef447a76a4535c63c70;hb=ab62e387cafb5e99819e24715dbc6496f5516e5a;hpb=bb0f32d0bad65fc6948ce6032f9004a70e11fef4 diff --git a/board/karo/tx48/tx48.c b/board/karo/tx48/tx48.c index 59df3a706a..10b939095d 100644 --- a/board/karo/tx48/tx48.c +++ b/board/karo/tx48/tx48.c @@ -1,13 +1,12 @@ /* - * tx48.c - * Copyright (C) 2012 Lothar Waßmann + * Copyright (C) 2012-2013 Lothar Waßmann * * based on evm.c * 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 +25,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +34,7 @@ #include #include #include -#include #include -#include #include #include @@ -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) @@ -306,6 +301,7 @@ struct pin_mux { #define PAD_CTRL_BASE 0x800 #define OFFSET(x) (unsigned int) (&((struct pad_signals *) \ (PAD_CTRL_BASE))->x) + /* * Configure the pin mux for the module */ @@ -315,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) @@ -324,13 +320,6 @@ static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux, #define PRM_RSTST_EXTERNAL_WARM_RST (1 << 5) #define PRM_RSTST_ICEPICK_RST (1 << 9) -struct prm_device { - unsigned int prmrstctrl; /* offset 0x00 */ - unsigned int prmrsttime; /* offset 0x04 */ - unsigned int prmrstst; /* offset 0x08 */ - /* ... */ -}; - static u32 prm_rstst __attribute__((section(".data"))); /* @@ -345,6 +334,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, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", }, + { TX48_MMC_CD_GPIO, GPIOF_INPUT, "MMC0 CD", }, }; static const struct pin_mux stk5_lcd_pads[] = { @@ -372,10 +368,6 @@ 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", }, @@ -392,32 +384,153 @@ static const struct gpio stk5v5_gpios[] = { }; #ifdef CONFIG_LCD +static u16 tx48_cmap[256]; vidinfo_t panel_info = { /* set to max. size supported by SoC */ .vl_col = 1366, .vl_row = 768, .vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */ + .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 */ void *lcd_console_address; /* Start of console buffer */ -int lcd_line_length; int lcd_color_fg; int lcd_color_bg; @@ -425,6 +538,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) { @@ -446,22 +565,49 @@ 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); + gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, + lcd_backlight_polarity()); } } void lcd_disable(void) { - da8xx_fb_disable(); + 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) { - gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1); + debug("Switching LCD off\n"); + 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); } @@ -470,93 +616,177 @@ void lcd_panel_disable(void) void lcd_ctrl_init(void *lcdbase) { int color_depth = 24; - char *vm; + const char *video_mode = karo_get_vmode(getenv("video_mode")); + const char *vm; 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)) { + if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) { + debug("Disabling LCD\n"); lcd_enabled = 0; + setenv("splashimage", NULL); return; } - vm = getenv("video_mode"); - if (vm == NULL) { + karo_fdt_move_fdt(); + lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt); + + if (video_mode == NULL) { + debug("Disabling LCD\n"); lcd_enabled = 0; return; } - - strncpy((char *)p->name, vm, sizeof(p->name)); - - val = simple_strtoul(vm, &vm, 0); - if (val != 0) { - if (val > panel_info.vl_col) - val = panel_info.vl_col; - p->width = val; - panel_info.vl_col = val; + 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); + 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, 0); - 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; + + 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", + video_mode, 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 { @@ -569,6 +799,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)); } @@ -580,8 +811,9 @@ 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! */ @@ -594,6 +826,9 @@ int board_init(void) /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + if (ctrlc()) + printf("CTRL-C detected\n"); + return 0; } @@ -631,31 +866,81 @@ static void show_reset_cause(u32 prm_rstst) /* called with default environment! */ int checkboard(void) { - struct prm_device *prmdev = (struct prm_device *)PRM_DEVICE; - - prm_rstst = readl(&prmdev->prmrstst); + 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; } +static void tx48_set_cpu_clock(void) +{ + unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0); + unsigned long act_cpu_clk; + + if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000) + return; + + if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) { + if (prm_rstst & PRM_RSTST_WDT1_RST) { + printf("Watchdog reset detected; skipping cpu clock change\n"); + } else { + printf(" detected; skipping cpu clock change\n"); + } + return; + } + + mpu_pll_config_val(cpu_clk); + + 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) +{ + 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; -#ifdef CONFIG_OF_BOARD_SETUP + tx48_set_cpu_clock(); 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); @@ -671,10 +956,13 @@ int board_late_init(void) } else { printf("WARNING: Unsupported baseboard: '%s'\n", baseboard); - return -EINVAL; + ret = -EINVAL; } - return 0; +exit: + tx48_init_mac(); + clear_ctrlc(); + return ret; } #ifdef CONFIG_DRIVER_TI_CPSW @@ -704,9 +992,15 @@ static struct cpsw_slave_data cpsw_slaves[] = { .slave_reg_ofs = 0x208, .sliver_reg_ofs = 0xd80, .phy_id = 0, + .phy_if = PHY_INTERFACE_MODE_RMII, }, }; +void s_init(void) +{ + /* Nothing to be done here */ +} + static struct cpsw_platform_data cpsw_data = { .mdio_base = CPSW_MDIO_BASE, .cpsw_base = CPSW_BASE, @@ -729,74 +1023,30 @@ 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)) { - debug("MAC addr set to: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac_addr[0], mac_addr[1], mac_addr[2], - mac_addr[3], mac_addr[4], mac_addr[5]); - 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); } #endif /* CONFIG_DRIVER_TI_CPSW */ -#if defined(CONFIG_NAND_AM33XX) && defined(CONFIG_CMD_SWITCH_ECC) -/****************************************************************************** - * Command to switch between NAND HW and SW ecc - *****************************************************************************/ -static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) +int cpu_mmc_init(bd_t *bis) { - int type = 0; - - if (argc < 2) - goto usage; - - if (strncmp(argv[1], "hw", 2) == 0) { - if (argc == 3) - type = simple_strtoul(argv[2], NULL, 10); - am33xx_nand_switch_ecc(NAND_ECC_HW, type); - } - else if (strncmp(argv[1], "sw", 2) == 0) - am33xx_nand_switch_ecc(NAND_ECC_SOFT, 0); - else - goto usage; - - return 0; - -usage: - printf("Usage: nandecc %s\n", cmdtp->usage); - return 1; + return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1); } +#endif -U_BOOT_CMD( - nandecc, 3, 1, do_switch_ecc, - "Switch NAND ECC calculation algorithm b/w hardware and software", - "[sw|hw ] \n" - " [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n" - " hw_type- 0 for Hamming code\n" - " 1 for bch4\n" - " 2 for bch8\n" - " 3 for bch16\n" -); -#endif /* CONFIG_NAND_AM33XX && CONFIG_CMD_SWITCH_ECC */ +void tx48_disable_watchdog(void) +{ + struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + + while (readl(&wdtimer->wdtwwps) & (1 << 4)) + ; + writel(0xaaaa, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) & (1 << 4)) + ; + writel(0x5555, &wdtimer->wdtwspr); +} enum { LED_STATE_INIT = -1, @@ -830,31 +1080,42 @@ void show_activity(int arg) #ifdef CONFIG_FDT_FIXUP_PARTITIONS #include #include -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 */ -static void tx48_fixup_flexcan(void *blob) +static const char *tx48_touchpanels[] = { + "ti,tsc2007", + "edt,edt-ft5x06", + "ti,am3359-tscadc", +}; + +void 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; - 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"); -} + ret = fdt_increase_size(blob, 4096); + if (ret) + printf("Failed to increase FDT size: %s\n", fdt_strerror(ret)); -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_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(); } #endif /* CONFIG_OF_BOARD_SETUP */