+// 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 <common.h>
#include <dm.h>
+#include <debug_uart.h>
#include <errno.h>
#include <ns16550.h>
#include <spl.h>
#include <asm/arch/ddr_defs.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/i2c.h>
#include <asm/arch/mem.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <asm/emif.h>
#include <asm/gpio.h>
+#include <asm/omap_common.h>
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
DECLARE_GLOBAL_DATA_PTR;
+int dram_init(void)
+{
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ sdram_init();
+#endif
+
+ /* dram_init must store complete ramsize in gd->ram_size */
+ gd->ram_size = get_ram_size(
+ (void *)CONFIG_SYS_SDRAM_BASE,
+ CONFIG_MAX_RAM_BANK_SIZE);
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+
+ return 0;
+}
+
#if !CONFIG_IS_ENABLED(OF_CONTROL)
static const struct ns16550_platdata am33xx_serial[] = {
- { .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+ { .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# ifdef CONFIG_SYS_NS16550_COM2
- { .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+ { .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# ifdef CONFIG_SYS_NS16550_COM3
- { .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
- { .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
- { .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
- { .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
+ { .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
+ { .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
+ { .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
+ { .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2,
+ .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# endif
# endif
};
# endif
};
+#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
+
#ifdef CONFIG_DM_GPIO
static const struct omap_gpio_platdata am33xx_gpio[] = {
{ 0, AM33XX_GPIO0_BASE },
const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
#endif
-#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_MMC_OMAP_HS)
int cpu_mmc_init(bd_t *bis)
{
int ret;
}
#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)) && \
};
#ifdef CONFIG_AM335X_USB0
-static void am33xx_otg0_set_phy_power(u8 on)
+static void am33xx_otg0_set_phy_power(struct udevice *dev, u8 on)
{
am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
}
#endif
#ifdef CONFIG_AM335X_USB1
-static void am33xx_otg1_set_phy_power(u8 on)
+static void am33xx_otg1_set_phy_power(struct udevice *dev, u8 on)
{
am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
}
.board_data = &otg1_board_data,
};
#endif
-#endif
int arch_misc_init(void)
{
-#ifndef CONFIG_DM_USB
#ifdef CONFIG_AM335X_USB0
musb_register(&otg0_plat, &otg0_board_data,
(void *)USB0_OTG_BASE);
musb_register(&otg1_plat, &otg1_board_data,
(void *)USB1_OTG_BASE);
#endif
-#else
+ return 0;
+}
+
+#else /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */
+
+int arch_misc_init(void)
+{
struct udevice *dev;
int ret;
ret = uclass_first_device(UCLASS_MISC, &dev);
if (ret || !dev)
return ret;
+
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_USB_ETHER)
+ ret = usb_ether_init();
+ if (ret) {
+ pr_err("USB ether init failed\n");
+ return ret;
+ }
#endif
+
return 0;
}
+#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
{
prcm_init();
set_mux_conf_regs();
-
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
+ update_rtc_magic();
+#endif
return 0;
}
*/
__weak void am33xx_spl_board_init(void)
{
- do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
- do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
}
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
{
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);
;
}
+#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;
+ 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();
+
+ /* Disable EMIF_DEVOFF for normal operation and to exit self-refresh */
+ writel(0, &prm_device->emif_ctrl);
+
+ 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)
set_uart_mux_conf();
setup_early_clocks();
uart_soft_reset();
+#ifdef CONFIG_SPL_BUILD
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+ save_omap_boot_params();
+#endif
+#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();
#ifdef CONFIG_SPL_BUILD
void board_init_f(ulong dummy)
{
+ hw_data_init();
early_system_init();
board_early_init_f();
sdram_init();
+ /* dram_init must store complete ramsize in gd->ram_size */
+ gd->ram_size = get_ram_size(
+ (void *)CONFIG_SYS_SDRAM_BASE,
+ CONFIG_MAX_RAM_BANK_SIZE);
}
#endif
int arch_cpu_init_dm(void)
{
+ hw_data_init();
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
early_system_init();
#endif