X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=board%2Fkaro%2Ftx48%2Ftx48.c;h=7383738a249121f4a5812b5c04fdf244512d5fc1;hp=88602a5a36492f3246a7b06368a92c6d1c8257ce;hb=001bd08c07559603eade16459d72c17d5e4d5034;hpb=9fa95fb6b24bfaf48d7d295bd45cdb67f06456a7 diff --git a/board/karo/tx48/tx48.c b/board/karo/tx48/tx48.c index 88602a5a36..7383738a24 100644 --- a/board/karo/tx48/tx48.c +++ b/board/karo/tx48/tx48.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,11 +28,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -47,250 +47,12 @@ 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 GMII_SEL (CTRL_BASE + 0x650) - -/* UART Defines */ -#define UART_SYSCFG_OFFSET 0x54 -#define UART_SYSSTS_OFFSET 0x58 - -#define UART_RESET (0x1 << 1) -#define UART_CLK_RUNNING_MASK 0x1 -#define UART_SMART_IDLE_EN (0x1 << 0x3) - -/* Timer Defines */ -#define TSICR_REG 0x54 -#define TIOCP_CFG_REG 0x10 -#define TCLR_REG 0x38 - -/* RGMII mode define */ -#define RGMII_MODE_ENABLE 0xA -#define RMII_MODE_ENABLE 0x5 -#define MII_MODE_ENABLE 0x0 +#define TX48_MMC_CD_GPIO AM33XX_GPIO_NR(3, 15) #define NO_OF_MAC_ADDR 1 +#ifndef ETH_ALEN #define ETH_ALEN 6 - -/* PAD Control Fields */ -#define SLEWCTRL (0x1 << 6) -#define RXACTIVE (0x1 << 5) -#define PULLUP_EN (0x1 << 4) /* Pull UP Selection */ -#define PULLUDEN (0x0 << 3) /* Pull up enabled */ -#define PULLUDDIS (0x1 << 3) /* Pull up disabled */ -#define MODE(val) (val) - -/* - * PAD CONTROL OFFSETS - * Field names corresponds to the pad signal name - */ -struct pad_signals { - int gpmc_ad0; - int gpmc_ad1; - int gpmc_ad2; - int gpmc_ad3; - int gpmc_ad4; - int gpmc_ad5; - int gpmc_ad6; - int gpmc_ad7; - int gpmc_ad8; - int gpmc_ad9; - int gpmc_ad10; - int gpmc_ad11; - int gpmc_ad12; - int gpmc_ad13; - int gpmc_ad14; - int gpmc_ad15; - int gpmc_a0; - int gpmc_a1; - int gpmc_a2; - int gpmc_a3; - int gpmc_a4; - int gpmc_a5; - int gpmc_a6; - int gpmc_a7; - int gpmc_a8; - int gpmc_a9; - int gpmc_a10; - int gpmc_a11; - int gpmc_wait0; - int gpmc_wpn; - int gpmc_be1n; - int gpmc_csn0; - int gpmc_csn1; - int gpmc_csn2; - int gpmc_csn3; - int gpmc_clk; - int gpmc_advn_ale; - int gpmc_oen_ren; - int gpmc_wen; - int gpmc_be0n_cle; - int lcd_data0; - int lcd_data1; - int lcd_data2; - int lcd_data3; - int lcd_data4; - int lcd_data5; - int lcd_data6; - int lcd_data7; - int lcd_data8; - int lcd_data9; - int lcd_data10; - int lcd_data11; - int lcd_data12; - int lcd_data13; - int lcd_data14; - int lcd_data15; - int lcd_vsync; - int lcd_hsync; - int lcd_pclk; - int lcd_ac_bias_en; - int mmc0_dat3; - int mmc0_dat2; - int mmc0_dat1; - int mmc0_dat0; - int mmc0_clk; - int mmc0_cmd; - int mii1_col; - int mii1_crs; - int mii1_rxerr; - int mii1_txen; - int mii1_rxdv; - int mii1_txd3; - int mii1_txd2; - int mii1_txd1; - int mii1_txd0; - int mii1_txclk; - int mii1_rxclk; - int mii1_rxd3; - int mii1_rxd2; - int mii1_rxd1; - int mii1_rxd0; - int rmii1_refclk; - int mdio_data; - int mdio_clk; - int spi0_sclk; - int spi0_d0; - int spi0_d1; - int spi0_cs0; - int spi0_cs1; - int ecap0_in_pwm0_out; - int uart0_ctsn; - int uart0_rtsn; - int uart0_rxd; - int uart0_txd; - int uart1_ctsn; - int uart1_rtsn; - int uart1_rxd; - int uart1_txd; - int i2c0_sda; - int i2c0_scl; - int mcasp0_aclkx; - int mcasp0_fsx; - int mcasp0_axr0; - int mcasp0_ahclkr; - int mcasp0_aclkr; - int mcasp0_fsr; - int mcasp0_axr1; - int mcasp0_ahclkx; - int xdma_event_intr0; - int xdma_event_intr1; - int nresetin_out; - int porz; - int nnmi; - int osc0_in; - int osc0_out; - int rsvd1; - int tms; - int tdi; - int tdo; - int tck; - int ntrst; - int emu0; - int emu1; - int osc1_in; - int osc1_out; - int pmic_power_en; - int rtc_porz; - int rsvd2; - int ext_wakeup; - int enz_kaldo_1p8v; - int usb0_dm; - int usb0_dp; - int usb0_ce; - int usb0_id; - int usb0_vbus; - int usb0_drvvbus; - int usb1_dm; - int usb1_dp; - int usb1_ce; - int usb1_id; - int usb1_vbus; - int usb1_drvvbus; - int ddr_resetn; - int ddr_csn0; - int ddr_cke; - int ddr_ck; - int ddr_nck; - int ddr_casn; - int ddr_rasn; - int ddr_wen; - int ddr_ba0; - int ddr_ba1; - int ddr_ba2; - int ddr_a0; - int ddr_a1; - int ddr_a2; - int ddr_a3; - int ddr_a4; - int ddr_a5; - int ddr_a6; - int ddr_a7; - int ddr_a8; - int ddr_a9; - int ddr_a10; - int ddr_a11; - int ddr_a12; - int ddr_a13; - int ddr_a14; - int ddr_a15; - int ddr_odt; - int ddr_d0; - int ddr_d1; - int ddr_d2; - int ddr_d3; - int ddr_d4; - int ddr_d5; - int ddr_d6; - int ddr_d7; - int ddr_d8; - int ddr_d9; - int ddr_d10; - int ddr_d11; - int ddr_d12; - int ddr_d13; - int ddr_d14; - int ddr_d15; - int ddr_dqm0; - int ddr_dqm1; - int ddr_dqs0; - int ddr_dqsn0; - int ddr_dqs1; - int ddr_dqsn1; - int ddr_vref; - int ddr_vtp; - int ddr_strben0; - int ddr_strben1; - int ain7; - int ain6; - int ain5; - int ain4; - int ain3; - int ain2; - int ain1; - int ain0; - int vrefp; - int vrefn; -}; +#endif struct pin_mux { short reg_offset; @@ -324,6 +86,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, }, @@ -333,10 +112,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[] = { - { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", }, + { 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[] = { @@ -365,9 +147,9 @@ static const struct pin_mux stk5_lcd_pads[] = { }; 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[] = { @@ -376,18 +158,20 @@ 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 -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, + .vl_bpix = LCD_COLOR32, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */ +}; + +static struct lcd_ctrl_config lcd_cfg = { + .bpp = 24, }; #define FB_SYNC_OE_LOW_ACT (1 << 31) @@ -534,6 +318,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) { @@ -560,7 +350,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()); } } @@ -595,7 +386,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); } @@ -604,7 +396,7 @@ void lcd_panel_disable(void) void lcd_ctrl_init(void *lcdbase) { int color_depth = 24; - const char *video_mode = getenv("video_mode"); + const char *video_mode = karo_get_vmode(getenv("video_mode")); const char *vm; unsigned long val; int refresh = 60; @@ -626,14 +418,15 @@ void lcd_ctrl_init(void *lcdbase) karo_fdt_move_fdt(); - vm = karo_fdt_set_display(video_mode, "/panel", NULL); - if (vm == NULL) { + if (video_mode == NULL) { debug("Disabling LCD\n"); lcd_enabled = 0; return; } - video_mode = vm; - 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); @@ -743,7 +536,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 * @@ -773,7 +566,7 @@ void lcd_ctrl_init(void *lcdbase) debug("Initializing FB driver\n"); tx48_lcd_panel_setup(&da8xx_panel, p); - da8xx_video_init(&da8xx_panel, color_depth); + da8xx_video_init(&da8xx_panel, &lcd_cfg, color_depth); debug("Initializing LCD controller\n"); video_hw_init(); @@ -807,6 +600,8 @@ static void stk5v5_board_init(void) /* 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; @@ -814,9 +609,24 @@ int board_init(void) /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; - if (ctrlc()) - printf("CTRL-C detected\n"); + if (ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) { + if (prm_rstst & PRM_RSTST_WDT1_RST) + printf("WDOG RESET detected\n"); + else + printf(" 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; } @@ -857,11 +667,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; } @@ -869,18 +676,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 (had_ctrlc() || (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" : ""); 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) @@ -899,7 +717,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; } @@ -913,8 +731,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) @@ -936,6 +762,7 @@ int board_late_init(void) baseboard); ret = -EINVAL; } + exit: tx48_init_mac(); clear_ctrlc(); @@ -943,7 +770,7 @@ exit: } #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__); @@ -968,7 +795,7 @@ static struct cpsw_slave_data cpsw_slaves[] = { { .slave_reg_ofs = 0x208, .sliver_reg_ofs = 0xd80, - .phy_id = 0, + .phy_addr = 0, .phy_if = PHY_INTERFACE_MODE_RMII, }, }; @@ -992,8 +819,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, }; @@ -1001,11 +826,18 @@ static struct cpsw_platform_data cpsw_data = { 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; @@ -1059,21 +891,41 @@ static struct node_info nodes[] = { #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 = getenv("video_mode"); + 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); - video_mode = karo_fdt_set_display(video_mode, "/panel", NULL); 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 */