avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
40
u-boot/arch/arm/cpu/armv7/am33xx/Kconfig
Normal file
40
u-boot/arch/arm/cpu/armv7/am33xx/Kconfig
Normal file
@@ -0,0 +1,40 @@
|
||||
if AM43XX
|
||||
config TARGET_AM43XX_EVM
|
||||
bool "Support am43xx_evm"
|
||||
select TI_I2C_BOARD_DETECT
|
||||
help
|
||||
This option specifies support for the AM43xx
|
||||
GP and HS EVM development platforms.The AM437x
|
||||
GP EVM is a standalone test, development, and
|
||||
evaluation module system that enables developers
|
||||
to write software and develop hardware around
|
||||
an AM43xx processor subsystem.
|
||||
|
||||
config ISW_ENTRY_ADDR
|
||||
hex "Address in memory or XIP flash of bootloader entry point"
|
||||
help
|
||||
After any reset, the boot ROM on the AM43XX SOC
|
||||
searches the boot media for a valid boot image.
|
||||
For non-XIP devices, the ROM then copies the
|
||||
image into internal memory.
|
||||
For all boot modes, after the ROM processes the
|
||||
boot image it eventually computes the entry
|
||||
point address depending on the device type
|
||||
(secure/non-secure), boot media (xip/non-xip) and
|
||||
image headers.
|
||||
default 0x402F4000
|
||||
|
||||
config PUB_ROM_DATA_SIZE
|
||||
hex "Size in bytes of the L3 SRAM reserved by ROM to store data"
|
||||
help
|
||||
During the device boot, the public ROM uses the top of
|
||||
the public L3 OCMC RAM to store r/w data like stack,
|
||||
heap, globals etc. When the ROM is copying the boot
|
||||
image from the boot media into memory, the image must
|
||||
not spill over into this area. This value can be used
|
||||
during compile time to determine the maximum size of a
|
||||
boot image. Once the ROM transfers control to the boot
|
||||
image, this area is no longer used, and can be reclaimed
|
||||
for run time use by the boot image.
|
||||
default 0x8400
|
||||
endif
|
||||
22
u-boot/arch/arm/cpu/armv7/am33xx/Makefile
Normal file
22
u-boot/arch/arm/cpu/armv7/am33xx/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# 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 += ddr.o
|
||||
obj-y += emif4.o
|
||||
obj-y += board.o
|
||||
obj-y += mux.o
|
||||
|
||||
obj-$(CONFIG_CLOCK_SYNTHESIZER) += clk_synthesizer.o
|
||||
300
u-boot/arch/arm/cpu/armv7/am33xx/board.c
Normal file
300
u-boot/arch/arm/cpu/armv7/am33xx/board.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
#include <ns16550.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;
|
||||
|
||||
#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 },
|
||||
# ifdef CONFIG_SYS_NS16550_COM2
|
||||
{ .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK },
|
||||
# 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 },
|
||||
# endif
|
||||
# endif
|
||||
};
|
||||
|
||||
U_BOOT_DEVICES(am33xx_uarts) = {
|
||||
{ "ns16550_serial", &am33xx_serial[0] },
|
||||
# ifdef CONFIG_SYS_NS16550_COM2
|
||||
{ "ns16550_serial", &am33xx_serial[1] },
|
||||
# ifdef CONFIG_SYS_NS16550_COM3
|
||||
{ "ns16550_serial", &am33xx_serial[2] },
|
||||
{ "ns16550_serial", &am33xx_serial[3] },
|
||||
{ "ns16550_serial", &am33xx_serial[4] },
|
||||
{ "ns16550_serial", &am33xx_serial[5] },
|
||||
# endif
|
||||
# endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DM_GPIO
|
||||
static const struct omap_gpio_platdata am33xx_gpio[] = {
|
||||
{ 0, AM33XX_GPIO0_BASE },
|
||||
{ 1, AM33XX_GPIO1_BASE },
|
||||
{ 2, AM33XX_GPIO2_BASE },
|
||||
{ 3, AM33XX_GPIO3_BASE },
|
||||
#ifdef CONFIG_AM43XX
|
||||
{ 4, AM33XX_GPIO4_BASE },
|
||||
{ 5, AM33XX_GPIO5_BASE },
|
||||
#endif
|
||||
};
|
||||
|
||||
U_BOOT_DEVICES(am33xx_gpios) = {
|
||||
{ "gpio_omap", &am33xx_gpio[0] },
|
||||
{ "gpio_omap", &am33xx_gpio[1] },
|
||||
{ "gpio_omap", &am33xx_gpio[2] },
|
||||
{ "gpio_omap", &am33xx_gpio[3] },
|
||||
#ifdef CONFIG_AM43XX
|
||||
{ "gpio_omap", &am33xx_gpio[4] },
|
||||
{ "gpio_omap", &am33xx_gpio[5] },
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DM_GPIO
|
||||
static const struct gpio_bank gpio_bank_am33xx[] = {
|
||||
{ (void *)AM33XX_GPIO0_BASE },
|
||||
{ (void *)AM33XX_GPIO1_BASE },
|
||||
{ (void *)AM33XX_GPIO2_BASE },
|
||||
{ (void *)AM33XX_GPIO3_BASE },
|
||||
#ifdef CONFIG_AM43XX
|
||||
{ (void *)AM33XX_GPIO4_BASE },
|
||||
{ (void *)AM33XX_GPIO5_BASE },
|
||||
#endif
|
||||
};
|
||||
|
||||
const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
|
||||
#endif
|
||||
|
||||
#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_USB_MUSB_GADGET) || defined(CONFIG_USB_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
|
||||
/*
|
||||
* 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
|
||||
* and that's not true in s_init in this case so we cannot do it there.
|
||||
*/
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
prcm_init();
|
||||
set_mux_conf_regs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
board_early_init_f();
|
||||
sdram_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
watchdog_disable();
|
||||
set_uart_mux_conf();
|
||||
setup_clocks_for_console();
|
||||
uart_soft_reset();
|
||||
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
|
||||
/* Enable RTC32K clock */
|
||||
rtc32k_enable();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
104
u-boot/arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
Normal file
104
u-boot/arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* clk-synthesizer.c
|
||||
*
|
||||
* Clock synthesizer apis
|
||||
*
|
||||
* Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clk_synthesizer.h>
|
||||
#include <i2c.h>
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_read - Read register from synthesizer.
|
||||
* @addr: addr within the i2c device
|
||||
* buf: Buffer to which value is to be read.
|
||||
*
|
||||
* For reading the register from this clock synthesizer, a command needs to
|
||||
* be send along with enabling byte read more, and then read can happen.
|
||||
* Returns 0 on success
|
||||
*/
|
||||
static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Enable Bye read */
|
||||
addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
|
||||
/* Send the command byte */
|
||||
rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
|
||||
if (rc)
|
||||
printf("Failed to send command to clock synthesizer\n");
|
||||
|
||||
/* Read the Data */
|
||||
return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_write - Write a value to register in synthesizer.
|
||||
* @addr: addr within the i2c device
|
||||
* val: Value to be written in the addr.
|
||||
*
|
||||
* Enable the byte read mode in the address and start the i2c transfer.
|
||||
* Returns 0 on success
|
||||
*/
|
||||
static int clk_synthesizer_reg_write(int addr, uint8_t val)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
int rc = 0;
|
||||
|
||||
/* Enable byte write */
|
||||
cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
cmd[1] = val;
|
||||
|
||||
rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
|
||||
if (rc)
|
||||
printf("Clock synthesizer reg write failed at addr = 0x%x\n",
|
||||
addr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_clock_syntherizer - Program the clock synthesizer to get the desired
|
||||
* frequency.
|
||||
* @data: Data containing the desired output
|
||||
*
|
||||
* This is a PLL-based high performance synthesizer which gives 3 outputs
|
||||
* as per the PLL_DIV and load capacitor programmed.
|
||||
*/
|
||||
int setup_clock_synthesizer(struct clk_synth *data)
|
||||
{
|
||||
int rc;
|
||||
uint8_t val;
|
||||
|
||||
rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
|
||||
if (rc) {
|
||||
printf("i2c probe failed at address 0x%x\n",
|
||||
CLK_SYNTHESIZER_I2C_ADDR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
|
||||
if (val != data->id)
|
||||
return rc;
|
||||
|
||||
/* Crystal Load capacitor selection */
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
241
u-boot/arch/arm/cpu/armv7/am33xx/clock.c
Normal file
241
u-boot/arch/arm/cpu/armv7/am33xx/clock.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 wait_for_clk_disable(u32 *clkctrl_addr)
|
||||
{
|
||||
u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
|
||||
u32 bound = LDELAY;
|
||||
|
||||
while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
|
||||
clkctrl = readl(clkctrl_addr);
|
||||
idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
|
||||
MODULE_CLKCTRL_IDLEST_SHIFT;
|
||||
if (--bound == 0) {
|
||||
printf("Clock disable failed for 0x%p idlest 0x%x\n",
|
||||
clkctrl_addr, clkctrl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
static inline void disable_clock_module(u32 *const clkctrl_addr,
|
||||
u32 wait_for_disable)
|
||||
{
|
||||
clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
|
||||
MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
|
||||
MODULE_CLKCTRL_MODULEMODE_SHIFT);
|
||||
debug("Disable clock module - %p\n", clkctrl_addr);
|
||||
if (wait_for_disable)
|
||||
wait_for_clk_disable(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);
|
||||
}
|
||||
|
||||
static inline void disable_clock_domain(u32 *const clkctrl_reg)
|
||||
{
|
||||
clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
|
||||
CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
|
||||
CD_CLKCTRL_CLKTRCTRL_SHIFT);
|
||||
debug("Disable 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 do_disable_clocks(u32 *const *clk_domains,
|
||||
u32 *const *clk_modules_disable,
|
||||
u8 wait_for_disable)
|
||||
{
|
||||
u32 i, max = 100;
|
||||
|
||||
|
||||
/* Clock modules that need to be put in SW_DISABLE */
|
||||
for (i = 0; (i < max) && clk_modules_disable[i]; i++)
|
||||
disable_clock_module(clk_modules_disable[i],
|
||||
wait_for_disable);
|
||||
|
||||
/* Put the clock domains in SW_SLEEP mode */
|
||||
for (i = 0; (i < max) && clk_domains[i]; i++)
|
||||
disable_clock_domain(clk_domains[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Before scaling up the clocks we need to have the PMIC scale up the
|
||||
* voltages first. This will be dependent on which PMIC is in use
|
||||
* and in some cases we may not be scaling things up at all and thus not
|
||||
* need to do anything here.
|
||||
*/
|
||||
__weak void scale_vcores(void)
|
||||
{
|
||||
}
|
||||
|
||||
void prcm_init()
|
||||
{
|
||||
enable_basic_clocks();
|
||||
scale_vcores();
|
||||
setup_dplls();
|
||||
timer_init();
|
||||
}
|
||||
234
u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
Normal file
234
u-boot/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable Spread Spectrum for the MPU by calculating the required
|
||||
* values and setting the registers accordingly.
|
||||
* @param permille The spreading in permille (10th of a percent)
|
||||
*/
|
||||
void set_mpu_spreadspectrum(int permille)
|
||||
{
|
||||
u32 multiplier_m;
|
||||
u32 predivider_n;
|
||||
u32 cm_clksel_dpll_mpu;
|
||||
u32 cm_clkmode_dpll_mpu;
|
||||
u32 ref_clock;
|
||||
u32 pll_bandwidth;
|
||||
u32 mod_freq_divider;
|
||||
u32 exponent;
|
||||
u32 mantissa;
|
||||
u32 delta_m_step;
|
||||
|
||||
printf("Enabling Spread Spectrum of %d permille for MPU\n",
|
||||
permille);
|
||||
|
||||
/* Read PLL parameter m and n */
|
||||
cm_clksel_dpll_mpu = readl(&cmwkup->clkseldpllmpu);
|
||||
multiplier_m = (cm_clksel_dpll_mpu >> 8) & 0x3FF;
|
||||
predivider_n = cm_clksel_dpll_mpu & 0x7F;
|
||||
|
||||
/*
|
||||
* Calculate reference clock (clock after pre-divider),
|
||||
* its max. PLL bandwidth,
|
||||
* and resulting mod_freq_divider
|
||||
*/
|
||||
ref_clock = V_OSCK / (predivider_n + 1);
|
||||
pll_bandwidth = ref_clock / 70;
|
||||
mod_freq_divider = ref_clock / (4 * pll_bandwidth);
|
||||
|
||||
/* Calculate Mantissa/Exponent */
|
||||
exponent = 0;
|
||||
mantissa = mod_freq_divider;
|
||||
while ((mantissa > 127) && (exponent < 7)) {
|
||||
exponent++;
|
||||
mantissa /= 2;
|
||||
}
|
||||
if (mantissa > 127)
|
||||
mantissa = 127;
|
||||
|
||||
mod_freq_divider = mantissa << exponent;
|
||||
|
||||
/*
|
||||
* Calculate Modulation steps
|
||||
* As we use Downspread only, the spread is twice the value of
|
||||
* permille, so Div2!
|
||||
* As it takes the value in percent, divide by ten!
|
||||
*/
|
||||
delta_m_step = ((u32)((multiplier_m * permille) / 10 / 2)) << 18;
|
||||
delta_m_step /= 100;
|
||||
delta_m_step /= mod_freq_divider;
|
||||
if (delta_m_step > 0xFFFFF)
|
||||
delta_m_step = 0xFFFFF;
|
||||
|
||||
/* Setup Spread Spectrum */
|
||||
writel(delta_m_step, &cmwkup->sscdeltamstepdllmpu);
|
||||
writel((exponent << 8) | mantissa, &cmwkup->sscmodfreqdivdpllmpu);
|
||||
cm_clkmode_dpll_mpu = readl(&cmwkup->clkmoddpllmpu);
|
||||
/* clear all SSC flags */
|
||||
cm_clkmode_dpll_mpu &= ~(0xF << CM_CLKMODE_DPLL_SSC_EN_SHIFT);
|
||||
/* enable SSC with Downspread only */
|
||||
cm_clkmode_dpll_mpu |= CM_CLKMODE_DPLL_SSC_EN_MASK |
|
||||
CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK;
|
||||
writel(cm_clkmode_dpll_mpu, &cmwkup->clkmoddpllmpu);
|
||||
while (!(readl(&cmwkup->clkmoddpllmpu) & 0x2000))
|
||||
;
|
||||
}
|
||||
231
u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
Normal file
231
u-boot/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
|
||||
|
||||
/* 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);
|
||||
|
||||
while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
|
||||
(idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
|
||||
clkctrl = readl(&cmwkup->wkup_uart0ctrl);
|
||||
idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
|
||||
MODULE_CLKCTRL_IDLEST_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,
|
||||
&cmper->spi0clkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
|
||||
|
||||
/* Select the Master osc clk as Timer2 clock source */
|
||||
writel(0x1, &cmdpll->clktimer2clk);
|
||||
|
||||
/* For OPP100 the mac clock should be /5. */
|
||||
writel(0x4, &cmdpll->clkselmacclk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TI_EDMA3
|
||||
void enable_edma3_clocks(void)
|
||||
{
|
||||
u32 *const clk_domains_edma3[] = {
|
||||
0
|
||||
};
|
||||
|
||||
u32 *const clk_modules_explicit_en_edma3[] = {
|
||||
&cmper->tpccclkctrl,
|
||||
&cmper->tptc0clkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_enable_clocks(clk_domains_edma3,
|
||||
clk_modules_explicit_en_edma3,
|
||||
1);
|
||||
}
|
||||
|
||||
void disable_edma3_clocks(void)
|
||||
{
|
||||
u32 *const clk_domains_edma3[] = {
|
||||
0
|
||||
};
|
||||
|
||||
u32 *const clk_modules_disable_edma3[] = {
|
||||
&cmper->tpccclkctrl,
|
||||
&cmper->tptc0clkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_disable_clocks(clk_domains_edma3,
|
||||
clk_modules_disable_edma3,
|
||||
1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
|
||||
void enable_usb_clocks(int index)
|
||||
{
|
||||
u32 *usbclkctrl = 0;
|
||||
u32 *usbphyocp2scpclkctrl = 0;
|
||||
|
||||
if (index == 0) {
|
||||
usbclkctrl = &cmper->usb0clkctrl;
|
||||
usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
|
||||
setbits_le32(&cmper->usb0clkctrl,
|
||||
USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
|
||||
setbits_le32(&cmwkup->usbphy0clkctrl,
|
||||
USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
|
||||
} else if (index == 1) {
|
||||
usbclkctrl = &cmper->usb1clkctrl;
|
||||
usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
|
||||
setbits_le32(&cmper->usb1clkctrl,
|
||||
USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
|
||||
setbits_le32(&cmwkup->usbphy1clkctrl,
|
||||
USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
|
||||
}
|
||||
|
||||
u32 *const clk_domains_usb[] = {
|
||||
0
|
||||
};
|
||||
|
||||
u32 *const clk_modules_explicit_en_usb[] = {
|
||||
usbclkctrl,
|
||||
usbphyocp2scpclkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_enable_clocks(clk_domains_usb, clk_modules_explicit_en_usb, 1);
|
||||
}
|
||||
|
||||
void disable_usb_clocks(int index)
|
||||
{
|
||||
u32 *usbclkctrl = 0;
|
||||
u32 *usbphyocp2scpclkctrl = 0;
|
||||
|
||||
if (index == 0) {
|
||||
usbclkctrl = &cmper->usb0clkctrl;
|
||||
usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl;
|
||||
clrbits_le32(&cmper->usb0clkctrl,
|
||||
USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
|
||||
clrbits_le32(&cmwkup->usbphy0clkctrl,
|
||||
USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
|
||||
} else if (index == 1) {
|
||||
usbclkctrl = &cmper->usb1clkctrl;
|
||||
usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl;
|
||||
clrbits_le32(&cmper->usb1clkctrl,
|
||||
USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960);
|
||||
clrbits_le32(&cmwkup->usbphy1clkctrl,
|
||||
USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K);
|
||||
}
|
||||
|
||||
u32 *const clk_domains_usb[] = {
|
||||
0
|
||||
};
|
||||
|
||||
u32 *const clk_modules_disable_usb[] = {
|
||||
usbclkctrl,
|
||||
usbphyocp2scpclkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_disable_clocks(clk_domains_usb, clk_modules_disable_usb, 1);
|
||||
}
|
||||
#endif
|
||||
404
u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
Normal file
404
u-boot/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
Normal file
@@ -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();
|
||||
}
|
||||
445
u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c
Normal file
445
u-boot/arch/arm/cpu/armv7/am33xx/clock_ti816x.c
Normal file
@@ -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();
|
||||
}
|
||||
31
u-boot/arch/arm/cpu/armv7/am33xx/config.mk
Normal file
31
u-boot/arch/arm/cpu/armv7/am33xx/config.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
include $(srctree)/$(CPUDIR)/omap-common/config_secure.mk
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
|
||||
#
|
||||
# For booting from SPI use
|
||||
# u-boot-spl_HS_SPI_X-LOADER to program flash
|
||||
#
|
||||
# For booting spl from all other media
|
||||
# use u-boot-spl_HS_ISSW
|
||||
#
|
||||
# Refer to README.ti-secure for more info
|
||||
#
|
||||
ALL-y += u-boot-spl_HS_ISSW
|
||||
ALL-$(CONFIG_SPL_SPI_SUPPORT) += u-boot-spl_HS_SPI_X-LOADER
|
||||
else
|
||||
ALL-y += MLO
|
||||
ALL-$(CONFIG_SPL_SPI_SUPPORT) += MLO.byteswap
|
||||
endif
|
||||
else
|
||||
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
|
||||
ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
|
||||
endif
|
||||
ALL-y += u-boot.img
|
||||
endif
|
||||
379
u-boot/arch/arm/cpu/armv7/am33xx/ddr.c
Normal file
379
u-boot/arch/arm/cpu/armv7/am33xx/ddr.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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 For details about these magic
|
||||
* values please see the EMIF registers section of the TRM.
|
||||
*/
|
||||
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(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);
|
||||
|
||||
/*
|
||||
* for most SOCs these registers won't need to be changed so only
|
||||
* write to these registers if someone explicitly has set the
|
||||
* register's value.
|
||||
*/
|
||||
if(regs->emif_cos_config) {
|
||||
writel(regs->emif_prio_class_serv_map, &emif_reg[nr]->emif_prio_class_serv_map);
|
||||
writel(regs->emif_connect_id_serv_1_map, &emif_reg[nr]->emif_connect_id_serv_1_map);
|
||||
writel(regs->emif_connect_id_serv_2_map, &emif_reg[nr]->emif_connect_id_serv_2_map);
|
||||
writel(regs->emif_cos_config, &emif_reg[nr]->emif_cos_config);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sequence to ensure that the PHY is in a known state prior to
|
||||
* startting hardware leveling. Also acts as to latch some state from
|
||||
* the EMIF into the PHY.
|
||||
*/
|
||||
writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
|
||||
clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
|
||||
EMIF_REG_INITREF_DIS_MASK);
|
||||
|
||||
writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
|
||||
writel(regs->sdram_config, &cstat->secure_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);
|
||||
|
||||
/* Perform hardware leveling for DDR3 */
|
||||
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
|
||||
udelay(1000);
|
||||
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
|
||||
0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
|
||||
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
|
||||
0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
|
||||
|
||||
writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
|
||||
|
||||
/* Enable read leveling */
|
||||
writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
|
||||
|
||||
/*
|
||||
* Enable full read and write leveling. Wait for read and write
|
||||
* leveling bit to clear RDWRLVLFULL_START bit 31
|
||||
*/
|
||||
while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000)
|
||||
!= 0)
|
||||
;
|
||||
|
||||
/* Check the timeout register to see if leveling is complete */
|
||||
if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
|
||||
puts("DDR3 H/W leveling incomplete with errors\n");
|
||||
|
||||
} else {
|
||||
/* DDR2 */
|
||||
configure_mr(nr, 0);
|
||||
configure_mr(nr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure SDRAM
|
||||
*/
|
||||
void config_sdram(const struct emif_regs *regs, int nr)
|
||||
{
|
||||
if (regs->zq_config) {
|
||||
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);
|
||||
|
||||
/* Trigger initialization */
|
||||
writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
|
||||
/* Wait 1ms because of L3 timeout error */
|
||||
udelay(1000);
|
||||
|
||||
/* Write proper sdram_ref_cref_ctrl value */
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure EXT PHY registers for software leveling
|
||||
*/
|
||||
static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr)
|
||||
{
|
||||
u32 *ext_phy_ctrl_base = 0;
|
||||
u32 *emif_ext_phy_ctrl_base = 0;
|
||||
__maybe_unused const u32 *ext_phy_ctrl_const_regs;
|
||||
u32 i = 0;
|
||||
__maybe_unused 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++);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AM43XX
|
||||
/*
|
||||
* External phy 6-24 registers do not change with ddr frequency.
|
||||
* These only need to be set on DDR2 on AM43xx.
|
||||
*/
|
||||
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++);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure EXT PHY registers for hardware leveling
|
||||
*/
|
||||
static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
|
||||
{
|
||||
/*
|
||||
* Enable hardware leveling on the EMIF. For details about these
|
||||
* magic values please see the EMIF registers section of the TRM.
|
||||
*/
|
||||
writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
|
||||
writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22_shdw);
|
||||
writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23);
|
||||
writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23_shdw);
|
||||
writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24);
|
||||
writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24_shdw);
|
||||
writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25);
|
||||
writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25_shdw);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26_shdw);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27_shdw);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28_shdw);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29_shdw);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30);
|
||||
writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34_shdw);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35);
|
||||
writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35_shdw);
|
||||
writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
|
||||
writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
|
||||
|
||||
/*
|
||||
* Sequence to ensure that the PHY is again in a known state after
|
||||
* hardware leveling.
|
||||
*/
|
||||
writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Also set time between rising edge of DDR_RESET to rising
|
||||
* edge of DDR_CKE to > 500us per memory spec.
|
||||
*/
|
||||
#ifndef CONFIG_AM43XX
|
||||
setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
|
||||
EMIF_REG_INITREF_DIS_MASK);
|
||||
#endif
|
||||
if (regs->zq_config)
|
||||
/* Set time between rising edge of DDR_RESET to rising
|
||||
* edge of DDR_CKE to > 500us per memory spec. */
|
||||
writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
|
||||
|
||||
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) {
|
||||
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
|
||||
ext_phy_settings_hwlvl(regs, nr);
|
||||
else
|
||||
ext_phy_settings_swlvl(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
|
||||
}
|
||||
140
u-boot/arch/arm/cpu/armv7/am33xx/emif4.c
Normal file
140
u-boot/arch/arm/cpu/armv7/am33xx/emif4.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
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)
|
||||
;
|
||||
|
||||
config_io_ctrl(ioregs);
|
||||
|
||||
/* Set CKE to be controlled by EMIF/DDR PHY */
|
||||
writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
|
||||
|
||||
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
|
||||
/* Allow EMIF to control DDR_RESET */
|
||||
writel(0x00000000, &ddrctrl->ddrioctrl);
|
||||
#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
|
||||
33
u-boot/arch/arm/cpu/armv7/am33xx/mux.c
Normal file
33
u-boot/arch/arm/cpu/armv7/am33xx/mux.c
Normal file
@@ -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);
|
||||
}
|
||||
175
u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c
Normal file
175
u-boot/arch/arm/cpu/armv7/am33xx/sys_info.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <linux/compiler.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_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
|
||||
static char *cpu_revs[] = {
|
||||
"1.0",
|
||||
"2.0",
|
||||
"2.1"};
|
||||
|
||||
|
||||
static char *dev_types[] = {
|
||||
"TST",
|
||||
"EMU",
|
||||
"HS",
|
||||
"GP"};
|
||||
|
||||
/**
|
||||
* Print CPU information
|
||||
*/
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
char *cpu_s, *sec_s, *rev_s;
|
||||
|
||||
switch (get_cpu_type()) {
|
||||
case AM335X:
|
||||
cpu_s = "AM335X";
|
||||
break;
|
||||
case TI81XX:
|
||||
cpu_s = "TI81XX";
|
||||
break;
|
||||
default:
|
||||
cpu_s = "Unknown CPU type";
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
|
||||
rev_s = cpu_revs[get_cpu_rev()];
|
||||
else
|
||||
rev_s = "?";
|
||||
|
||||
if (get_device_type() < ARRAY_SIZE(dev_types))
|
||||
sec_s = dev_types[get_device_type()];
|
||||
else
|
||||
sec_s = "?";
|
||||
|
||||
printf("%s-%s rev %s\n", cpu_s, sec_s, rev_s);
|
||||
|
||||
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
|
||||
56
u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
Normal file
56
u-boot/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* (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 = .;
|
||||
*(.vectors)
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user