X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=board%2Fkaro%2Ftx6%2Ftx6ul.c;h=2c0a91fd535a54506e3b143e21eee256d54a0044;hp=ba936cd4a931c16d797b34660928563505ff2f4f;hb=9f552d0051a126bdd9d58d5d5aa8639338292e20;hpb=b613e722f29c16b73805731b93c405b391f34708 diff --git a/board/karo/tx6/tx6ul.c b/board/karo/tx6/tx6ul.c index ba936cd4a9..2c0a91fd53 100644 --- a/board/karo/tx6/tx6ul.c +++ b/board/karo/tx6/tx6ul.c @@ -34,6 +34,10 @@ #define TX6UL_FEC_RST_GPIO IMX_GPIO_NR(5, 6) #define TX6UL_FEC_PWR_GPIO IMX_GPIO_NR(5, 7) #define TX6UL_FEC_INT_GPIO IMX_GPIO_NR(5, 5) + +#define TX6UL_FEC2_RST_GPIO IMX_GPIO_NR(4, 28) +#define TX6UL_FEC2_INT_GPIO IMX_GPIO_NR(4, 27) + #define TX6UL_LED_GPIO IMX_GPIO_NR(5, 9) #define TX6UL_LCD_PWR_GPIO IMX_GPIO_NR(5, 4) @@ -127,7 +131,9 @@ static const iomux_v3_cfg_t const tx6ul_enet1_pads[] = { MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(TX6_ENET_PAD_CTRL), MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(TX6_ENET_PAD_CTRL), MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(TX6_ENET_PAD_CTRL), +}; +static const iomux_v3_cfg_t const tx6ul_enet2_pads[] = { MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_CFG_SION | MUX_PAD_CTRL(PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_48ohm | @@ -148,8 +154,10 @@ static const iomux_v3_cfg_t const tx6ul_enet1_pads[] = { static const iomux_v3_cfg_t const tx6_i2c_gpio_pads[] = { /* internal I2C */ - MX6_PAD_SNVS_TAMPER1__GPIO5_IO01 | MUX_CFG_SION | MUX_PAD_CTRL(TX6_I2C_PAD_CTRL), - MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_CFG_SION | MUX_PAD_CTRL(TX6_I2C_PAD_CTRL), + MX6_PAD_SNVS_TAMPER1__GPIO5_IO01 | MUX_CFG_SION | + MUX_PAD_CTRL(TX6_I2C_PAD_CTRL), + MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_CFG_SION | + MUX_PAD_CTRL(TX6_I2C_PAD_CTRL), }; static const struct gpio const tx6ul_gpios[] = { @@ -162,10 +170,16 @@ static const struct gpio const tx6ul_gpios[] = { { TX6UL_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", }, }; +static const struct gpio const tx6ul_fec2_gpios[] = { + { TX6UL_FEC2_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC2 PHY RESET", }, + { TX6UL_FEC2_INT_GPIO, GPIOFLAG_INPUT, "FEC2 PHY INT", }, +}; + #define GPIO_DR 0 #define GPIO_DIR 4 #define GPIO_PSR 8 +/* run with default environment */ static void tx6_i2c_recover(void) { int i; @@ -578,6 +592,12 @@ int board_mmc_init(bd_t *bis) debug("%s@%d: \n", __func__, __LINE__); +#ifndef CONFIG_ENV_IS_IN_MMC + if (!(gd->flags & GD_FLG_ENV_READY)) { + printf("deferred ..."); + return 0; + } +#endif for (i = 0; i < ARRAY_SIZE(tx6ul_esdhc_cfg); i++) { struct mmc *mmc; struct tx6_esdhc_cfg *cfg = &tx6ul_esdhc_cfg[i]; @@ -609,70 +629,11 @@ int board_mmc_init(bd_t *bis) } #endif /* CONFIG_CMD_MMC */ -#ifdef CONFIG_FEC_MXC - -#ifndef ETH_ALEN -#define ETH_ALEN 6 -#endif - -int board_eth_init(bd_t *bis) -{ - int ret; - - debug("%s@%d: \n", __func__, __LINE__); - - /* delay at least 21ms for the PHY internal POR signal to deassert */ - udelay(22000); - - imx_iomux_v3_setup_multiple_pads(tx6ul_enet1_pads, - ARRAY_SIZE(tx6ul_enet1_pads)); - - /* Deassert RESET to the external phy */ - gpio_set_value(TX6UL_FEC_RST_GPIO, 1); - - if (getenv("ethaddr")) { - ret = fecmxc_initialize_multi(bis, 0, -1, ENET_BASE_ADDR); - if (ret) { - printf("failed to initialize FEC0: %d\n", ret); - return ret; - } - } - if (getenv("eth1addr")) { - ret = fecmxc_initialize_multi(bis, 1, -1, ENET2_BASE_ADDR); - if (ret) { - printf("failed to initialize FEC1: %d\n", ret); - return ret; - } - } - return 0; -} - -static void tx6_init_mac(void) -{ - u8 mac[ETH_ALEN]; - - imx_get_mac_from_fuse(0, mac); - if (!is_valid_ethaddr(mac)) { - printf("No valid MAC address programmed\n"); - return; - } - - printf("MAC addr from fuse: %pM\n", mac); - eth_setenv_enetaddr("ethaddr", mac); - - imx_get_mac_from_fuse(1, mac); - eth_setenv_enetaddr("eth1addr", mac); -} -#else -static inline void tx6_init_mac(void) -{ -} -#endif /* CONFIG_FEC_MXC */ - enum { LED_STATE_INIT = -1, LED_STATE_OFF, LED_STATE_ON, + LED_STATE_ERR, }; static inline int calc_blink_rate(void) @@ -690,13 +651,24 @@ void show_activity(int arg) static int led_state = LED_STATE_INIT; static int blink_rate; static ulong last; + int ret; + + switch (led_state) { + case LED_STATE_ERR: + return; - if (led_state == LED_STATE_INIT) { + case LED_STATE_INIT: last = get_timer(0); - gpio_set_value(TX6UL_LED_GPIO, 1); - led_state = LED_STATE_ON; + ret = gpio_set_value(TX6UL_LED_GPIO, 1); + if (ret) + led_state = LED_STATE_ERR; + else + led_state = LED_STATE_ON; blink_rate = calc_blink_rate(); - } else { + break; + + case LED_STATE_ON: + case LED_STATE_OFF: if (get_timer(last) > blink_rate) { blink_rate = calc_blink_rate(); last = get_timer_masked(); @@ -707,6 +679,7 @@ void show_activity(int arg) } led_state = 1 - led_state; } + break; } } @@ -933,57 +906,14 @@ static int lcd_backlight_polarity(void) return lcd_bl_polarity; } -void lcd_enable(void) -{ - /* HACK ALERT: - * global variable from common/lcd.c - * Set to 0 here to prevent messages from going to LCD - * rather than serial console - */ - lcd_is_enabled = 0; - - if (lcd_enabled) { - karo_load_splashimage(1); - - debug("Switching LCD on\n"); - gpio_set_value(TX6UL_LCD_PWR_GPIO, 1); - udelay(100); - gpio_set_value(TX6UL_LCD_RST_GPIO, 1); - udelay(300000); - gpio_set_value(TX6UL_LCD_BACKLIGHT_GPIO, - lcd_backlight_polarity()); - } -} - -void lcd_disable(void) -{ - if (lcd_enabled) { - printf("Disabling LCD\n"); -// ipuv3_fb_shutdown(); - } -} - -void lcd_panel_disable(void) -{ - if (lcd_enabled) { - debug("Switching LCD off\n"); - gpio_set_value(TX6UL_LCD_BACKLIGHT_GPIO, - !lcd_backlight_polarity()); - gpio_set_value(TX6UL_LCD_RST_GPIO, 0); - gpio_set_value(TX6UL_LCD_PWR_GPIO, 0); - } -} - static const iomux_v3_cfg_t stk5_lcd_pads[] = { -#if 1 +#ifdef CONFIG_LCD /* LCD RESET */ - MX6_PAD_LCD_RESET__LCDIF_RESET, + MX6_PAD_LCD_RESET__GPIO3_IO04 | MUX_PAD_CTRL(TX6_GPIO_OUT_PAD_CTRL), /* LCD POWER_ENABLE */ MX6_PAD_SNVS_TAMPER4__GPIO5_IO04 | MUX_PAD_CTRL(TX6_GPIO_OUT_PAD_CTRL), /* LCD Backlight (PWM) */ MX6_PAD_NAND_DQS__GPIO4_IO16 | MUX_PAD_CTRL(TX6_GPIO_OUT_PAD_CTRL), -#endif -#ifdef CONFIG_LCD /* Display */ MX6_PAD_LCD_DATA00__LCDIF_DATA00, MX6_PAD_LCD_DATA01__LCDIF_DATA01, @@ -1017,11 +947,43 @@ static const iomux_v3_cfg_t stk5_lcd_pads[] = { }; static const struct gpio stk5_lcd_gpios[] = { -// { TX6UL_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", }, + { TX6UL_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", }, { TX6UL_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", }, { TX6UL_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", }, }; +/* run with valid env from NAND/eMMC */ +void lcd_enable(void) +{ + /* HACK ALERT: + * global variable from common/lcd.c + * Set to 0 here to prevent messages from going to LCD + * rather than serial console + */ + lcd_is_enabled = 0; + + if (lcd_enabled) { + karo_load_splashimage(1); + + debug("Switching LCD on\n"); + gpio_set_value(TX6UL_LCD_PWR_GPIO, 1); + udelay(100); + gpio_set_value(TX6UL_LCD_RST_GPIO, 1); + udelay(300000); + gpio_set_value(TX6UL_LCD_BACKLIGHT_GPIO, + lcd_backlight_polarity()); + } +} + +static void lcd_disable(void) +{ + if (lcd_enabled) { + printf("Disabling LCD\n"); + panel_info.vl_row = 0; + lcd_enabled = 0; + } +} + void lcd_ctrl_init(void *lcdbase) { int color_depth = 24; @@ -1032,8 +994,6 @@ void lcd_ctrl_init(void *lcdbase) struct fb_videomode *p = &tx6_fb_modes[0]; struct fb_videomode fb_mode; int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0; - int pix_fmt; - int lcd_bus_width; if (!lcd_enabled) { debug("LCD disabled\n"); @@ -1041,8 +1001,7 @@ void lcd_ctrl_init(void *lcdbase) } if (had_ctrlc() || (wrsr & WRSR_TOUT)) { - debug("Disabling LCD\n"); - lcd_enabled = 0; + lcd_disable(); setenv("splashimage", NULL); return; } @@ -1051,8 +1010,7 @@ void lcd_ctrl_init(void *lcdbase) lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt); if (video_mode == NULL) { - debug("Disabling LCD\n"); - lcd_enabled = 0; + lcd_disable(); return; } vm = video_mode; @@ -1101,22 +1059,14 @@ void lcd_ctrl_init(void *lcdbase) yres_set = 1; } else if (!bpp_set) { switch (val) { - case 32: - case 24: - if (is_lvds()) - pix_fmt = IPU_PIX_FMT_LVDS888; - /* fallthru */ - case 16: case 8: + case 16: + case 18: + case 24: + case 32: color_depth = val; break; - case 18: - if (is_lvds()) { - color_depth = val; - break; - } - /* fallthru */ default: printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n", end - vm, vm, color_depth); @@ -1201,67 +1151,24 @@ void lcd_ctrl_init(void *lcdbase) imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads)); - lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24); - switch (lcd_bus_width) { - case 24: - pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24; - break; - - case 18: - pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666; - break; + debug("video format: %ux%u-%u@%u\n", p->xres, p->yres, + color_depth, refresh); - case 16: - if (!is_lvds()) { - pix_fmt = IPU_PIX_FMT_RGB565; - break; - } - /* fallthru */ - default: - lcd_enabled = 0; - printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD", - lcd_bus_width); - return; - } - if (is_lvds()) { - int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0); - int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt); - uint32_t gpr2; - uint32_t gpr3; - - if (lvds_chan_mask == 0) { - printf("No LVDS channel active\n"); - lcd_enabled = 0; - return; - } - - gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8); - if (lcd_bus_width == 24) - gpr2 |= (1 << 5) | (1 << 7); - gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0; - gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0; - debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8); - writel(gpr2, IOMUXC_BASE_ADDR + 8); - - gpr3 = readl(IOMUXC_BASE_ADDR + 0xc); - gpr3 &= ~((3 << 8) | (3 << 6)); - writel(gpr3, IOMUXC_BASE_ADDR + 0xc); - } if (karo_load_splashimage(0) == 0) { -#if 0 - int ret; + char vmode[128]; + + /* setup env variable for mxsfb display driver */ + snprintf(vmode, sizeof(vmode), + "x:%d,y:%d,le:%d,ri:%d,up:%d,lo:%d,hs:%d,vs:%d,sync:%d,pclk:%d,depth:%d", + p->xres, p->yres, p->left_margin, p->right_margin, + p->upper_margin, p->lower_margin, p->hsync_len, + p->vsync_len, p->sync, p->pixclock, color_depth); + setenv("videomode", vmode); debug("Initializing LCD controller\n"); - ret = ipuv3_fb_init(p, 0, pix_fmt, - is_lvds() ? DI_PCLK_LDB : DI_PCLK_PLL3, - di_clk_rate, -1); - if (ret) { - printf("Failed to initialize FB driver: %d\n", ret); - lcd_enabled = 0; - } -#else - lcd_enabled = pix_fmt * 0; -#endif + lcdif_clk_enable(); + video_hw_init(); + setenv("videomode", NULL); } else { debug("Skipping initialization of LCD controller\n"); } @@ -1270,6 +1177,20 @@ void lcd_ctrl_init(void *lcdbase) #define lcd_enabled 0 #endif /* CONFIG_LCD */ +#ifndef CONFIG_ENV_IS_IN_MMC +static void tx6_mmc_init(void) +{ + puts("MMC: "); + if (board_mmc_init(gd->bd) < 0) + cpu_mmc_init(gd->bd); + print_mmc_devices(','); +} +#else +static inline void tx6_mmc_init(void) +{ +} +#endif + static void stk5_board_init(void) { int ret; @@ -1280,14 +1201,15 @@ static void stk5_board_init(void) return; } imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads)); -debug("%s@%d: \n", __func__, __LINE__); + debug("%s@%d: \n", __func__, __LINE__); } static void stk5v3_board_init(void) { -debug("%s@%d: \n", __func__, __LINE__); + debug("%s@%d: \n", __func__, __LINE__); stk5_board_init(); -debug("%s@%d: \n", __func__, __LINE__); + debug("%s@%d: \n", __func__, __LINE__); + tx6_mmc_init(); } static void stk5v5_board_init(void) @@ -1295,6 +1217,7 @@ static void stk5v5_board_init(void) int ret; stk5_board_init(); + tx6_mmc_init(); ret = gpio_request_one(IMX_GPIO_NR(3, 5), GPIOFLAG_OUTPUT_INIT_HIGH, "Flexcan Transceiver"); @@ -1330,7 +1253,6 @@ static void tx6ul_set_cpu_clock(void) int board_late_init(void) { - int ret = 0; const char *baseboard; debug("%s@%d: \n", __func__, __LINE__); @@ -1372,21 +1294,108 @@ int board_late_init(void) printf("WARNING: Unsupported STK5 board rev.: %s\n", baseboard + 4); } + } else if (strncmp(baseboard, "ulmb-", 5) == 0) { + const char *otg_mode = getenv("otg_mode"); + + if (otg_mode && strcmp(otg_mode, "host") == 0) { + printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n", + otg_mode, baseboard); + setenv("otg_mode", "none"); + } + stk5_board_init(); } else { printf("WARNING: Unsupported baseboard: '%s'\n", baseboard); - ret = -EINVAL; + if (!had_ctrlc()) + return -EINVAL; } exit: -debug("%s@%d: \n", __func__, __LINE__); - tx6_init_mac(); -debug("%s@%d: \n", __func__, __LINE__); + debug("%s@%d: \n", __func__, __LINE__); clear_ctrlc(); - return ret; + return 0; +} + +#ifdef CONFIG_FEC_MXC + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +static void tx6_init_mac(void) +{ + u8 mac[ETH_ALEN]; + const char *baseboard = getenv("baseboard"); + + imx_get_mac_from_fuse(0, mac); + if (!is_valid_ethaddr(mac)) { + printf("No valid MAC address programmed\n"); + return; + } + printf("MAC addr from fuse: %pM\n", mac); + if (!getenv("ethaddr")) + eth_setenv_enetaddr("ethaddr", mac); + + if (!baseboard || strncmp(baseboard, "stk5", 4) == 0) { + setenv("eth1addr", NULL); + return; + } + if (getenv("eth1addr")) + return; + imx_get_mac_from_fuse(1, mac); + eth_setenv_enetaddr("eth1addr", mac); } +int board_eth_init(bd_t *bis) +{ + int ret; + + tx6_init_mac(); + + /* delay at least 21ms for the PHY internal POR signal to deassert */ + udelay(22000); + + imx_iomux_v3_setup_multiple_pads(tx6ul_enet1_pads, + ARRAY_SIZE(tx6ul_enet1_pads)); + + /* Deassert RESET to the external phys */ + gpio_set_value(TX6UL_FEC_RST_GPIO, 1); + + if (getenv("ethaddr")) { + ret = fecmxc_initialize_multi(bis, 0, 0, ENET_BASE_ADDR); + if (ret) { + printf("failed to initialize FEC0: %d\n", ret); + return ret; + } + } + if (getenv("eth1addr")) { + ret = gpio_request_array(tx6ul_fec2_gpios, + ARRAY_SIZE(tx6ul_fec2_gpios)); + if (ret < 0) { + printf("Failed to request tx6ul_fec2_gpios: %d\n", ret); + } + imx_iomux_v3_setup_multiple_pads(tx6ul_enet2_pads, + ARRAY_SIZE(tx6ul_enet2_pads)); + + writel(0x00100000, 0x020c80e4); /* assert ENET2_125M_EN */ + + /* Minimum PHY reset duration */ + udelay(100); + gpio_set_value(TX6UL_FEC2_RST_GPIO, 1); + /* Wait for PHY internal POR to finish */ + udelay(22000); + + ret = fecmxc_initialize_multi(bis, 1, 2, ENET2_BASE_ADDR); + if (ret) { + printf("failed to initialize FEC1: %d\n", ret); + return ret; + } + } + return 0; +} +#endif /* CONFIG_FEC_MXC */ + #ifdef CONFIG_SERIAL_TAG void get_board_serial(struct tag_serialnr *serialnr) {