X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap2%2Fam33xx%2Fboard.c;h=ce58bf811f29b99b1f679698aedae4de07dd9b89;hb=c27178ba3649f539c9f1890ea147f4c5415f63b5;hp=ae86b69b9c71ff555989132826cac832bdbde95e;hpb=4f42a0d7210bd8d4d1f5e2fb73456679d74c44cd;p=oweals%2Fu-boot.git diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c index ae86b69b9c..ce58bf811f 100644 --- a/arch/arm/mach-omap2/am33xx/board.c +++ b/arch/arm/mach-omap2/am33xx/board.c @@ -1,17 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * board.c * * Common board functions for AM33XX based boards * * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include +#include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +41,14 @@ #include #include +#define AM43XX_EMIF_BASE 0x4C000000 +#define AM43XX_SDRAM_CONFIG_OFFSET 0x8 +#define AM43XX_SDRAM_TYPE_MASK 0xE0000000 +#define AM43XX_SDRAM_TYPE_SHIFT 29 +#define AM43XX_SDRAM_TYPE_DDR3 3 +#define AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET 0xDC +#define AM43XX_RDWRLVLFULL_START 0x80000000 + DECLARE_GLOBAL_DATA_PTR; int dram_init(void) @@ -94,7 +105,21 @@ U_BOOT_DEVICES(am33xx_uarts) = { # endif }; -#ifdef CONFIG_DM_GPIO +#ifdef CONFIG_DM_I2C +static const struct omap_i2c_platdata am33xx_i2c[] = { + { I2C_BASE1, 100000, OMAP_I2C_REV_V2}, + { I2C_BASE2, 100000, OMAP_I2C_REV_V2}, + { I2C_BASE3, 100000, OMAP_I2C_REV_V2}, +}; + +U_BOOT_DEVICES(am33xx_i2c) = { + { "i2c_omap", &am33xx_i2c[0] }, + { "i2c_omap", &am33xx_i2c[1] }, + { "i2c_omap", &am33xx_i2c[2] }, +}; +#endif + +#if CONFIG_IS_ENABLED(DM_GPIO) static const struct omap_gpio_platdata am33xx_gpio[] = { { 0, AM33XX_GPIO0_BASE }, { 1, AM33XX_GPIO1_BASE }, @@ -119,7 +144,7 @@ U_BOOT_DEVICES(am33xx_gpios) = { #endif #endif -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static const struct gpio_bank gpio_bank_am33xx[] = { { (void *)AM33XX_GPIO0_BASE }, { (void *)AM33XX_GPIO1_BASE }, @@ -147,10 +172,68 @@ int cpu_mmc_init(bd_t *bis) } #endif +/* + * RTC only with DDR in self-refresh mode magic value, checked against during + * boot to see if we have a valid config. This should be in sync with the value + * that will be in drivers/soc/ti/pm33xx.c. + */ +#define RTC_MAGIC_VAL 0x8cd0 + +/* Board type field bit shift for RTC only with DDR in self-refresh mode */ +#define RTC_BOARD_TYPE_SHIFT 16 + /* AM33XX has two MUSB controllers which can be host or gadget */ #if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \ (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \ - (!defined(CONFIG_DM_USB)) + (!CONFIG_IS_ENABLED(DM_USB) || !CONFIG_IS_ENABLED(OF_CONTROL)) && \ + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_MUSB_NEW_SUPPORT)) + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +#if CONFIG_IS_ENABLED(DM_USB) && !CONFIG_IS_ENABLED(OF_CONTROL) +static struct ti_musb_platdata usb0 = { + .base = (void *)USB0_OTG_BASE, + .ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl0, + .plat = { + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + }, +}; + +static struct ti_musb_platdata usb1 = { + .base = (void *)USB1_OTG_BASE, + .ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl1, + .plat = { + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + }, +}; + +U_BOOT_DEVICES(am33xx_usbs) = { +#if CONFIG_AM335X_USB0_MODE == MUSB_PERIPHERAL + { "ti-musb-peripheral", &usb0 }, +#elif CONFIG_AM335X_USB0_MODE == MUSB_HOST + { "ti-musb-host", &usb0 }, +#endif +#if CONFIG_AM335X_USB1_MODE == MUSB_PERIPHERAL + { "ti-musb-peripheral", &usb1 }, +#elif CONFIG_AM335X_USB1_MODE == MUSB_HOST + { "ti-musb-host", &usb1 }, +#endif +}; + +int arch_misc_init(void) +{ + return 0; +} +#else static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; /* USB 2.0 PHY Control */ @@ -169,13 +252,6 @@ static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr) } } -static struct musb_hdrc_config musb_config = { - .multipoint = 1, - .dyn_fifo = 1, - .num_eps = 16, - .ram_bits = 12, -}; - #ifdef CONFIG_AM335X_USB0 static void am33xx_otg0_set_phy_power(struct udevice *dev, u8 on) { @@ -226,6 +302,7 @@ int arch_misc_init(void) #endif return 0; } +#endif #else /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */ @@ -252,6 +329,48 @@ int arch_misc_init(void) #endif /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT + +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) || \ + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)) +static void rtc32k_unlock(struct davinci_rtc *rtc) +{ + /* + * Unlock the RTC's registers. For more details please see the + * RTC_SS section of the TRM. In order to unlock we need to + * write these specific values (keys) in this order. + */ + writel(RTC_KICK0R_WE, &rtc->kick0r); + writel(RTC_KICK1R_WE, &rtc->kick1r); +} +#endif + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) +/* + * Write contents of the RTC_SCRATCH1 register based on board type + * Two things are passed + * on. First 16 bits (0:15) are written with RTC_MAGIC value. Once the + * control gets to kernel, kernel reads the scratchpad register and gets to + * know that bootloader has rtc_only support. + * + * Second important thing is the board type (16:31). This is needed in the + * rtc_only boot where in we want to avoid costly i2c reads to eeprom to + * identify the board type and we go ahead and copy the board strings to + * am43xx_board_name. + */ +void update_rtc_magic(void) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + u32 magic = RTC_MAGIC_VAL; + + magic |= (rtc_only_get_board_type() << RTC_BOARD_TYPE_SHIFT); + + rtc32k_unlock(rtc); + + /* write magic */ + writel(magic, &rtc->scratch1); +} +#endif + /* * In the case of non-SPL based booting we'll want to call these * functions a tiny bit later as it will require gd to be set and cleared @@ -259,9 +378,11 @@ int arch_misc_init(void) */ int board_early_init_f(void) { - prcm_init(); set_mux_conf_regs(); - + prcm_init(); +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) + update_rtc_magic(); +#endif return 0; } @@ -278,13 +399,7 @@ static void rtc32k_enable(void) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; - /* - * Unlock the RTC's registers. For more details please see the - * RTC_SS section of the TRM. In order to unlock we need to - * write these specific values (keys) in this order. - */ - writel(RTC_KICK0R_WE, &rtc->kick0r); - writel(RTC_KICK1R_WE, &rtc->kick1r); + rtc32k_unlock(rtc); /* Enable the RTC 32K OSC by setting bits 3 and 6. */ writel((1 << 3) | (1 << 6), &rtc->osc); @@ -321,8 +436,85 @@ static void watchdog_disable(void) ; } +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) +/* + * Check if we are executing rtc-only + DDR mode, and resume from it if needed + */ +static void rtc_only(void) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + struct prm_device_inst *prm_device = + (struct prm_device_inst *)PRM_DEVICE_INST; + + u32 scratch1, sdrc; + void (*resume_func)(void); + + scratch1 = readl(&rtc->scratch1); + + /* + * Check RTC scratch against RTC_MAGIC_VAL, RTC_MAGIC_VAL is only + * written to this register when we want to wake up from RTC only + * with DDR in self-refresh mode. Contents of the RTC_SCRATCH1: + * bits 0-15: RTC_MAGIC_VAL + * bits 16-31: board type (needed for sdram_init) + */ + if ((scratch1 & 0xffff) != RTC_MAGIC_VAL) + return; + + rtc32k_unlock(rtc); + + /* Clear RTC magic */ + writel(0, &rtc->scratch1); + + /* + * Update board type based on value stored on RTC_SCRATCH1, this + * is done so that we don't need to read the board type from eeprom + * over i2c bus which is expensive + */ + rtc_only_update_board_type(scratch1 >> RTC_BOARD_TYPE_SHIFT); + + /* + * Enable EMIF_DEVOFF in PRCM_PRM_EMIF_CTRL to indicate to EMIF we + * are resuming from self-refresh. This avoids an unnecessary re-init + * of the DDR. The re-init takes time and we would need to wait for + * it to complete before accessing DDR to avoid L3 NOC errors. + */ + writel(EMIF_CTRL_DEVOFF, &prm_device->emif_ctrl); + + rtc_only_prcm_init(); + sdram_init(); + + /* Check EMIF4D_SDRAM_CONFIG[31:29] SDRAM_TYPE */ + /* Only perform leveling if SDRAM_TYPE = 3 (DDR3) */ + sdrc = readl(AM43XX_EMIF_BASE + AM43XX_SDRAM_CONFIG_OFFSET); + + sdrc &= AM43XX_SDRAM_TYPE_MASK; + sdrc >>= AM43XX_SDRAM_TYPE_SHIFT; + + if (sdrc == AM43XX_SDRAM_TYPE_DDR3) { + writel(AM43XX_RDWRLVLFULL_START, + AM43XX_EMIF_BASE + + AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET); + mdelay(1); + +am43xx_wait: + sdrc = readl(AM43XX_EMIF_BASE + + AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET); + if (sdrc == AM43XX_RDWRLVLFULL_START) + goto am43xx_wait; + } + + resume_func = (void *)readl(&rtc->scratch0); + if (resume_func) + resume_func(); +} +#endif + void s_init(void) { +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) + rtc_only(); +#endif } void early_system_init(void) @@ -350,9 +542,15 @@ void early_system_init(void) #ifdef CONFIG_DEBUG_UART_OMAP debug_uart_init(); #endif + +#ifdef CONFIG_SPL_BUILD + spl_early_init(); +#endif + #ifdef CONFIG_TI_I2C_BOARD_DETECT do_board_detect(); #endif + #if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) /* Enable RTC32K clock */ rtc32k_enable();