diff options
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/armv7/am33xx')
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/Makefile | 21 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/board.c | 251 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/clock.c | 177 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c | 161 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c | 112 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c | 404 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c | 445 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/config.mk | 11 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/ddr.c | 266 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/emif4.c | 132 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/mem.c | 98 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/mux.c | 33 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c | 178 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds | 55 | 
14 files changed, 2344 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/Makefile b/roms/u-boot/arch/arm/cpu/armv7/am33xx/Makefile new file mode 100644 index 00000000..5566310d --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-$(CONFIG_AM33XX)	+= clock_am33xx.o +obj-$(CONFIG_TI814X)	+= clock_ti814x.o +obj-$(CONFIG_AM43XX)	+= clock_am43xx.o + +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX),) +obj-y	+= clock.o +endif + +obj-$(CONFIG_TI816X)	+= clock_ti816x.o +obj-y	+= sys_info.o +obj-y	+= mem.o +obj-y	+= ddr.o +obj-y	+= emif4.o +obj-y	+= board.o +obj-y	+= mux.o diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/board.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/board.c new file mode 100644 index 00000000..28c16f8d --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/board.c @@ -0,0 +1,251 @@ +/* + * 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 <errno.h> +#include <spl.h> +#include <asm/arch/cpu.h> +#include <asm/arch/hardware.h> +#include <asm/arch/omap.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.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 <i2c.h> +#include <miiphy.h> +#include <cpsw.h> +#include <asm/errno.h> +#include <linux/compiler.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/musb.h> +#include <asm/omap_musb.h> +#include <asm/davinci_rtc.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct gpio_bank gpio_bank_am33xx[] = { +	{ (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX }, +	{ (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX }, +	{ (void *)AM33XX_GPIO2_BASE, METHOD_GPIO_24XX }, +	{ (void *)AM33XX_GPIO3_BASE, METHOD_GPIO_24XX }, +#ifdef CONFIG_AM43XX +	{ (void *)AM33XX_GPIO4_BASE, METHOD_GPIO_24XX }, +	{ (void *)AM33XX_GPIO5_BASE, METHOD_GPIO_24XX }, +#endif +}; + +const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx; + +#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) +int cpu_mmc_init(bd_t *bis) +{ +	int ret; + +	ret = omap_mmc_init(0, 0, 0, -1, -1); +	if (ret) +		return ret; + +	return omap_mmc_init(1, 0, 0, -1, -1); +} +#endif + +/* AM33XX has two MUSB controllers which can be host or gadget */ +#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \ +	(defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; + +/* USB 2.0 PHY Control */ +#define CM_PHY_PWRDN			(1 << 0) +#define CM_PHY_OTG_PWRDN		(1 << 1) +#define OTGVDET_EN			(1 << 19) +#define OTGSESSENDEN			(1 << 20) + +static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr) +{ +	if (on) { +		clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, +				OTGVDET_EN | OTGSESSENDEN); +	} else { +		clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); +	} +} + +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(u8 on) +{ +	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0); +} + +struct omap_musb_board_data otg0_board_data = { +	.set_phy_power = am33xx_otg0_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg0_plat = { +	.mode           = CONFIG_AM335X_USB0_MODE, +	.config         = &musb_config, +	.power          = 50, +	.platform_ops	= &musb_dsps_ops, +	.board_data	= &otg0_board_data, +}; +#endif + +#ifdef CONFIG_AM335X_USB1 +static void am33xx_otg1_set_phy_power(u8 on) +{ +	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1); +} + +struct omap_musb_board_data otg1_board_data = { +	.set_phy_power = am33xx_otg1_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg1_plat = { +	.mode           = CONFIG_AM335X_USB1_MODE, +	.config         = &musb_config, +	.power          = 50, +	.platform_ops	= &musb_dsps_ops, +	.board_data	= &otg1_board_data, +}; +#endif +#endif + +int arch_misc_init(void) +{ +#ifdef CONFIG_AM335X_USB0 +	musb_register(&otg0_plat, &otg0_board_data, +		(void *)USB0_OTG_BASE); +#endif +#ifdef CONFIG_AM335X_USB1 +	musb_register(&otg1_plat, &otg1_board_data, +		(void *)USB1_OTG_BASE); +#endif +	return 0; +} + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +/* + * This function is the place to do per-board things such as ramp up the + * MPU clock frequency. + */ +__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) +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); + +	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ +	writel((1 << 3) | (1 << 6), &rtc->osc); +} +#endif + +static void uart_soft_reset(void) +{ +	struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; +	u32 regval; + +	regval = readl(&uart_base->uartsyscfg); +	regval |= UART_RESET; +	writel(regval, &uart_base->uartsyscfg); +	while ((readl(&uart_base->uartsyssts) & +		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) +		; + +	/* Disable smart idle */ +	regval = readl(&uart_base->uartsyscfg); +	regval |= UART_SMART_IDLE_EN; +	writel(regval, &uart_base->uartsyscfg); +} + +static void watchdog_disable(void) +{ +	struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + +	writel(0xAAAA, &wdtimer->wdtwspr); +	while (readl(&wdtimer->wdtwwps) != 0x0) +		; +	writel(0x5555, &wdtimer->wdtwspr); +	while (readl(&wdtimer->wdtwwps) != 0x0) +		; +} + +void s_init(void) +{ +	/* +	 * The ROM will only have set up sufficient pinmux to allow for the +	 * first 4KiB NOR to be read, we must finish doing what we know of +	 * the NOR mux in this space in order to continue. +	 */ +#ifdef CONFIG_NOR_BOOT +	enable_norboot_pin_mux(); +#endif +	/* +	 * Save the boot parameters passed from romcode. +	 * We cannot delay the saving further than this, +	 * to prevent overwrites. +	 */ +#ifdef CONFIG_SPL_BUILD +	save_omap_boot_params(); +#endif +	watchdog_disable(); +	timer_init(); +	set_uart_mux_conf(); +	setup_clocks_for_console(); +	uart_soft_reset(); +#ifdef CONFIG_NOR_BOOT +	gd->baudrate = CONFIG_BAUDRATE; +	serial_init(); +	gd->have_console = 1; +#elif defined(CONFIG_SPL_BUILD) +	gd = &gdata; +	preloader_console_init(); +#endif +	prcm_init(); +	set_mux_conf_regs(); +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) +	/* Enable RTC32K clock */ +	rtc32k_enable(); +#endif +	sdram_init(); +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ +	/* Enable D-cache. I-cache is already enabled in start.S */ +	dcache_enable(); +} +#endif /* !CONFIG_SYS_DCACHE_OFF */ diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock.c new file mode 100644 index 00000000..0672798f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock.c @@ -0,0 +1,177 @@ +/* + * clock.c + * + * Clock initialization for AM33XX boards. + * Derived from OMAP4 boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +static void setup_post_dividers(const struct dpll_regs *dpll_regs, +			 const struct dpll_params *params) +{ +	/* Setup post-dividers */ +	if (params->m2 >= 0) +		writel(params->m2, dpll_regs->cm_div_m2_dpll); +	if (params->m3 >= 0) +		writel(params->m3, dpll_regs->cm_div_m3_dpll); +	if (params->m4 >= 0) +		writel(params->m4, dpll_regs->cm_div_m4_dpll); +	if (params->m5 >= 0) +		writel(params->m5, dpll_regs->cm_div_m5_dpll); +	if (params->m6 >= 0) +		writel(params->m6, dpll_regs->cm_div_m6_dpll); +} + +static inline void do_lock_dpll(const struct dpll_regs *dpll_regs) +{ +	clrsetbits_le32(dpll_regs->cm_clkmode_dpll, +			CM_CLKMODE_DPLL_DPLL_EN_MASK, +			DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_lock(const struct dpll_regs *dpll_regs) +{ +	if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK, +			   (void *)dpll_regs->cm_idlest_dpll, LDELAY)) { +		printf("DPLL locking failed for 0x%x\n", +		       dpll_regs->cm_clkmode_dpll); +		hang(); +	} +} + +static inline void do_bypass_dpll(const struct dpll_regs *dpll_regs) +{ +	clrsetbits_le32(dpll_regs->cm_clkmode_dpll, +			CM_CLKMODE_DPLL_DPLL_EN_MASK, +			DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_bypass(const struct dpll_regs *dpll_regs) +{ +	if (!wait_on_value(ST_DPLL_CLK_MASK, 0, +			   (void *)dpll_regs->cm_idlest_dpll, LDELAY)) { +		printf("Bypassing DPLL failed 0x%x\n", +		       dpll_regs->cm_clkmode_dpll); +	} +} + +static void bypass_dpll(const struct dpll_regs *dpll_regs) +{ +	do_bypass_dpll(dpll_regs); +	wait_for_bypass(dpll_regs); +} + +void do_setup_dpll(const struct dpll_regs *dpll_regs, +		   const struct dpll_params *params) +{ +	u32 temp; + +	if (!params) +		return; + +	temp = readl(dpll_regs->cm_clksel_dpll); + +	bypass_dpll(dpll_regs); + +	/* Set M & N */ +	temp &= ~CM_CLKSEL_DPLL_M_MASK; +	temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK; + +	temp &= ~CM_CLKSEL_DPLL_N_MASK; +	temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK; + +	writel(temp, dpll_regs->cm_clksel_dpll); + +	setup_post_dividers(dpll_regs, params); + +	/* Wait till the DPLL locks */ +	do_lock_dpll(dpll_regs); +	wait_for_lock(dpll_regs); +} + +static void setup_dplls(void) +{ +	const struct dpll_params *params; + +	params = get_dpll_core_params(); +	do_setup_dpll(&dpll_core_regs, params); + +	params = get_dpll_mpu_params(); +	do_setup_dpll(&dpll_mpu_regs, params); + +	params = get_dpll_per_params(); +	do_setup_dpll(&dpll_per_regs, params); +	writel(0x300, &cmwkup->clkdcoldodpllper); + +	params = get_dpll_ddr_params(); +	do_setup_dpll(&dpll_ddr_regs, params); +} + +static inline void wait_for_clk_enable(u32 *clkctrl_addr) +{ +	u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; +	u32 bound = LDELAY; + +	while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || +		(idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { +		clkctrl = readl(clkctrl_addr); +		idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> +			 MODULE_CLKCTRL_IDLEST_SHIFT; +		if (--bound == 0) { +			printf("Clock enable failed for 0x%p idlest 0x%x\n", +			       clkctrl_addr, clkctrl); +			return; +		} +	} +} + +static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode, +				       u32 wait_for_enable) +{ +	clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK, +			enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT); +	debug("Enable clock module - %p\n", clkctrl_addr); +	if (wait_for_enable) +		wait_for_clk_enable(clkctrl_addr); +} + +static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode) +{ +	clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK, +			enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT); +	debug("Enable clock domain - %p\n", clkctrl_reg); +} + +void do_enable_clocks(u32 *const *clk_domains, +		      u32 *const *clk_modules_explicit_en, u8 wait_for_enable) +{ +	u32 i, max = 100; + +	/* Put the clock domains in SW_WKUP mode */ +	for (i = 0; (i < max) && clk_domains[i]; i++) { +		enable_clock_domain(clk_domains[i], +				    CD_CLKCTRL_CLKTRCTRL_SW_WKUP); +	} + +	/* Clock modules that need to be put in SW_EXPLICIT_EN mode */ +	for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) { +		enable_clock_module(clk_modules_explicit_en[i], +				    MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, +				    wait_for_enable); +	}; +} + +void prcm_init() +{ +	enable_basic_clocks(); +	setup_dplls(); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c new file mode 100644 index 00000000..92142c89 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c @@ -0,0 +1,161 @@ +/* + * clock_am33xx.c + * + * clocks for AM33XX based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +#define OSC	(V_OSCK/1000000) + +struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; +struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; +struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; +struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC; + +const struct dpll_regs dpll_mpu_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x88, +	.cm_idlest_dpll		= CM_WKUP + 0x20, +	.cm_clksel_dpll		= CM_WKUP + 0x2C, +	.cm_div_m2_dpll		= CM_WKUP + 0xA8, +}; + +const struct dpll_regs dpll_core_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x90, +	.cm_idlest_dpll		= CM_WKUP + 0x5C, +	.cm_clksel_dpll		= CM_WKUP + 0x68, +	.cm_div_m4_dpll		= CM_WKUP + 0x80, +	.cm_div_m5_dpll		= CM_WKUP + 0x84, +	.cm_div_m6_dpll		= CM_WKUP + 0xD8, +}; + +const struct dpll_regs dpll_per_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x8C, +	.cm_idlest_dpll		= CM_WKUP + 0x70, +	.cm_clksel_dpll		= CM_WKUP + 0x9C, +	.cm_div_m2_dpll		= CM_WKUP + 0xAC, +}; + +const struct dpll_regs dpll_ddr_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x94, +	.cm_idlest_dpll		= CM_WKUP + 0x34, +	.cm_clksel_dpll		= CM_WKUP + 0x40, +	.cm_div_m2_dpll		= CM_WKUP + 0xA0, +}; + +struct dpll_params dpll_mpu_opp100 = { +		CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1}; +const struct dpll_params dpll_core_opp100 = { +		1000, OSC-1, -1, -1, 10, 8, 4}; +const struct dpll_params dpll_mpu = { +		MPUPLL_M_300, OSC-1, 1, -1, -1, -1, -1}; +const struct dpll_params dpll_core = { +		50, OSC-1, -1, -1, 1, 1, 1}; +const struct dpll_params dpll_per = { +		960, OSC-1, 5, -1, -1, -1, -1}; + +const struct dpll_params *get_dpll_mpu_params(void) +{ +	return &dpll_mpu; +} + +const struct dpll_params *get_dpll_core_params(void) +{ +	return &dpll_core; +} + +const struct dpll_params *get_dpll_per_params(void) +{ +	return &dpll_per; +} + +void setup_clocks_for_console(void) +{ +	clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, +			CD_CLKCTRL_CLKTRCTRL_SW_WKUP << +			CD_CLKCTRL_CLKTRCTRL_SHIFT); + +	clrsetbits_le32(&cmper->l4hsclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, +			CD_CLKCTRL_CLKTRCTRL_SW_WKUP << +			CD_CLKCTRL_CLKTRCTRL_SHIFT); + +	clrsetbits_le32(&cmwkup->wkup_uart0ctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +	clrsetbits_le32(&cmper->uart1clkctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +	clrsetbits_le32(&cmper->uart2clkctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +	clrsetbits_le32(&cmper->uart3clkctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +	clrsetbits_le32(&cmper->uart4clkctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +	clrsetbits_le32(&cmper->uart5clkctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +} + +void enable_basic_clocks(void) +{ +	u32 *const clk_domains[] = { +		&cmper->l3clkstctrl, +		&cmper->l4fwclkstctrl, +		&cmper->l3sclkstctrl, +		&cmper->l4lsclkstctrl, +		&cmwkup->wkclkstctrl, +		&cmper->emiffwclkctrl, +		&cmrtc->clkstctrl, +		0 +	}; + +	u32 *const clk_modules_explicit_en[] = { +		&cmper->l3clkctrl, +		&cmper->l4lsclkctrl, +		&cmper->l4fwclkctrl, +		&cmwkup->wkl4wkclkctrl, +		&cmper->l3instrclkctrl, +		&cmper->l4hsclkctrl, +		&cmwkup->wkgpio0clkctrl, +		&cmwkup->wkctrlclkctrl, +		&cmper->timer2clkctrl, +		&cmper->gpmcclkctrl, +		&cmper->elmclkctrl, +		&cmper->mmc0clkctrl, +		&cmper->mmc1clkctrl, +		&cmwkup->wkup_i2c0ctrl, +		&cmper->gpio1clkctrl, +		&cmper->gpio2clkctrl, +		&cmper->gpio3clkctrl, +		&cmper->i2c1clkctrl, +		&cmper->cpgmac0clkctrl, +		&cmper->spi0clkctrl, +		&cmrtc->rtcclkctrl, +		&cmper->usb0clkctrl, +		&cmper->emiffwclkctrl, +		&cmper->emifclkctrl, +		0 +	}; + +	do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); + +	/* Select the Master osc 24 MHZ as Timer2 clock source */ +	writel(0x1, &cmdpll->clktimer2clk); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c new file mode 100644 index 00000000..d0bc2340 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c @@ -0,0 +1,112 @@ +/* + * clock_am43xx.c + * + * clocks for AM43XX based boards + * Derived from AM33XX based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; +struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; +struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; + +const struct dpll_regs dpll_mpu_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x560, +	.cm_idlest_dpll		= CM_WKUP + 0x564, +	.cm_clksel_dpll		= CM_WKUP + 0x56c, +	.cm_div_m2_dpll		= CM_WKUP + 0x570, +}; + +const struct dpll_regs dpll_core_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x520, +	.cm_idlest_dpll		= CM_WKUP + 0x524, +	.cm_clksel_dpll		= CM_WKUP + 0x52C, +	.cm_div_m4_dpll		= CM_WKUP + 0x538, +	.cm_div_m5_dpll		= CM_WKUP + 0x53C, +	.cm_div_m6_dpll		= CM_WKUP + 0x540, +}; + +const struct dpll_regs dpll_per_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x5E0, +	.cm_idlest_dpll		= CM_WKUP + 0x5E4, +	.cm_clksel_dpll		= CM_WKUP + 0x5EC, +	.cm_div_m2_dpll		= CM_WKUP + 0x5F0, +}; + +const struct dpll_regs dpll_ddr_regs = { +	.cm_clkmode_dpll	= CM_WKUP + 0x5A0, +	.cm_idlest_dpll		= CM_WKUP + 0x5A4, +	.cm_clksel_dpll		= CM_WKUP + 0x5AC, +	.cm_div_m2_dpll		= CM_WKUP + 0x5B0, +	.cm_div_m4_dpll		= CM_WKUP + 0x5B8, +}; + +void setup_clocks_for_console(void) +{ +	/* Do not add any spl_debug prints in this function */ +	clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, +			CD_CLKCTRL_CLKTRCTRL_SW_WKUP << +			CD_CLKCTRL_CLKTRCTRL_SHIFT); + +	/* Enable UART0 */ +	clrsetbits_le32(&cmwkup->wkup_uart0ctrl, +			MODULE_CLKCTRL_MODULEMODE_MASK, +			MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << +			MODULE_CLKCTRL_MODULEMODE_SHIFT); +} + +void enable_basic_clocks(void) +{ +	u32 *const clk_domains[] = { +		&cmper->l3clkstctrl, +		&cmper->l3sclkstctrl, +		&cmper->l4lsclkstctrl, +		&cmwkup->wkclkstctrl, +		&cmper->emifclkstctrl, +		0 +	}; + +	u32 *const clk_modules_explicit_en[] = { +		&cmper->l3clkctrl, +		&cmper->l4lsclkctrl, +		&cmper->l4fwclkctrl, +		&cmwkup->wkl4wkclkctrl, +		&cmper->l3instrclkctrl, +		&cmper->l4hsclkctrl, +		&cmwkup->wkgpio0clkctrl, +		&cmwkup->wkctrlclkctrl, +		&cmper->timer2clkctrl, +		&cmper->gpmcclkctrl, +		&cmper->elmclkctrl, +		&cmper->mmc0clkctrl, +		&cmper->mmc1clkctrl, +		&cmwkup->wkup_i2c0ctrl, +		&cmper->gpio1clkctrl, +		&cmper->gpio2clkctrl, +		&cmper->gpio3clkctrl, +		&cmper->gpio4clkctrl, +		&cmper->gpio5clkctrl, +		&cmper->i2c1clkctrl, +		&cmper->cpgmac0clkctrl, +		&cmper->emiffwclkctrl, +		&cmper->emifclkctrl, +		&cmper->otfaemifclkctrl, +		&cmper->qspiclkctrl, +		0 +	}; + +	do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); + +	/* Select the Master osc clk as Timer2 clock source */ +	writel(0x1, &cmdpll->clktimer2clk); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c new file mode 100644 index 00000000..9b5a47b0 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c @@ -0,0 +1,404 @@ +/* + * clock_ti814x.c + * + * Clocks for TI814X based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* PRCM */ +#define PRCM_MOD_EN		0x2 + +/* CLK_SRC */ +#define OSC_SRC0		0 +#define OSC_SRC1		1 + +#define L3_OSC_SRC		OSC_SRC0 + +#define OSC_0_FREQ		20 + +#define DCO_HS2_MIN		500 +#define DCO_HS2_MAX		1000 +#define DCO_HS1_MIN		1000 +#define DCO_HS1_MAX		2000 + +#define SELFREQDCO_HS2		0x00000801 +#define SELFREQDCO_HS1		0x00001001 + +#define MPU_N			0x1 +#define MPU_M			0x3C +#define MPU_M2			1 +#define MPU_CLKCTRL		0x1 + +#define L3_N			19 +#define L3_M			880 +#define L3_M2			4 +#define L3_CLKCTRL		0x801 + +#define DDR_N			19 +#define DDR_M			666 +#define DDR_M2			2 +#define DDR_CLKCTRL		0x801 + +/* ADPLLJ register values */ +#define ADPLLJ_CLKCTRL_HS2	0x00000801 /* HS2 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_HS1	0x00001001 /* HS1 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_CLKDCOLDOEN	(1 << 29) +#define ADPLLJ_CLKCTRL_IDLE		(1 << 23) +#define ADPLLJ_CLKCTRL_CLKOUTEN		(1 << 20) +#define ADPLLJ_CLKCTRL_CLKOUTLDOEN	(1 << 19) +#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ	(1 << 17) +#define ADPLLJ_CLKCTRL_LPMODE		(1 << 12) +#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN	(1 << 11) +#define ADPLLJ_CLKCTRL_REGM4XEN		(1 << 10) +#define ADPLLJ_CLKCTRL_TINITZ		(1 << 0) +#define ADPLLJ_CLKCTRL_CLKDCO		(ADPLLJ_CLKCTRL_CLKDCOLDOEN | \ +					 ADPLLJ_CLKCTRL_CLKOUTEN | \ +					 ADPLLJ_CLKCTRL_CLKOUTLDOEN | \ +					 ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ) + +#define ADPLLJ_STATUS_PHASELOCK		(1 << 10) +#define ADPLLJ_STATUS_FREQLOCK		(1 << 9) +#define ADPLLJ_STATUS_PHSFRQLOCK	(ADPLLJ_STATUS_PHASELOCK | \ +					 ADPLLJ_STATUS_FREQLOCK) +#define ADPLLJ_STATUS_BYPASSACK		(1 << 8) +#define ADPLLJ_STATUS_BYPASS		(1 << 0) +#define ADPLLJ_STATUS_BYPASSANDACK	(ADPLLJ_STATUS_BYPASSACK | \ +					 ADPLLJ_STATUS_BYPASS) + +#define ADPLLJ_TENABLE_ENB		(1 << 0) +#define ADPLLJ_TENABLEDIV_ENB		(1 << 0) + +#define ADPLLJ_M2NDIV_M2SHIFT		16 + +#define MPU_PLL_BASE			(PLL_SUBSYS_BASE + 0x048) +#define L3_PLL_BASE			(PLL_SUBSYS_BASE + 0x110) +#define DDR_PLL_BASE			(PLL_SUBSYS_BASE + 0x290) + +struct ad_pll { +	unsigned int pwrctrl; +	unsigned int clkctrl; +	unsigned int tenable; +	unsigned int tenablediv; +	unsigned int m2ndiv; +	unsigned int mn2div; +	unsigned int fracdiv; +	unsigned int bwctrl; +	unsigned int fracctrl; +	unsigned int status; +	unsigned int m3div; +	unsigned int rampctrl; +}; + +#define OSC_SRC_CTRL			(PLL_SUBSYS_BASE + 0x2C0) + +#define ENET_CLKCTRL_CMPL		0x30000 + +#define SATA_PLL_BASE			(CTRL_BASE + 0x0720) + +struct sata_pll { +	unsigned int pllcfg0; +	unsigned int pllcfg1; +	unsigned int pllcfg2; +	unsigned int pllcfg3; +	unsigned int pllcfg4; +	unsigned int pllstatus; +	unsigned int rxstatus; +	unsigned int txstatus; +	unsigned int testcfg; +}; + +#define SEL_IN_FREQ		(0x1 << 31) +#define DIGCLRZ			(0x1 << 30) +#define ENDIGLDO		(0x1 << 4) +#define APLL_CP_CURR		(0x1 << 3) +#define ENBGSC_REF		(0x1 << 2) +#define ENPLLLDO		(0x1 << 1) +#define ENPLL			(0x1 << 0) + +#define SATA_PLLCFG0_1 (SEL_IN_FREQ | ENBGSC_REF) +#define SATA_PLLCFG0_2 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF) +#define SATA_PLLCFG0_3 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF | ENPLLLDO) +#define SATA_PLLCFG0_4 (SEL_IN_FREQ | DIGCLRZ | ENDIGLDO | ENBGSC_REF | \ +			ENPLLLDO | ENPLL) + +#define PLL_LOCK		(0x1 << 0) + +#define ENSATAMODE		(0x1 << 31) +#define PLLREFSEL		(0x1 << 30) +#define MDIVINT			(0x4b << 18) +#define EN_CLKAUX		(0x1 << 5) +#define EN_CLK125M		(0x1 << 4) +#define EN_CLK100M		(0x1 << 3) +#define EN_CLK50M		(0x1 << 2) + +#define SATA_PLLCFG1 (ENSATAMODE |	\ +		      PLLREFSEL |	\ +		      MDIVINT |		\ +		      EN_CLKAUX |	\ +		      EN_CLK125M |	\ +		      EN_CLK100M |	\ +		      EN_CLK50M) + +#define DIGLDO_EN_CAPLESSMODE	(0x1 << 22) +#define PLLDO_EN_LDO_STABLE	(0x1 << 11) +#define PLLDO_EN_BUF_CUR	(0x1 << 7) +#define PLLDO_EN_LP		(0x1 << 6) +#define PLLDO_CTRL_TRIM_1_4V	(0x10 << 1) + +#define SATA_PLLCFG3 (DIGLDO_EN_CAPLESSMODE |	\ +		      PLLDO_EN_LDO_STABLE |	\ +		      PLLDO_EN_BUF_CUR |	\ +		      PLLDO_EN_LP |		\ +		      PLLDO_CTRL_TRIM_1_4V) + +const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; +const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; +const struct sata_pll *spll = (struct sata_pll *)SATA_PLL_BASE; + +/* + * Enable the peripheral clock for required peripherals + */ +static void enable_per_clocks(void) +{ +	/* HSMMC1 */ +	writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl); +	while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN) +		; + +	/* Ethernet */ +	writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl); +	writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl); +	while ((readl(&cmalwon->ethernet0clkctrl) & ENET_CLKCTRL_CMPL) != 0) +		; +	writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl); +	while ((readl(&cmalwon->ethernet1clkctrl) & ENET_CLKCTRL_CMPL) != 0) +		; + +	/* RTC clocks */ +	writel(PRCM_MOD_EN, &cmalwon->rtcclkstctrl); +	writel(PRCM_MOD_EN, &cmalwon->rtcclkctrl); +	while (readl(&cmalwon->rtcclkctrl) != PRCM_MOD_EN) +		; +} + +/* + * select the HS1 or HS2 for DCO Freq + * return : CLKCTRL + */ +static u32 pll_dco_freq_sel(u32 clkout_dco) +{ +	if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX) +		return SELFREQDCO_HS2; +	else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX) +		return SELFREQDCO_HS1; +	else +		return -1; +} + +/* + * select the sigma delta config + * return: sigma delta val + */ +static u32 pll_sigma_delta_val(u32 clkout_dco) +{ +	u32 sig_val = 0; + +	sig_val = (clkout_dco + 225) / 250; +	sig_val = sig_val << 24; + +	return sig_val; +} + +/* + * configure individual ADPLLJ + */ +static void pll_config(u32 base, u32 n, u32 m, u32 m2, +		       u32 clkctrl_val, int adpllj) +{ +	const struct ad_pll *adpll = (struct ad_pll *)base; +	u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0; +	u32 sig_val = 0, hs_mod = 0; + +	m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n; +	mn2val = m; + +	/* calculate clkout_dco */ +	clkout_dco = ((OSC_0_FREQ / (n+1)) * m); + +	/* sigma delta & Hs mode selection skip for ADPLLS*/ +	if (adpllj) { +		sig_val = pll_sigma_delta_val(clkout_dco); +		hs_mod = pll_dco_freq_sel(clkout_dco); +	} + +	/* by-pass pll */ +	read_clkctrl = readl(&adpll->clkctrl); +	writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl); +	while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK) +		!= ADPLLJ_STATUS_BYPASSANDACK) +		; + +	/* clear TINITZ */ +	read_clkctrl = readl(&adpll->clkctrl); +	writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + +	/* +	 * ref_clk = 20/(n + 1); +	 * clkout_dco = ref_clk * m; +	 * clk_out = clkout_dco/m2; +	*/ +	read_clkctrl = readl(&adpll->clkctrl) & +			     ~(ADPLLJ_CLKCTRL_LPMODE | +			     ADPLLJ_CLKCTRL_DRIFTGUARDIAN | +			     ADPLLJ_CLKCTRL_REGM4XEN); +	writel(m2nval, &adpll->m2ndiv); +	writel(mn2val, &adpll->mn2div); + +	/* Skip for modena(ADPLLS) */ +	if (adpllj) { +		writel(sig_val, &adpll->fracdiv); +		writel((read_clkctrl | hs_mod), &adpll->clkctrl); +	} + +	/* Load M2, N2 dividers of ADPLL */ +	writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); +	writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); + +	/* Load M, N dividers of ADPLL */ +	writel(ADPLLJ_TENABLE_ENB, &adpll->tenable); +	writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable); + +	/* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */ +	read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO; +	if (adpllj) +		writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO), +						&adpll->clkctrl); + +	/* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */ +	read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE; +	writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + +	/* Wait for phase and freq lock */ +	while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) != +	       ADPLLJ_STATUS_PHSFRQLOCK) +		; +} + +static void unlock_pll_control_mmr(void) +{ +	/* TRM 2.10.1.4 and 3.2.7-3.2.11 */ +	writel(0x1EDA4C3D, 0x481C5040); +	writel(0x2FF1AC2B, 0x48140060); +	writel(0xF757FDC0, 0x48140064); +	writel(0xE2BC3A6D, 0x48140068); +	writel(0x1EBF131D, 0x4814006c); +	writel(0x6F361E05, 0x48140070); +} + +static void mpu_pll_config(void) +{ +	pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0); +} + +static void l3_pll_config(void) +{ +	u32 l3_osc_src, rd_osc_src = 0; + +	l3_osc_src = L3_OSC_SRC; +	rd_osc_src = readl(OSC_SRC_CTRL); + +	if (OSC_SRC0 == l3_osc_src) +		writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL); +	else +		writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL); + +	pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1); +} + +void ddr_pll_config(unsigned int ddrpll_m) +{ +	pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1); +} + +void sata_pll_config(void) +{ +	/* +	 * This sequence for configuring the SATA PLL +	 * resident in the control module is documented +	 * in TI8148 TRM section 21.3.1 +	 */ +	writel(SATA_PLLCFG1, &spll->pllcfg1); +	udelay(50); + +	writel(SATA_PLLCFG3, &spll->pllcfg3); +	udelay(50); + +	writel(SATA_PLLCFG0_1, &spll->pllcfg0); +	udelay(50); + +	writel(SATA_PLLCFG0_2, &spll->pllcfg0); +	udelay(50); + +	writel(SATA_PLLCFG0_3, &spll->pllcfg0); +	udelay(50); + +	writel(SATA_PLLCFG0_4, &spll->pllcfg0); +	udelay(50); + +	while (((readl(&spll->pllstatus) & PLL_LOCK) == 0)) +		; +} + +void enable_dmm_clocks(void) +{ +	writel(PRCM_MOD_EN, &cmdef->fwclkctrl); +	writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); +	writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); +	while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN) +		; +	writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); +	while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN) +		; +	while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) +		; +	writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); +	while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN) +		; +	writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); +	while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) +		; +} + +void setup_clocks_for_console(void) +{ +	unlock_pll_control_mmr(); +	/* UART0 */ +	writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); +	while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) +		; +} +/* + * Configure the PLL/PRCM for necessary peripherals + */ +void prcm_init(void) +{ +	/* Enable the control module */ +	writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); + +	/* Configure PLLs */ +	mpu_pll_config(); +	l3_pll_config(); +	sata_pll_config(); + +	/* Enable the required peripherals */ +	enable_per_clocks(); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c new file mode 100644 index 00000000..ace4a5af --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c @@ -0,0 +1,445 @@ +/* + * clock_ti816x.c + * + * Clocks for TI816X based boards + * + * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com> + * Antoine Tenart, <atenart@adeneo-embedded.com> + * + * Based on TI-PSP-04.00.02.14 : + * + * Copyright (C) 2009, Texas Instruments, Incorporated + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +#include <asm/emif.h> + +#define CM_PLL_BASE		(CTRL_BASE + 0x0400) + +/* Main PLL */ +#define MAIN_N			64 +#define MAIN_P			0x1 +#define MAIN_INTFREQ1		0x8 +#define MAIN_FRACFREQ1		0x800000 +#define MAIN_MDIV1		0x2 +#define MAIN_INTFREQ2		0xE +#define MAIN_FRACFREQ2		0x0 +#define MAIN_MDIV2		0x1 +#define MAIN_INTFREQ3		0x8 +#define MAIN_FRACFREQ3		0xAAAAB0 +#define MAIN_MDIV3		0x3 +#define MAIN_INTFREQ4		0x9 +#define MAIN_FRACFREQ4		0x55554F +#define MAIN_MDIV4		0x3 +#define MAIN_INTFREQ5		0x9 +#define MAIN_FRACFREQ5		0x374BC6 +#define MAIN_MDIV5		0xC +#define MAIN_MDIV6		0x48 +#define MAIN_MDIV7		0x4 + +/* DDR PLL */ +#if defined(CONFIG_TI816X_DDR_PLL_400) /* 400 MHz */ +#define DDR_N			59 +#define DDR_P			0x1 +#define DDR_MDIV1		0x4 +#define DDR_INTFREQ2		0x8 +#define DDR_FRACFREQ2		0xD99999 +#define DDR_MDIV2		0x1E +#define DDR_INTFREQ3		0x8 +#define DDR_FRACFREQ3		0x0 +#define DDR_MDIV3		0x4 +#define DDR_INTFREQ4		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4		0x0 +#define DDR_MDIV4		0x4 +#define DDR_INTFREQ5		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5		0x0 +#define DDR_MDIV5		0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_531) /* 531 MHz */ +#define DDR_N			59 +#define DDR_P			0x1 +#define DDR_MDIV1		0x3 +#define DDR_INTFREQ2		0x8 +#define DDR_FRACFREQ2		0xD99999 +#define DDR_MDIV2		0x1E +#define DDR_INTFREQ3		0x8 +#define DDR_FRACFREQ3		0x0 +#define DDR_MDIV3		0x4 +#define DDR_INTFREQ4		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4		0x0 +#define DDR_MDIV4		0x4 +#define DDR_INTFREQ5		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5		0x0 +#define DDR_MDIV5		0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_675) /* 675 MHz */ +#define DDR_N			50 +#define DDR_P			0x1 +#define DDR_MDIV1		0x2 +#define DDR_INTFREQ2		0x9 +#define DDR_FRACFREQ2		0x0 +#define DDR_MDIV2		0x19 +#define DDR_INTFREQ3		0x13 +#define DDR_FRACFREQ3		0x800000 +#define DDR_MDIV3		0x2 +#define DDR_INTFREQ4		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4		0x0 +#define DDR_MDIV4		0x4 +#define DDR_INTFREQ5		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5		0x0 +#define DDR_MDIV5		0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_796) /* 796 MHz */ +#define DDR_N			59 +#define DDR_P			0x1 +#define DDR_MDIV1		0x2 +#define DDR_INTFREQ2		0x8 +#define DDR_FRACFREQ2		0xD99999 +#define DDR_MDIV2		0x1E +#define DDR_INTFREQ3		0x8 +#define DDR_FRACFREQ3		0x0 +#define DDR_MDIV3		0x4 +#define DDR_INTFREQ4		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4		0x0 +#define DDR_MDIV4		0x4 +#define DDR_INTFREQ5		0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5		0x0 +#define DDR_MDIV5		0x4 +#endif + +#define CONTROL_STATUS			(CTRL_BASE + 0x40) +#define DDR_RCD				(CTRL_BASE + 0x070C) +#define CM_TIMER1_CLKSEL		(PRCM_BASE + 0x390) +#define DMM_PAT_BASE_ADDR		(DMM_BASE + 0x420) +#define CM_ALWON_CUST_EFUSE_CLKCTRL	(PRCM_BASE + 0x1628) + +#define INTCPS_SYSCONFIG	0x48200010 +#define CM_SYSCLK10_CLKSEL	0x48180324 + +struct cm_pll { +	unsigned int mainpll_ctrl;	/* offset 0x400 */ +	unsigned int mainpll_pwd; +	unsigned int mainpll_freq1; +	unsigned int mainpll_div1; +	unsigned int mainpll_freq2; +	unsigned int mainpll_div2; +	unsigned int mainpll_freq3; +	unsigned int mainpll_div3; +	unsigned int mainpll_freq4; +	unsigned int mainpll_div4; +	unsigned int mainpll_freq5; +	unsigned int mainpll_div5; +	unsigned int resv0[1]; +	unsigned int mainpll_div6; +	unsigned int resv1[1]; +	unsigned int mainpll_div7; +	unsigned int ddrpll_ctrl;	/* offset 0x440 */ +	unsigned int ddrpll_pwd; +	unsigned int resv2[1]; +	unsigned int ddrpll_div1; +	unsigned int ddrpll_freq2; +	unsigned int ddrpll_div2; +	unsigned int ddrpll_freq3; +	unsigned int ddrpll_div3; +	unsigned int ddrpll_freq4; +	unsigned int ddrpll_div4; +	unsigned int ddrpll_freq5; +	unsigned int ddrpll_div5; +	unsigned int videopll_ctrl;	/* offset 0x470 */ +	unsigned int videopll_pwd; +	unsigned int videopll_freq1; +	unsigned int videopll_div1; +	unsigned int videopll_freq2; +	unsigned int videopll_div2; +	unsigned int videopll_freq3; +	unsigned int videopll_div3; +	unsigned int resv3[4]; +	unsigned int audiopll_ctrl;	/* offset 0x4A0 */ +	unsigned int audiopll_pwd; +	unsigned int resv4[2]; +	unsigned int audiopll_freq2; +	unsigned int audiopll_div2; +	unsigned int audiopll_freq3; +	unsigned int audiopll_div3; +	unsigned int audiopll_freq4; +	unsigned int audiopll_div4; +	unsigned int audiopll_freq5; +	unsigned int audiopll_div5; +}; + +const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; +const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; +const struct cm_pll *cmpll = (struct cm_pll *)CM_PLL_BASE; +const struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + +void enable_dmm_clocks(void) +{ +	writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); +	writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); +	writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); + +	/* Wait for clocks to be active */ +	while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) +		; +	/* Wait for emif0 to be fully functional, including OCP */ +	while (((readl(&cmdef->emif0clkctrl) >> 17) & 0x3) != 0) +		; +	/* Wait for emif1 to be fully functional, including OCP */ +	while (((readl(&cmdef->emif1clkctrl) >> 17) & 0x3) != 0) +		; + +	writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); +	/* Wait for dmm to be fully functional, including OCP */ +	while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0) +		; + +	/* Enable Tiled Access */ +	writel(0x80000000, DMM_PAT_BASE_ADDR); +} + +/* assume delay is aprox at least 1us */ +static void ddr_delay(int d) +{ +	int i; + +	/* +	 * read a control register. +	 * this is a bit more delay and cannot be optimized by the compiler +	 * assuming one read takes 200 cycles and A8 is runing 1 GHz +	 * somewhat conservative setting +	 */ +	for (i = 0; i < 50*d; i++) +		readl(CONTROL_STATUS); +} + +static void main_pll_init_ti816x(void) +{ +	u32 main_pll_ctrl = 0; + +	/* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ +	main_pll_ctrl = readl(&cmpll->mainpll_ctrl); +	main_pll_ctrl &= 0xFFFFFFFB; +	main_pll_ctrl |= BIT(2); +	writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + +	/* Enable PLL by setting BIT3 in its ctrl reg */ +	main_pll_ctrl = readl(&cmpll->mainpll_ctrl); +	main_pll_ctrl &= 0xFFFFFFF7; +	main_pll_ctrl |= BIT(3); +	writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + +	/* Write the values of N,P in the CTRL reg  */ +	main_pll_ctrl = readl(&cmpll->mainpll_ctrl); +	main_pll_ctrl &= 0xFF; +	main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8); +	writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + +	/* Power up clock1-7 */ +	writel(0x0, &cmpll->mainpll_pwd); + +	/* Program the freq and divider values for clock1-7 */ +	writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1), +		&cmpll->mainpll_freq1); +	writel(((1<<8) | MAIN_MDIV1), &cmpll->mainpll_div1); + +	writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2), +		&cmpll->mainpll_freq2); +	writel(((1<<8) | MAIN_MDIV2), &cmpll->mainpll_div2); + +	writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3), +		&cmpll->mainpll_freq3); +	writel(((1<<8) | MAIN_MDIV3), &cmpll->mainpll_div3); + +	writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4), +		&cmpll->mainpll_freq4); +	writel(((1<<8) | MAIN_MDIV4), &cmpll->mainpll_div4); + +	writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5), +		&cmpll->mainpll_freq5); +	writel(((1<<8) | MAIN_MDIV5), &cmpll->mainpll_div5); + +	writel((1<<8 | MAIN_MDIV6), &cmpll->mainpll_div6); + +	writel((1<<8 | MAIN_MDIV7), &cmpll->mainpll_div7); + +	/* Wait for PLL to lock */ +	while ((readl(&cmpll->mainpll_ctrl) & BIT(7)) != BIT(7)) +		; + +	/* Put the PLL in normal mode, disable bypass */ +	main_pll_ctrl = readl(&cmpll->mainpll_ctrl); +	main_pll_ctrl &= 0xFFFFFFFB; +	writel(main_pll_ctrl, &cmpll->mainpll_ctrl); +} + +static void ddr_pll_bypass_ti816x(void) +{ +	u32 ddr_pll_ctrl = 0; + +	/* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ +	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); +	ddr_pll_ctrl &= 0xFFFFFFFB; +	ddr_pll_ctrl |= BIT(2); +	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); +} + +static void ddr_pll_init_ti816x(void) +{ +	u32 ddr_pll_ctrl = 0; +	/* Enable PLL by setting BIT3 in its ctrl reg */ +	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); +	ddr_pll_ctrl &= 0xFFFFFFF7; +	ddr_pll_ctrl |= BIT(3); +	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); + +	/* Write the values of N,P in the CTRL reg  */ +	ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); +	ddr_pll_ctrl &= 0xFF; +	ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8); +	writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); + +	ddr_delay(10); + +	/* Power up clock1-5 */ +	writel(0x0, &cmpll->ddrpll_pwd); + +	/* Program the freq and divider values for clock1-3 */ +	writel(((0<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); +	ddr_delay(1); +	writel(((1<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); +	writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2), +		&cmpll->ddrpll_freq2); +	writel(((1<<8) | DDR_MDIV2), &cmpll->ddrpll_div2); +	writel(((0<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); +	ddr_delay(1); +	writel(((1<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); +	ddr_delay(1); +	writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), +		&cmpll->ddrpll_freq3); +	ddr_delay(1); +	writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), +		&cmpll->ddrpll_freq3); + +	ddr_delay(5); + +	/* Wait for PLL to lock */ +	while ((readl(&cmpll->ddrpll_ctrl) & BIT(7)) != BIT(7)) +		; + +	/* Power up RCD */ +	writel(BIT(0), DDR_RCD); +} + +static void peripheral_enable(void) +{ +	/* Wake-up the l3_slow clock */ +	writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); + +	/* +	 * Note on Timers: +	 * There are 8 timers(0-7) out of which timer 0 is a secure timer. +	 * Timer 0 mux should not be changed +	 * +	 * To access the timer registers we need the to be +	 * enabled which is what we do in the first step +	 */ + +	/* Enable timer1 */ +	writel(PRCM_MOD_EN, &cmalwon->timer1clkctrl); +	/* Select timer1 clock to be CLKIN (27MHz) */ +	writel(BIT(1), CM_TIMER1_CLKSEL); + +	/* Wait for timer1 to be ON-ACTIVE */ +	while (((readl(&cmalwon->l3slowclkstctrl) +					& (0x80000<<1))>>20) != 1) +		; +	/* Wait for timer1 to be enabled */ +	while (((readl(&cmalwon->timer1clkctrl) & 0x30000)>>16) != 0) +		; +	/* Active posted mode */ +	writel(PRCM_MOD_EN, (DM_TIMER1_BASE + 0x54)); +	while (readl(DM_TIMER1_BASE + 0x10) & BIT(0)) +		; +	/* Start timer1  */ +	writel(BIT(0), (DM_TIMER1_BASE + 0x38)); + +	/* eFuse */ +	writel(PRCM_MOD_EN, CM_ALWON_CUST_EFUSE_CLKCTRL); +	while (readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != PRCM_MOD_EN) +		; + +	/* Enable gpio0 */ +	writel(PRCM_MOD_EN, &cmalwon->gpio0clkctrl); +	while (readl(&cmalwon->gpio0clkctrl) != PRCM_MOD_EN) +		; +	writel((BIT(8)), &cmalwon->gpio0clkctrl); + +	/* Enable spi */ +	writel(PRCM_MOD_EN, &cmalwon->spiclkctrl); +	while (readl(&cmalwon->spiclkctrl) != PRCM_MOD_EN) +		; + +	/* Enable i2c0 */ +	writel(PRCM_MOD_EN, &cmalwon->i2c0clkctrl); +	while (readl(&cmalwon->i2c0clkctrl) != PRCM_MOD_EN) +		; + +	/* Enable ethernet0 */ +	writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl); +	writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl); +	writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl); + +	/* Enable hsmmc */ +	writel(PRCM_MOD_EN, &cmalwon->sdioclkctrl); +	while (readl(&cmalwon->sdioclkctrl) != PRCM_MOD_EN) +		; +} + +void setup_clocks_for_console(void) +{ +	/* Fix ROM code bug - from TI-PSP-04.00.02.14 */ +	writel(0x0, CM_SYSCLK10_CLKSEL); + +	ddr_pll_bypass_ti816x(); + +	/* Enable uart0-2 */ +	writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); +	while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) +		; +	writel(PRCM_MOD_EN, &cmalwon->uart1clkctrl); +	while (readl(&cmalwon->uart1clkctrl) != PRCM_MOD_EN) +		; +	writel(PRCM_MOD_EN, &cmalwon->uart2clkctrl); +	while (readl(&cmalwon->uart2clkctrl) != PRCM_MOD_EN) +		; +	while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) +		; +} + +void prcm_init(void) +{ +	/* Enable the control */ +	writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); + +	main_pll_init_ti816x(); +	ddr_pll_init_ti816x(); + +	/* +	 * With clk freqs setup to desired values, +	 * enable the required peripherals +	 */ +	peripheral_enable(); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/config.mk b/roms/u-boot/arch/arm/cpu/armv7/am33xx/config.mk new file mode 100644 index 00000000..5294d167 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/config.mk @@ -0,0 +1,11 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier:	GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +ALL-y	+= MLO +ALL-$(CONFIG_SPL_SPI_SUPPORT) += MLO.byteswap +else +ALL-y	+= u-boot.img +endif diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/ddr.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/ddr.c new file mode 100644 index 00000000..9a625c46 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/ddr.c @@ -0,0 +1,266 @@ +/* + * DDR Configuration for AM33xx devices. + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/arch/cpu.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/emif.h> + +/** + * Base address for EMIF instances + */ +static struct emif_reg_struct *emif_reg[2] = { +				(struct emif_reg_struct *)EMIF4_0_CFG_BASE, +				(struct emif_reg_struct *)EMIF4_1_CFG_BASE}; + +/** + * Base addresses for DDR PHY cmd/data regs + */ +static struct ddr_cmd_regs *ddr_cmd_reg[2] = { +				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR, +				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2}; + +static struct ddr_data_regs *ddr_data_reg[2] = { +				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR, +				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR2}; + +/** + * Base address for ddr io control instances + */ +static struct ddr_cmdtctrl *ioctrl_reg = { +			(struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR}; + +static inline u32 get_mr(int nr, u32 cs, u32 mr_addr) +{ +	u32 mr; + +	mr_addr |= cs << EMIF_REG_CS_SHIFT; +	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg); + +	mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data); +	debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr); +	if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) && +	    ((mr & 0x00ff0000) >> 16) == (mr & 0xff) && +	    ((mr & 0xff000000) >> 24) == (mr & 0xff)) +		return mr & 0xff; +	else +		return mr; +} + +static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val) +{ +	mr_addr |= cs << EMIF_REG_CS_SHIFT; +	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg); +	writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data); +} + +static void configure_mr(int nr, u32 cs) +{ +	u32 mr_addr; + +	while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK) +		; +	set_mr(nr, cs, LPDDR2_MR10, 0x56); + +	set_mr(nr, cs, LPDDR2_MR1, 0x43); +	set_mr(nr, cs, LPDDR2_MR2, 0x2); + +	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK; +	set_mr(nr, cs, mr_addr, 0x2); +} + +/* + * Configure EMIF4D5 registers and MR registers + */ +void config_sdram_emif4d5(const struct emif_regs *regs, int nr) +{ +	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl); +	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw); +	writel(0x1, &emif_reg[nr]->emif_iodft_tlgc); +	writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); + +	writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config); +	writel(regs->emif_rd_wr_lvl_rmp_win, +	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_win); +	writel(regs->emif_rd_wr_lvl_rmp_ctl, +	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); +	writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl); +	writel(regs->emif_rd_wr_exec_thresh, +	       &emif_reg[nr]->emif_rd_wr_exec_thresh); + +	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); +	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); +	writel(regs->sdram_config, &cstat->secure_emif_sdram_config); + +	if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) { +		configure_mr(nr, 0); +		configure_mr(nr, 1); +	} +} + +/** + * Configure SDRAM + */ +void config_sdram(const struct emif_regs *regs, int nr) +{ +	if (regs->zq_config) { +		/* +		 * A value of 0x2800 for the REF CTRL will give us +		 * about 570us for a delay, which will be long enough +		 * to configure things. +		 */ +		writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl); +		writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); +		writel(regs->sdram_config, &cstat->secure_emif_sdram_config); +		writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); +		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); +		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); +	} +	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); +	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); +	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); +} + +/** + * Set SDRAM timings + */ +void set_sdram_timings(const struct emif_regs *regs, int nr) +{ +	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1); +	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw); +	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2); +	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw); +	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3); +	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw); +} + +void __weak emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size) +{ +} + +/* + * Configure EXT PHY registers + */ +static void ext_phy_settings(const struct emif_regs *regs, int nr) +{ +	u32 *ext_phy_ctrl_base = 0; +	u32 *emif_ext_phy_ctrl_base = 0; +	const u32 *ext_phy_ctrl_const_regs; +	u32 i = 0; +	u32 size; + +	ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1); +	emif_ext_phy_ctrl_base = +			(u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1); + +	/* Configure external phy control timing registers */ +	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { +		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); +		/* Update shadow registers */ +		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); +	} + +	/* +	 * external phy 6-24 registers do not change with +	 * ddr frequency +	 */ +	emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size); + +	if (!size) +		return; + +	for (i = 0; i < size; i++) { +		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); +		/* Update shadow registers */ +		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); +	} +} + +/** + * Configure DDR PHY + */ +void config_ddr_phy(const struct emif_regs *regs, int nr) +{ +	/* +	 * disable initialization and refreshes for now until we +	 * finish programming EMIF regs. +	 */ +	setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl, +		     EMIF_REG_INITREF_DIS_MASK); + +	writel(regs->emif_ddr_phy_ctlr_1, +		&emif_reg[nr]->emif_ddr_phy_ctrl_1); +	writel(regs->emif_ddr_phy_ctlr_1, +		&emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw); + +	if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) +		ext_phy_settings(regs, nr); +} + +/** + * Configure DDR CMD control registers + */ +void config_cmd_ctrl(const struct cmd_control *cmd, int nr) +{ +	if (!cmd) +		return; + +	writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio); +	writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout); + +	writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio); +	writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout); + +	writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio); +	writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout); +} + +/** + * Configure DDR DATA registers + */ +void config_ddr_data(const struct ddr_data *data, int nr) +{ +	int i; + +	if (!data) +		return; + +	for (i = 0; i < DDR_DATA_REGS_NR; i++) { +		writel(data->datardsratio0, +			&(ddr_data_reg[nr]+i)->dt0rdsratio0); +		writel(data->datawdsratio0, +			&(ddr_data_reg[nr]+i)->dt0wdsratio0); +		writel(data->datawiratio0, +			&(ddr_data_reg[nr]+i)->dt0wiratio0); +		writel(data->datagiratio0, +			&(ddr_data_reg[nr]+i)->dt0giratio0); +		writel(data->datafwsratio0, +			&(ddr_data_reg[nr]+i)->dt0fwsratio0); +		writel(data->datawrsratio0, +			&(ddr_data_reg[nr]+i)->dt0wrsratio0); +	} +} + +void config_io_ctrl(const struct ctrl_ioregs *ioregs) +{ +	if (!ioregs) +		return; + +	writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl); +	writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl); +	writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl); +	writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl); +	writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl); +#ifdef CONFIG_AM43XX +	writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl); +	writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl); +	writel(ioregs->emif_sdram_config_ext, +	       &ioctrl_reg->emif_sdram_config_ext); +#endif +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/emif4.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/emif4.c new file mode 100644 index 00000000..2c67c322 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/emif4.c @@ -0,0 +1,132 @@ +/* + * emif4.c + * + * AM33XX emif4 configuration file + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/hardware.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/emif.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ +	/* 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; +} + +void dram_init_banksize(void) +{ +	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; +	gd->bd->bi_dram[0].size = gd->ram_size; +} + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +#ifdef CONFIG_TI81XX +static struct dmm_lisa_map_regs *hw_lisa_map_regs = +				(struct dmm_lisa_map_regs *)DMM_BASE; +#endif +#ifndef CONFIG_TI816X +static struct vtp_reg *vtpreg[2] = { +				(struct vtp_reg *)VTP0_CTRL_ADDR, +				(struct vtp_reg *)VTP1_CTRL_ADDR}; +#endif +#ifdef CONFIG_AM33XX +static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; +#endif +#ifdef CONFIG_AM43XX +static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; +static struct cm_device_inst *cm_device = +				(struct cm_device_inst *)CM_DEVICE_INST; +#endif + +#ifdef CONFIG_TI81XX +void config_dmm(const struct dmm_lisa_map_regs *regs) +{ +	enable_dmm_clocks(); + +	writel(0, &hw_lisa_map_regs->dmm_lisa_map_3); +	writel(0, &hw_lisa_map_regs->dmm_lisa_map_2); +	writel(0, &hw_lisa_map_regs->dmm_lisa_map_1); +	writel(0, &hw_lisa_map_regs->dmm_lisa_map_0); + +	writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3); +	writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2); +	writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1); +	writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0); +} +#endif + +#ifndef CONFIG_TI816X +static void config_vtp(int nr) +{ +	writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE, +			&vtpreg[nr]->vtp0ctrlreg); +	writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN), +			&vtpreg[nr]->vtp0ctrlreg); +	writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN, +			&vtpreg[nr]->vtp0ctrlreg); + +	/* Poll for READY */ +	while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) != +			VTP_CTRL_READY) +		; +} +#endif + +void __weak ddr_pll_config(unsigned int ddrpll_m) +{ +} + +void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs, +		const struct ddr_data *data, const struct cmd_control *ctrl, +		const struct emif_regs *regs, int nr) +{ +	ddr_pll_config(pll); +#ifndef CONFIG_TI816X +	config_vtp(nr); +#endif +	config_cmd_ctrl(ctrl, nr); + +	config_ddr_data(data, nr); +#ifdef CONFIG_AM33XX +	config_io_ctrl(ioregs); + +	/* Set CKE to be controlled by EMIF/DDR PHY */ +	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); +#endif +#ifdef CONFIG_AM43XX +	writel(readl(&cm_device->cm_dll_ctrl) & ~0x1, &cm_device->cm_dll_ctrl); +	while ((readl(&cm_device->cm_dll_ctrl) && CM_DLL_READYST) == 0) +		; +	writel(0x80000000, &ddrctrl->ddrioctrl); + +	config_io_ctrl(ioregs); + +	/* Set CKE to be controlled by EMIF/DDR PHY */ +	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); +#endif + +	/* Program EMIF instance */ +	config_ddr_phy(regs, nr); +	set_sdram_timings(regs, nr); +	if (get_emif_rev(EMIF1_BASE) == EMIF_4D5) +		config_sdram_emif4d5(regs, nr); +	else +		config_sdram(regs, nr); +} +#endif diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/mem.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/mem.c new file mode 100644 index 00000000..56c9e7db --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/mem.c @@ -0,0 +1,98 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + *     Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * Initial Code from: + *     Manikandan Pillai <mani.pillai@ti.com> + *     Richard Woodruff <r-woodruff2@ti.com> + *     Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <command.h> + +struct gpmc *gpmc_cfg; + + +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, +			u32 size) +{ +	writel(0, &cs->config7); +	sdelay(1000); +	/* Delay for settling */ +	writel(gpmc_config[0], &cs->config1); +	writel(gpmc_config[1], &cs->config2); +	writel(gpmc_config[2], &cs->config3); +	writel(gpmc_config[3], &cs->config4); +	writel(gpmc_config[4], &cs->config5); +	writel(gpmc_config[5], &cs->config6); +	/* Enable the config */ +	writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | +		(1 << 6)), &cs->config7); +	sdelay(2000); +} + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ +	/* putting a blanket check on GPMC based on ZeBu for now */ +	gpmc_cfg = (struct gpmc *)GPMC_BASE; +#if defined(CONFIG_NOR) +/* configure GPMC for NOR */ +	const u32 gpmc_regs[GPMC_MAX_REG] = {	STNOR_GPMC_CONFIG1, +						STNOR_GPMC_CONFIG2, +						STNOR_GPMC_CONFIG3, +						STNOR_GPMC_CONFIG4, +						STNOR_GPMC_CONFIG5, +						STNOR_GPMC_CONFIG6, +						STNOR_GPMC_CONFIG7 +						}; +	u32 size = GPMC_SIZE_16M; +	u32 base = CONFIG_SYS_FLASH_BASE; +#elif defined(CONFIG_NAND) +/* configure GPMC for NAND */ +	const u32  gpmc_regs[GPMC_MAX_REG] = {	M_NAND_GPMC_CONFIG1, +						M_NAND_GPMC_CONFIG2, +						M_NAND_GPMC_CONFIG3, +						M_NAND_GPMC_CONFIG4, +						M_NAND_GPMC_CONFIG5, +						M_NAND_GPMC_CONFIG6, +						0 +						}; +	u32 size = GPMC_SIZE_256M; +	u32 base = CONFIG_SYS_NAND_BASE; +#else +	const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 }; +	u32 size = 0; +	u32 base = 0; +#endif +	/* global settings */ +	writel(0x00000008, &gpmc_cfg->sysconfig); +	writel(0x00000000, &gpmc_cfg->irqstatus); +	writel(0x00000000, &gpmc_cfg->irqenable); +#ifdef CONFIG_NOR +	writel(0x00000200, &gpmc_cfg->config); +#else +	writel(0x00000012, &gpmc_cfg->config); +#endif +	/* +	 * Disable the GPMC0 config set by ROM code +	 */ +	writel(0, &gpmc_cfg->cs[0].config7); +	sdelay(1000); +	/* enable chip-select specific configurations */ +	enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/mux.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/mux.c new file mode 100644 index 00000000..2ded4722 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/mux.c @@ -0,0 +1,33 @@ +/* + * mux.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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/arch/mux.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* + * Configure the pin mux for the module + */ +void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux) +{ +	int i; + +	if (!mod_pin_mux) +		return; + +	for (i = 0; mod_pin_mux[i].reg_offset != -1; i++) +		MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c b/roms/u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c new file mode 100644 index 00000000..50eb598f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c @@ -0,0 +1,178 @@ +/* + * sys_info.c + * + * System information functions + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * Derived from Beagle Board and 3430 SDP code by + *      Richard Woodruff <r-woodruff2@ti.com> + *      Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <power/tps65910.h> + +struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE; + +/** + * get_cpu_rev(void) - extract rev info + */ +u32 get_cpu_rev(void) +{ +	u32 id; +	u32 rev; + +	id = readl(DEVICE_ID); +	rev = (id >> 28) & 0xff; + +	return rev; +} + +/** + * get_cpu_type(void) - extract cpu info + */ +u32 get_cpu_type(void) +{ +	u32 id = 0; +	u32 partnum; + +	id = readl(DEVICE_ID); +	partnum = (id >> 12) & 0xffff; + +	return partnum; +} + +/** + * get_board_rev() - setup to pass kernel board revision information + * returns:(bit[0-3] sub version, higher bit[7-4] is higher version) + */ +u32 get_board_rev(void) +{ +	return BOARD_REV_ID; +} + +/** + * get_device_type(): tell if GP/HS/EMU/TST + */ +u32 get_device_type(void) +{ +	int mode; +	mode = readl(&cstat->statusreg) & (DEVICE_MASK); +	return mode >>= 8; +} + +/** + * get_sysboot_value(void) - return SYS_BOOT[4:0] + */ +u32 get_sysboot_value(void) +{ +	int mode; +	mode = readl(&cstat->statusreg) & (SYSBOOT_MASK); +	return mode; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +/** + * Print CPU information + */ +int print_cpuinfo(void) +{ +	char *cpu_s, *sec_s; + +	switch (get_cpu_type()) { +	case AM335X: +		cpu_s = "AM335X"; +		break; +	case TI81XX: +		cpu_s = "TI81XX"; +		break; +	default: +		cpu_s = "Unknown cpu type"; +		break; +	} + +	switch (get_device_type()) { +	case TST_DEVICE: +		sec_s = "TST"; +		break; +	case EMU_DEVICE: +		sec_s = "EMU"; +		break; +	case HS_DEVICE: +		sec_s = "HS"; +		break; +	case GP_DEVICE: +		sec_s = "GP"; +		break; +	default: +		sec_s = "?"; +	} + +	printf("%s-%s rev %d\n", cpu_s, sec_s, get_cpu_rev()); + +	return 0; +} +#endif	/* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_AM33XX +int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev) +{ +	int sil_rev; + +	sil_rev = readl(&cdev->deviceid) >> 28; + +	if (sil_rev == 1) +		/* PG 2.0, efuse may not be set. */ +		return MPUPLL_M_800; +	else if (sil_rev >= 2) { +		/* Check what the efuse says our max speed is. */ +		int efuse_arm_mpu_max_freq; +		efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma); +		switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) { +		case AM335X_ZCZ_1000: +			return MPUPLL_M_1000; +		case AM335X_ZCZ_800: +			return MPUPLL_M_800; +		case AM335X_ZCZ_720: +			return MPUPLL_M_720; +		case AM335X_ZCZ_600: +		case AM335X_ZCE_600: +			return MPUPLL_M_600; +		case AM335X_ZCZ_300: +		case AM335X_ZCE_300: +			return MPUPLL_M_300; +		} +	} + +	/* PG 1.0 or otherwise unknown, use the PG1.0 max */ +	return MPUPLL_M_720; +} + +int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency) +{ +	/* For PG2.1 and later, we have one set of values. */ +	if (sil_rev >= 2) { +		switch (frequency) { +		case MPUPLL_M_1000: +			return TPS65910_OP_REG_SEL_1_3_2_5; +		case MPUPLL_M_800: +			return TPS65910_OP_REG_SEL_1_2_6; +		case MPUPLL_M_720: +			return TPS65910_OP_REG_SEL_1_2_0; +		case MPUPLL_M_600: +		case MPUPLL_M_300: +			return TPS65910_OP_REG_SEL_1_1_3; +		} +	} + +	/* Default to PG1.0/PG2.0 values. */ +	return TPS65910_OP_REG_SEL_1_1_3; +} +#endif diff --git a/roms/u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds new file mode 100644 index 00000000..b1c28c94 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + *	Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ +		LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ +		LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	.text      : +	{ +		__start = .; +		arch/arm/cpu/armv7/start.o	(.text) +		*(.text*) +	} >.sram + +	. = ALIGN(4); +	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + +	. = ALIGN(4); +	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} >.sram + +	. = ALIGN(4); +	__image_copy_end = .; + +	.end : +	{ +		*(.__end) +	} >.sram + +	.bss : +	{ +		. = ALIGN(4); +		__bss_start = .; +		*(.bss*) +		. = ALIGN(4); +		__bss_end = .; +	} >.sdram +}  | 
