GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
if TI816X
|
||||
|
||||
config TARGET_TI816X_EVM
|
||||
bool "Support ti816x_evm"
|
||||
help
|
||||
This option specifies support for the TI8168 EVM development platform
|
||||
with PG2.0 silicon and DDR3 DRAM.
|
||||
|
||||
endif
|
||||
|
||||
if TI814X
|
||||
|
||||
config TARGET_TI814X_EVM
|
||||
bool "Support ti814x_evm"
|
||||
help
|
||||
This option specifies support for the TI8148
|
||||
EVM development platform.
|
||||
|
||||
endif
|
||||
|
||||
if AM33XX
|
||||
|
||||
config AM33XX_CHILISOM
|
||||
bool
|
||||
select SUPPORT_SPL
|
||||
|
||||
choice
|
||||
prompt "AM33xx board select"
|
||||
|
||||
config TARGET_AM335X_EVM
|
||||
bool "Support am335x_evm"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
select TI_I2C_BOARD_DETECT
|
||||
imply CMD_DM
|
||||
imply SPL_DM
|
||||
imply SPL_DM_SEQ_ALIAS
|
||||
imply SPL_ENV_SUPPORT
|
||||
imply SPL_FS_EXT4
|
||||
imply SPL_FS_FAT
|
||||
imply SPL_GPIO_SUPPORT
|
||||
imply SPL_I2C_SUPPORT
|
||||
imply SPL_LIBCOMMON_SUPPORT
|
||||
imply SPL_LIBDISK_SUPPORT
|
||||
imply SPL_LIBGENERIC_SUPPORT
|
||||
imply SPL_MMC_SUPPORT
|
||||
imply SPL_NAND_SUPPORT
|
||||
imply SPL_OF_LIBFDT
|
||||
imply SPL_POWER_SUPPORT
|
||||
imply SPL_SEPARATE_BSS
|
||||
imply SPL_SERIAL_SUPPORT
|
||||
imply SPL_SYS_MALLOC_SIMPLE
|
||||
imply SPL_WATCHDOG_SUPPORT
|
||||
imply SPL_YMODEM_SUPPORT
|
||||
help
|
||||
This option specifies support for the AM335x
|
||||
GP and HS EVM development platforms. The AM335x
|
||||
GP EVM is a standalone test, development, and
|
||||
evaluation module system that enables developers
|
||||
to write software and develop hardware around
|
||||
an AM335x processor subsystem.
|
||||
|
||||
config TARGET_AM335X_BALTOS
|
||||
bool "Support am335x_baltos"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_AM335X_IGEP003X
|
||||
bool "Support am335x_igep003x"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_AM335X_SHC
|
||||
bool "Support am335x based shc board from bosch"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
imply CMD_SPL
|
||||
|
||||
config TARGET_AM335X_GUARDIAN
|
||||
bool "Support am335x based guardian board from bosch"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select DM_GPIO
|
||||
select DM_USB
|
||||
|
||||
config TARGET_AM335X_SL50
|
||||
bool "Support am335x_sl50"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_BAV335X
|
||||
bool "Support bav335x"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
help
|
||||
The BAV335x OEM Network Processor integrates all the functions of an
|
||||
embedded network computer in a small, easy to use SODIMM module which
|
||||
incorporates the popular Texas Instruments Sitara 32bit ARM Coretex-A8
|
||||
processor, with fast DDR3 512MB SDRAM, 4GB of embedded MMC and a Gigabit
|
||||
ethernet with simple connection to external connectors.
|
||||
|
||||
For more information, visit: http://birdland.com/oem
|
||||
|
||||
config TARGET_BRXRE1
|
||||
bool "Support BRXRE1"
|
||||
select BOARD_LATE_INIT
|
||||
|
||||
config TARGET_BRSMARC1
|
||||
bool "Support BRSMARC1"
|
||||
select BOARD_LATE_INIT
|
||||
|
||||
config TARGET_BRPPT1
|
||||
bool "Support BRPPT1"
|
||||
select BOARD_LATE_INIT
|
||||
|
||||
config TARGET_CHILIBOARD
|
||||
bool "Grinn chiliBoard"
|
||||
select AM33XX_CHILISOM
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_CM_T335
|
||||
bool "Support cm_t335"
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_DRACO
|
||||
bool "Support draco"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_ETAMIN
|
||||
bool "Support etamin"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PCM051
|
||||
bool "Support pcm051"
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PENGWYN
|
||||
bool "Support pengwyn"
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PEPPER
|
||||
bool "Support pepper"
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PHYCORE_AM335X_R2
|
||||
bool "Support phyCORE AM335X R2"
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PXM2
|
||||
bool "Support pxm2"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_RASTABAN
|
||||
bool "Support rastaban"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_RUT
|
||||
bool "Support rut"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_THUBAN
|
||||
bool "Support thuban"
|
||||
select BOARD_LATE_INIT
|
||||
select DM
|
||||
select DM_GPIO
|
||||
select DM_SERIAL
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_PDU001
|
||||
bool "Support PDU001"
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
imply SPL_SEPARATE_BSS
|
||||
imply CMD_DM
|
||||
help
|
||||
Support for PDU001 platform developed by EETS GmbH.
|
||||
The PDU001 is a processor and display unit developed around
|
||||
the Computing-Module m2 from bytes at work AG.
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
if AM43XX
|
||||
|
||||
choice
|
||||
prompt "AM43xx board select"
|
||||
|
||||
config TARGET_AM43XX_EVM
|
||||
bool "Support am43xx_evm"
|
||||
select BOARD_LATE_INIT
|
||||
select TI_I2C_BOARD_DETECT
|
||||
imply DM_ETH
|
||||
imply DM_I2C
|
||||
imply DM_SPI
|
||||
imply DM_SPI_FLASH
|
||||
imply SPL_ENV_SUPPORT
|
||||
imply SPL_FS_EXT4
|
||||
imply SPL_FS_FAT
|
||||
imply SPL_GPIO_SUPPORT
|
||||
imply SPL_I2C_SUPPORT
|
||||
imply SPL_LIBCOMMON_SUPPORT
|
||||
imply SPL_LIBDISK_SUPPORT
|
||||
imply SPL_LIBGENERIC_SUPPORT
|
||||
imply SPL_MMC_SUPPORT
|
||||
imply SPL_NAND_SUPPORT
|
||||
imply SPL_POWER_SUPPORT
|
||||
imply SPL_SERIAL_SUPPORT
|
||||
imply SPL_WATCHDOG_SUPPORT
|
||||
imply SPL_YMODEM_SUPPORT
|
||||
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 TARGET_CM_T43
|
||||
bool "Support cm_t43"
|
||||
|
||||
endchoice
|
||||
|
||||
config SPL_RTC_DDR_SUPPORT
|
||||
bool
|
||||
depends on SPL
|
||||
prompt "Enable RTC-DDR ONLY Support"
|
||||
help
|
||||
If you want RTC-DDR ONLY Support, say Y. RTC Only with DDR in
|
||||
self-refresh mode is a special power saving mode where in all
|
||||
the other voltages are turned off apart from the RTC domain and DDR.
|
||||
So only RTC is alive and ticking and one can program it to wake
|
||||
up after a predetermined period. Once RTC alarm fires, the PMIC
|
||||
powers up all the voltage domains. U-Boot takes a special path
|
||||
as the DDR has contents is in self-refresh and restore path is
|
||||
followed.
|
||||
|
||||
endif
|
||||
|
||||
if AM43XX || AM33XX
|
||||
config PUB_ROM_DATA_SIZE
|
||||
hex "Size in bytes of the L3 SRAM reserved by ROM to store data"
|
||||
default 0x8400
|
||||
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.
|
||||
endif
|
||||
@@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
|
||||
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
|
||||
ifeq ($(CONFIG_TI816X)$(CONFIG_SKIP_LOWLEVEL_INIT),)
|
||||
obj-y += emif4.o
|
||||
endif
|
||||
obj-$(CONFIG_TI816X) += ti816x_emif4.o
|
||||
obj-y += board.o
|
||||
obj-y += mux.o
|
||||
obj-y += prcm-regs.o
|
||||
obj-y += hw_data.o
|
||||
obj-y += fdt.o
|
||||
|
||||
obj-$(CONFIG_CLOCK_SYNTHESIZER) += clk_synthesizer.o
|
||||
|
||||
obj-$(CONFIG_AM33XX_CHILISOM) += chilisom.o
|
||||
@@ -0,0 +1,580 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* board.c
|
||||
*
|
||||
* Common board functions for AM33XX based boards
|
||||
*
|
||||
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <debug_uart.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/i2c.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/mmc_host_def.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/emif.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/omap_common.h>
|
||||
#include <i2c.h>
|
||||
#include <miiphy.h>
|
||||
#include <cpsw.h>
|
||||
#include <linux/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>
|
||||
|
||||
#define AM43XX_EMIF_BASE 0x4C000000
|
||||
#define AM43XX_SDRAM_CONFIG_OFFSET 0x8
|
||||
#define AM43XX_SDRAM_TYPE_MASK 0xE0000000
|
||||
#define AM43XX_SDRAM_TYPE_SHIFT 29
|
||||
#define AM43XX_SDRAM_TYPE_DDR3 3
|
||||
#define AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET 0xDC
|
||||
#define AM43XX_RDWRLVLFULL_START 0x80000000
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
sdram_init();
|
||||
#endif
|
||||
|
||||
/* dram_init must store complete ramsize in gd->ram_size */
|
||||
gd->ram_size = get_ram_size(
|
||||
(void *)CONFIG_SYS_SDRAM_BASE,
|
||||
CONFIG_MAX_RAM_BANK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
||||
gd->bd->bi_dram[0].size = gd->ram_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
static const struct ns16550_platdata am33xx_serial[] = {
|
||||
{ .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
# ifdef CONFIG_SYS_NS16550_COM2
|
||||
{ .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
# ifdef CONFIG_SYS_NS16550_COM3
|
||||
{ .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
{ .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
{ .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
{ .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2,
|
||||
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
|
||||
# endif
|
||||
# endif
|
||||
};
|
||||
|
||||
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_I2C
|
||||
static const struct omap_i2c_platdata am33xx_i2c[] = {
|
||||
{ I2C_BASE1, 100000, OMAP_I2C_REV_V2},
|
||||
{ I2C_BASE2, 100000, OMAP_I2C_REV_V2},
|
||||
{ I2C_BASE3, 100000, OMAP_I2C_REV_V2},
|
||||
};
|
||||
|
||||
U_BOOT_DEVICES(am33xx_i2c) = {
|
||||
{ "i2c_omap", &am33xx_i2c[0] },
|
||||
{ "i2c_omap", &am33xx_i2c[1] },
|
||||
{ "i2c_omap", &am33xx_i2c[2] },
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_GPIO
|
||||
static const struct omap_gpio_platdata am33xx_gpio[] = {
|
||||
{ 0, AM33XX_GPIO0_BASE },
|
||||
{ 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_MMC_OMAP_HS)
|
||||
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
|
||||
|
||||
/*
|
||||
* RTC only with DDR in self-refresh mode magic value, checked against during
|
||||
* boot to see if we have a valid config. This should be in sync with the value
|
||||
* that will be in drivers/soc/ti/pm33xx.c.
|
||||
*/
|
||||
#define RTC_MAGIC_VAL 0x8cd0
|
||||
|
||||
/* Board type field bit shift for RTC only with DDR in self-refresh mode */
|
||||
#define RTC_BOARD_TYPE_SHIFT 16
|
||||
|
||||
/* AM33XX has two MUSB controllers which can be host or gadget */
|
||||
#if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \
|
||||
(defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \
|
||||
(!CONFIG_IS_ENABLED(DM_USB) || !CONFIG_IS_ENABLED(OF_CONTROL)) && \
|
||||
(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_MUSB_NEW_SUPPORT))
|
||||
|
||||
static struct musb_hdrc_config musb_config = {
|
||||
.multipoint = 1,
|
||||
.dyn_fifo = 1,
|
||||
.num_eps = 16,
|
||||
.ram_bits = 12,
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_USB) && !CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
static struct ti_musb_platdata usb0 = {
|
||||
.base = (void *)USB0_OTG_BASE,
|
||||
.ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl0,
|
||||
.plat = {
|
||||
.config = &musb_config,
|
||||
.power = 50,
|
||||
.platform_ops = &musb_dsps_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ti_musb_platdata usb1 = {
|
||||
.base = (void *)USB1_OTG_BASE,
|
||||
.ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl1,
|
||||
.plat = {
|
||||
.config = &musb_config,
|
||||
.power = 50,
|
||||
.platform_ops = &musb_dsps_ops,
|
||||
},
|
||||
};
|
||||
|
||||
U_BOOT_DEVICES(am33xx_usbs) = {
|
||||
#if CONFIG_AM335X_USB0_MODE == MUSB_PERIPHERAL
|
||||
{ "ti-musb-peripheral", &usb0 },
|
||||
#elif CONFIG_AM335X_USB0_MODE == MUSB_HOST
|
||||
{ "ti-musb-host", &usb0 },
|
||||
#endif
|
||||
#if CONFIG_AM335X_USB1_MODE == MUSB_PERIPHERAL
|
||||
{ "ti-musb-peripheral", &usb1 },
|
||||
#elif CONFIG_AM335X_USB1_MODE == MUSB_HOST
|
||||
{ "ti-musb-host", &usb1 },
|
||||
#endif
|
||||
};
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||
|
||||
/* USB 2.0 PHY Control */
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AM335X_USB0
|
||||
static void am33xx_otg0_set_phy_power(struct udevice *dev, 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(struct udevice *dev, 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
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_first_device(UCLASS_MISC, &dev);
|
||||
if (ret || !dev)
|
||||
return ret;
|
||||
|
||||
#if defined(CONFIG_DM_ETH) && defined(CONFIG_USB_ETHER)
|
||||
ret = usb_ether_init();
|
||||
if (ret) {
|
||||
pr_err("USB ether init failed\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
|
||||
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) || \
|
||||
(defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT))
|
||||
static void rtc32k_unlock(struct davinci_rtc *rtc)
|
||||
{
|
||||
/*
|
||||
* Unlock the RTC's registers. For more details please see the
|
||||
* RTC_SS section of the TRM. In order to unlock we need to
|
||||
* write these specific values (keys) in this order.
|
||||
*/
|
||||
writel(RTC_KICK0R_WE, &rtc->kick0r);
|
||||
writel(RTC_KICK1R_WE, &rtc->kick1r);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
|
||||
/*
|
||||
* Write contents of the RTC_SCRATCH1 register based on board type
|
||||
* Two things are passed
|
||||
* on. First 16 bits (0:15) are written with RTC_MAGIC value. Once the
|
||||
* control gets to kernel, kernel reads the scratchpad register and gets to
|
||||
* know that bootloader has rtc_only support.
|
||||
*
|
||||
* Second important thing is the board type (16:31). This is needed in the
|
||||
* rtc_only boot where in we want to avoid costly i2c reads to eeprom to
|
||||
* identify the board type and we go ahead and copy the board strings to
|
||||
* am43xx_board_name.
|
||||
*/
|
||||
void update_rtc_magic(void)
|
||||
{
|
||||
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
|
||||
u32 magic = RTC_MAGIC_VAL;
|
||||
|
||||
magic |= (rtc_only_get_board_type() << RTC_BOARD_TYPE_SHIFT);
|
||||
|
||||
rtc32k_unlock(rtc);
|
||||
|
||||
/* write magic */
|
||||
writel(magic, &rtc->scratch1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In the case of non-SPL based booting we'll want to call these
|
||||
* functions a tiny bit later as it will require gd to be set and cleared
|
||||
* and that's not true in s_init in this case so we cannot do it there.
|
||||
*/
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
set_mux_conf_regs();
|
||||
prcm_init();
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
|
||||
update_rtc_magic();
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
|
||||
static void rtc32k_enable(void)
|
||||
{
|
||||
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
|
||||
|
||||
rtc32k_unlock(rtc);
|
||||
|
||||
/* 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)
|
||||
;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
|
||||
/*
|
||||
* Check if we are executing rtc-only + DDR mode, and resume from it if needed
|
||||
*/
|
||||
static void rtc_only(void)
|
||||
{
|
||||
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
|
||||
struct prm_device_inst *prm_device =
|
||||
(struct prm_device_inst *)PRM_DEVICE_INST;
|
||||
|
||||
u32 scratch1, sdrc;
|
||||
void (*resume_func)(void);
|
||||
|
||||
scratch1 = readl(&rtc->scratch1);
|
||||
|
||||
/*
|
||||
* Check RTC scratch against RTC_MAGIC_VAL, RTC_MAGIC_VAL is only
|
||||
* written to this register when we want to wake up from RTC only
|
||||
* with DDR in self-refresh mode. Contents of the RTC_SCRATCH1:
|
||||
* bits 0-15: RTC_MAGIC_VAL
|
||||
* bits 16-31: board type (needed for sdram_init)
|
||||
*/
|
||||
if ((scratch1 & 0xffff) != RTC_MAGIC_VAL)
|
||||
return;
|
||||
|
||||
rtc32k_unlock(rtc);
|
||||
|
||||
/* Clear RTC magic */
|
||||
writel(0, &rtc->scratch1);
|
||||
|
||||
/*
|
||||
* Update board type based on value stored on RTC_SCRATCH1, this
|
||||
* is done so that we don't need to read the board type from eeprom
|
||||
* over i2c bus which is expensive
|
||||
*/
|
||||
rtc_only_update_board_type(scratch1 >> RTC_BOARD_TYPE_SHIFT);
|
||||
|
||||
/*
|
||||
* Enable EMIF_DEVOFF in PRCM_PRM_EMIF_CTRL to indicate to EMIF we
|
||||
* are resuming from self-refresh. This avoids an unnecessary re-init
|
||||
* of the DDR. The re-init takes time and we would need to wait for
|
||||
* it to complete before accessing DDR to avoid L3 NOC errors.
|
||||
*/
|
||||
writel(EMIF_CTRL_DEVOFF, &prm_device->emif_ctrl);
|
||||
|
||||
rtc_only_prcm_init();
|
||||
sdram_init();
|
||||
|
||||
/* Check EMIF4D_SDRAM_CONFIG[31:29] SDRAM_TYPE */
|
||||
/* Only perform leveling if SDRAM_TYPE = 3 (DDR3) */
|
||||
sdrc = readl(AM43XX_EMIF_BASE + AM43XX_SDRAM_CONFIG_OFFSET);
|
||||
|
||||
sdrc &= AM43XX_SDRAM_TYPE_MASK;
|
||||
sdrc >>= AM43XX_SDRAM_TYPE_SHIFT;
|
||||
|
||||
if (sdrc == AM43XX_SDRAM_TYPE_DDR3) {
|
||||
writel(AM43XX_RDWRLVLFULL_START,
|
||||
AM43XX_EMIF_BASE +
|
||||
AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET);
|
||||
mdelay(1);
|
||||
|
||||
am43xx_wait:
|
||||
sdrc = readl(AM43XX_EMIF_BASE +
|
||||
AM43XX_READ_WRITE_LEVELING_CTRL_OFFSET);
|
||||
if (sdrc == AM43XX_RDWRLVLFULL_START)
|
||||
goto am43xx_wait;
|
||||
}
|
||||
|
||||
resume_func = (void *)readl(&rtc->scratch0);
|
||||
if (resume_func)
|
||||
resume_func();
|
||||
}
|
||||
#endif
|
||||
|
||||
void s_init(void)
|
||||
{
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
|
||||
rtc_only();
|
||||
#endif
|
||||
}
|
||||
|
||||
void early_system_init(void)
|
||||
{
|
||||
/*
|
||||
* 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_early_clocks();
|
||||
uart_soft_reset();
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* Save the boot parameters passed from romcode.
|
||||
* We cannot delay the saving further than this,
|
||||
* to prevent overwrites.
|
||||
*/
|
||||
save_omap_boot_params();
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_UART_OMAP
|
||||
debug_uart_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
spl_early_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TI_I2C_BOARD_DETECT
|
||||
do_board_detect();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
|
||||
/* Enable RTC32K clock */
|
||||
rtc32k_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
hw_data_init();
|
||||
early_system_init();
|
||||
board_early_init_f();
|
||||
sdram_init();
|
||||
/* dram_init must store complete ramsize in gd->ram_size */
|
||||
gd->ram_size = get_ram_size(
|
||||
(void *)CONFIG_SYS_SDRAM_BASE,
|
||||
CONFIG_MAX_RAM_BANK_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int arch_cpu_init_dm(void)
|
||||
{
|
||||
hw_data_init();
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
early_system_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
* Copyright (C) 2017, Grinn - http://grinn-global.com/
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/clk_synthesizer.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/ddr_defs.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/omap.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/emif.h>
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/tps65217.h>
|
||||
#include <spl.h>
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
|
||||
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||
|
||||
static struct module_pin_mux i2c0_pin_mux[] = {
|
||||
{OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
|
||||
PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
|
||||
{OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
|
||||
PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
|
||||
{-1},
|
||||
};
|
||||
|
||||
static struct module_pin_mux nand_pin_mux[] = {
|
||||
{OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */
|
||||
{OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */
|
||||
{OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */
|
||||
{OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */
|
||||
{OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */
|
||||
{OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */
|
||||
{OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */
|
||||
{OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */
|
||||
{OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
|
||||
{OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */
|
||||
{OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */
|
||||
{OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
|
||||
{OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */
|
||||
{OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */
|
||||
{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */
|
||||
{-1},
|
||||
};
|
||||
|
||||
static void enable_i2c0_pin_mux(void)
|
||||
{
|
||||
configure_module_pin_mux(i2c0_pin_mux);
|
||||
}
|
||||
|
||||
void chilisom_enable_pin_mux(void)
|
||||
{
|
||||
/* chilisom pin mux */
|
||||
configure_module_pin_mux(nand_pin_mux);
|
||||
}
|
||||
|
||||
static const struct ddr_data ddr3_chilisom_data = {
|
||||
.datardsratio0 = MT41K256M16HA125E_RD_DQS,
|
||||
.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
|
||||
.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
|
||||
.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
|
||||
};
|
||||
|
||||
static const struct cmd_control ddr3_chilisom_cmd_ctrl_data = {
|
||||
.cmd0csratio = MT41K256M16HA125E_RATIO,
|
||||
.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
|
||||
|
||||
.cmd1csratio = MT41K256M16HA125E_RATIO,
|
||||
.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
|
||||
|
||||
.cmd2csratio = MT41K256M16HA125E_RATIO,
|
||||
.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
|
||||
};
|
||||
|
||||
static struct emif_regs ddr3_chilisom_emif_reg_data = {
|
||||
.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
|
||||
.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
|
||||
.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
|
||||
.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
|
||||
.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
|
||||
.ocp_config = 0x00141414,
|
||||
.zq_config = MT41K256M16HA125E_ZQ_CFG,
|
||||
.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
|
||||
};
|
||||
|
||||
void chilisom_spl_board_init(void)
|
||||
{
|
||||
int mpu_vdd;
|
||||
int usb_cur_lim;
|
||||
|
||||
enable_i2c0_pin_mux();
|
||||
|
||||
/* Get the frequency */
|
||||
dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
|
||||
|
||||
|
||||
if (i2c_probe(TPS65217_CHIP_PM))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Increase USB current limit to 1300mA or 1800mA and set
|
||||
* the MPU voltage controller as needed.
|
||||
*/
|
||||
if (dpll_mpu_opp100.m == MPUPLL_M_1000) {
|
||||
usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA;
|
||||
mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
|
||||
} else {
|
||||
usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA;
|
||||
mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
|
||||
}
|
||||
|
||||
if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
|
||||
TPS65217_POWER_PATH,
|
||||
usb_cur_lim,
|
||||
TPS65217_USB_INPUT_CUR_LIMIT_MASK))
|
||||
puts("tps65217_reg_write failure\n");
|
||||
|
||||
/* Set DCDC3 (CORE) voltage to 1.125V */
|
||||
if (tps65217_voltage_update(TPS65217_DEFDCDC3,
|
||||
TPS65217_DCDC_VOLT_SEL_1125MV)) {
|
||||
puts("tps65217_voltage_update failure\n");
|
||||
return;
|
||||
}
|
||||
/* Set CORE Frequencies to OPP100 */
|
||||
do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
|
||||
|
||||
/* Set DCDC2 (MPU) voltage */
|
||||
if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
|
||||
puts("tps65217_voltage_update failure\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set LDO3 to 1.8V and LDO4 to 3.3V */
|
||||
if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
|
||||
TPS65217_DEFLS1,
|
||||
TPS65217_LDO_VOLTAGE_OUT_1_8,
|
||||
TPS65217_LDO_MASK))
|
||||
puts("tps65217_reg_write failure\n");
|
||||
|
||||
if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
|
||||
TPS65217_DEFLS2,
|
||||
TPS65217_LDO_VOLTAGE_OUT_3_3,
|
||||
TPS65217_LDO_MASK))
|
||||
puts("tps65217_reg_write failure\n");
|
||||
|
||||
/* Set MPU Frequency to what we detected now that voltages are set */
|
||||
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
|
||||
}
|
||||
|
||||
#define OSC (V_OSCK/1000000)
|
||||
const struct dpll_params dpll_ddr_chilisom = {
|
||||
400, OSC-1, 1, -1, -1, -1, -1};
|
||||
|
||||
const struct dpll_params *get_dpll_ddr_params(void)
|
||||
{
|
||||
return &dpll_ddr_chilisom;
|
||||
}
|
||||
|
||||
const struct ctrl_ioregs ioregs_chilisom = {
|
||||
.cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
|
||||
.cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
|
||||
.cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
|
||||
.dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
|
||||
.dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
|
||||
};
|
||||
|
||||
void sdram_init(void)
|
||||
{
|
||||
config_ddr(400, &ioregs_chilisom,
|
||||
&ddr3_chilisom_data,
|
||||
&ddr3_chilisom_cmd_ctrl_data,
|
||||
&ddr3_chilisom_emif_reg_data, 0);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* clk-synthesizer.c
|
||||
*
|
||||
* Clock synthesizer apis
|
||||
*
|
||||
* Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clk_synthesizer.h>
|
||||
#include <i2c.h>
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_read - Read register from synthesizer.
|
||||
* dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
|
||||
* @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(struct udevice *dev, int addr, u8 *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Enable Bye read */
|
||||
addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
/* 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);
|
||||
#else
|
||||
/* Send the command byte */
|
||||
rc = dm_i2c_reg_write(dev, addr, *buf);
|
||||
if (rc)
|
||||
printf("Failed to send command to clock synthesizer\n");
|
||||
|
||||
/* Read the Data */
|
||||
rc = dm_i2c_reg_read(dev, addr);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*buf = (u8)rc;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_write - Write a value to register in synthesizer.
|
||||
* dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
|
||||
* @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(struct udevice *dev, int addr, u8 val)
|
||||
{
|
||||
u8 cmd[2];
|
||||
int rc = 0;
|
||||
|
||||
/* Enable byte write */
|
||||
cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
cmd[1] = val;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
|
||||
#else
|
||||
rc = dm_i2c_write(dev, addr, cmd, 2);
|
||||
#endif
|
||||
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;
|
||||
u8 val = 0;
|
||||
struct udevice *dev = NULL;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
|
||||
if (rc) {
|
||||
printf("i2c probe failed at address 0x%x\n",
|
||||
CLK_SYNTHESIZER_I2C_ADDR);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
|
||||
if (rc) {
|
||||
printf("failed to get device for synthesizer at address 0x%x\n",
|
||||
CLK_SYNTHESIZER_I2C_ADDR);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
|
||||
if (val != data->id)
|
||||
return rc;
|
||||
|
||||
/* Crystal Load capacitor selection */
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
|
||||
data->capacitor);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
|
||||
data->mux);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
|
||||
data->pdiv2);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
|
||||
data->pdiv3);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* clock.c
|
||||
*
|
||||
* Clock initialization for AM33XX boards.
|
||||
* Derived from OMAP4 boards
|
||||
*
|
||||
* Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
#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 setup_early_clocks(void)
|
||||
{
|
||||
setup_clocks_for_console();
|
||||
enable_basic_clocks();
|
||||
timer_init();
|
||||
}
|
||||
|
||||
void prcm_init(void)
|
||||
{
|
||||
scale_vcores();
|
||||
setup_dplls();
|
||||
}
|
||||
|
||||
void rtc_only_prcm_init(void)
|
||||
{
|
||||
const struct dpll_params *params;
|
||||
|
||||
rtc_only_enable_basic_clocks();
|
||||
|
||||
params = get_dpll_ddr_params();
|
||||
do_setup_dpll(&dpll_ddr_regs, params);
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* clock_am33xx.c
|
||||
*
|
||||
* clocks for AM33XX based boards
|
||||
*
|
||||
* Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/sys_proto.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,
|
||||
};
|
||||
|
||||
const struct dpll_regs dpll_disp_regs = {
|
||||
.cm_clkmode_dpll = CM_WKUP + 0x98,
|
||||
.cm_idlest_dpll = CM_WKUP + 0x48,
|
||||
.cm_clksel_dpll = CM_WKUP + 0x54,
|
||||
.cm_div_m2_dpll = CM_WKUP + 0xA4,
|
||||
};
|
||||
|
||||
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_opp[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
|
||||
{ /* 19.2 MHz */
|
||||
{125, 3, 2, -1, -1, -1, -1}, /* OPP 50 */
|
||||
{-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
|
||||
{125, 3, 1, -1, -1, -1, -1}, /* OPP 100 */
|
||||
{150, 3, 1, -1, -1, -1, -1}, /* OPP 120 */
|
||||
{125, 2, 1, -1, -1, -1, -1}, /* OPP TB */
|
||||
{625, 11, 1, -1, -1, -1, -1} /* OPP NT */
|
||||
},
|
||||
{ /* 24 MHz */
|
||||
{25, 0, 2, -1, -1, -1, -1}, /* OPP 50 */
|
||||
{-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
|
||||
{25, 0, 1, -1, -1, -1, -1}, /* OPP 100 */
|
||||
{30, 0, 1, -1, -1, -1, -1}, /* OPP 120 */
|
||||
{100, 3, 1, -1, -1, -1, -1}, /* OPP TB */
|
||||
{125, 2, 1, -1, -1, -1, -1} /* OPP NT */
|
||||
},
|
||||
{ /* 25 MHz */
|
||||
{24, 0, 2, -1, -1, -1, -1}, /* OPP 50 */
|
||||
{-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
|
||||
{24, 0, 1, -1, -1, -1, -1}, /* OPP 100 */
|
||||
{144, 4, 1, -1, -1, -1, -1}, /* OPP 120 */
|
||||
{32, 0, 1, -1, -1, -1, -1}, /* OPP TB */
|
||||
{40, 0, 1, -1, -1, -1, -1} /* OPP NT */
|
||||
},
|
||||
{ /* 26 MHz */
|
||||
{300, 12, 2, -1, -1, -1, -1}, /* OPP 50 */
|
||||
{-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
|
||||
{300, 12, 1, -1, -1, -1, -1}, /* OPP 100 */
|
||||
{360, 12, 1, -1, -1, -1, -1}, /* OPP 120 */
|
||||
{400, 12, 1, -1, -1, -1, -1}, /* OPP TB */
|
||||
{500, 12, 1, -1, -1, -1, -1} /* OPP NT */
|
||||
},
|
||||
};
|
||||
|
||||
const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ] = {
|
||||
{625, 11, -1, -1, 10, 8, 4}, /* 19.2 MHz */
|
||||
{125, 2, -1, -1, 10, 8, 4}, /* 24 MHz */
|
||||
{40, 0, -1, -1, 10, 8, 4}, /* 25 MHz */
|
||||
{500, 12, -1, -1, 10, 8, 4} /* 26 MHz */
|
||||
};
|
||||
|
||||
const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ] = {
|
||||
{400, 7, 5, -1, -1, -1, -1}, /* 19.2 MHz */
|
||||
{400, 9, 5, -1, -1, -1, -1}, /* 24 MHz */
|
||||
{384, 9, 5, -1, -1, -1, -1}, /* 25 MHz */
|
||||
{480, 12, 5, -1, -1, -1, -1} /* 26 MHz */
|
||||
};
|
||||
|
||||
const struct dpll_params dpll_ddr3_303MHz[NUM_CRYSTAL_FREQ] = {
|
||||
{505, 15, 2, -1, -1, -1, -1}, /*19.2*/
|
||||
{101, 3, 2, -1, -1, -1, -1}, /* 24 MHz */
|
||||
{303, 24, 1, -1, -1, -1, -1}, /* 25 MHz */
|
||||
{303, 12, 2, -1, -1, -1, -1} /* 26 MHz */
|
||||
};
|
||||
|
||||
const struct dpll_params dpll_ddr3_400MHz[NUM_CRYSTAL_FREQ] = {
|
||||
{125, 5, 1, -1, -1, -1, -1}, /*19.2*/
|
||||
{50, 2, 1, -1, -1, -1, -1}, /* 24 MHz */
|
||||
{16, 0, 1, -1, -1, -1, -1}, /* 25 MHz */
|
||||
{200, 12, 1, -1, -1, -1, -1} /* 26 MHz */
|
||||
};
|
||||
|
||||
const struct dpll_params dpll_ddr2_266MHz[NUM_CRYSTAL_FREQ] = {
|
||||
{665, 47, 1, -1, -1, -1, -1}, /*19.2*/
|
||||
{133, 11, 1, -1, -1, -1, -1}, /* 24 MHz */
|
||||
{266, 24, 1, -1, -1, -1, -1}, /* 25 MHz */
|
||||
{133, 12, 1, -1, -1, -1, -1} /* 26 MHz */
|
||||
};
|
||||
|
||||
__weak const struct dpll_params *get_dpll_mpu_params(void)
|
||||
{
|
||||
return &dpll_mpu_opp100;
|
||||
}
|
||||
|
||||
const struct dpll_params *get_dpll_core_params(void)
|
||||
{
|
||||
int ind = get_sys_clk_index();
|
||||
|
||||
return &dpll_core_1000MHz[ind];
|
||||
}
|
||||
|
||||
const struct dpll_params *get_dpll_per_params(void)
|
||||
{
|
||||
int ind = get_sys_clk_index();
|
||||
|
||||
return &dpll_per_192MHz[ind];
|
||||
}
|
||||
|
||||
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))
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* clock_am43xx.c
|
||||
*
|
||||
* clocks for AM43XX based boards
|
||||
* Derived from AM33XX based boards
|
||||
*
|
||||
* Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void rtc_only_enable_basic_clocks(void)
|
||||
{
|
||||
u32 *const clk_domains[] = {
|
||||
&cmper->emifclkstctrl,
|
||||
0
|
||||
};
|
||||
|
||||
u32 *const clk_modules_explicit_en[] = {
|
||||
&cmper->gpio5clkctrl,
|
||||
&cmper->emiffwclkctrl,
|
||||
&cmper->emifclkctrl,
|
||||
&cmper->otfaemifclkctrl,
|
||||
0
|
||||
};
|
||||
|
||||
do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
|
||||
|
||||
/* Select the Master osc clk as Timer2 clock source */
|
||||
writel(0x1, &cmdpll->clktimer2clk);
|
||||
}
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,409 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* clock_ti814x.c
|
||||
*
|
||||
* Clocks for TI814X based boards
|
||||
*
|
||||
* Copyright (C) 2013, Texas Instruments, Incorporated
|
||||
*/
|
||||
|
||||
#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)
|
||||
;
|
||||
}
|
||||
|
||||
void setup_early_clocks(void)
|
||||
{
|
||||
setup_clocks_for_console();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* 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 */
|
||||
#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
|
||||
|
||||
#define CONTROL_STATUS (CTRL_BASE + 0x40)
|
||||
#define DDR_RCD (CTRL_BASE + 0x070C)
|
||||
#define CM_TIMER1_CLKSEL (PRCM_BASE + 0x390)
|
||||
#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->dmmclkctrl);
|
||||
/* Wait for dmm to be fully functional, including OCP */
|
||||
while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0)
|
||||
;
|
||||
}
|
||||
|
||||
void enable_emif_clocks(void)
|
||||
{
|
||||
writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
|
||||
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)
|
||||
;
|
||||
}
|
||||
|
||||
/* 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(1) | BIT(8)), &cmalwon->gpio0clkctrl);
|
||||
|
||||
/* Enable gpio1 */
|
||||
writel(PRCM_MOD_EN, &cmalwon->gpio1clkctrl);
|
||||
while (readl(&cmalwon->gpio1clkctrl) != PRCM_MOD_EN)
|
||||
;
|
||||
writel((BIT(1) | BIT(8)), &cmalwon->gpio1clkctrl);
|
||||
|
||||
/* 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 setup_early_clocks(void)
|
||||
{
|
||||
setup_clocks_for_console();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* DDR Configuration for AM33xx devices.
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
#ifdef CONFIG_AM43XX
|
||||
struct prm_device_inst *prm_device =
|
||||
(struct prm_device_inst *)PRM_DEVICE_INST;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
/* Wait 1ms because of L3 timeout error */
|
||||
udelay(1000);
|
||||
|
||||
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
|
||||
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
|
||||
|
||||
#ifdef CONFIG_AM43XX
|
||||
/*
|
||||
* Disable EMIF_DEVOFF
|
||||
* -> Cold Boot: This is just rewriting the default register value.
|
||||
* -> RTC Resume: Must disable DEVOFF before leveling.
|
||||
*/
|
||||
writel(0, &prm_device->emif_ctrl);
|
||||
#endif
|
||||
|
||||
/* Perform hardware leveling for DDR3 */
|
||||
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
|
||||
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);
|
||||
|
||||
/* Wait 1ms because of L3 timeout error */
|
||||
udelay(1000);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
#ifdef CONFIG_TI816X
|
||||
writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
|
||||
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);
|
||||
writel(0x0000613B, &emif_reg[nr]->emif_sdram_ref_ctrl); /* initially a large refresh period */
|
||||
writel(0x1000613B, &emif_reg[nr]->emif_sdram_ref_ctrl); /* trigger initialization */
|
||||
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
|
||||
#else
|
||||
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);
|
||||
|
||||
/* Write REG_COS_COUNT_1, REG_COS_COUNT_2, and REG_PR_OLD_COUNT. */
|
||||
if (regs->ocp_config)
|
||||
writel(regs->ocp_config, &emif_reg[nr]->emif_l3_config);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
if (regs->emif_ddr_phy_ctlr_1 & 0x00040000) {
|
||||
/* PHY_INVERT_CLKOUT = 1 */
|
||||
writel(0x00040100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
|
||||
writel(0x00040100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
|
||||
} else {
|
||||
/* PHY_INVERT_CLKOUT = 0 */
|
||||
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(0x00000077, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
|
||||
writel(0x00000077, &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 and set time between rising edge of
|
||||
* DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
|
||||
* We currently hardcode a value based on a max expected frequency
|
||||
* of 400MHz.
|
||||
*/
|
||||
writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
|
||||
&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
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* emif4.c
|
||||
*
|
||||
* AM33XX emif4 configuration file
|
||||
*
|
||||
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
static struct vtp_reg *vtpreg[2] = {
|
||||
(struct vtp_reg *)VTP0_CTRL_ADDR,
|
||||
(struct vtp_reg *)VTP1_CTRL_ADDR};
|
||||
#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_TI814X
|
||||
void config_dmm(const struct dmm_lisa_map_regs *regs)
|
||||
{
|
||||
struct dmm_lisa_map_regs *hw_lisa_map_regs =
|
||||
(struct dmm_lisa_map_regs *)DMM_BASE;
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
;
|
||||
}
|
||||
|
||||
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);
|
||||
config_vtp(nr);
|
||||
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)
|
||||
#ifndef CONFIG_SPL_RTC_DDR_SUPPORT
|
||||
/* Allow EMIF to control DDR_RESET */
|
||||
writel(0x00000000, &ddrctrl->ddrioctrl);
|
||||
#else
|
||||
/* Override EMIF DDR_RESET control */
|
||||
writel(0x80000000, &ddrctrl->ddrioctrl);
|
||||
#endif /* CONFIG_SPL_RTC_DDR_SUPPORT */
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2017 Texas Instruments, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <asm/omap_common.h>
|
||||
#include <asm/arch-am33xx/sys_proto.h>
|
||||
|
||||
#ifdef CONFIG_TI_SECURE_DEVICE
|
||||
|
||||
static void ft_hs_fixups(void *fdt, bd_t *bd)
|
||||
{
|
||||
/* Check we are running on an HS/EMU device type */
|
||||
if (GP_DEVICE != get_device_type()) {
|
||||
if ((ft_hs_disable_rng(fdt, bd) == 0) &&
|
||||
(ft_hs_fixup_dram(fdt, bd) == 0) &&
|
||||
(ft_hs_add_tee(fdt, bd) == 0))
|
||||
return;
|
||||
} else {
|
||||
printf("ERROR: Incorrect device type (GP) detected!");
|
||||
}
|
||||
/* Fixup failed or wrong device type */
|
||||
hang();
|
||||
}
|
||||
#else
|
||||
static void ft_hs_fixups(void *fdt, bd_t *bd) { }
|
||||
#endif /* #ifdef CONFIG_TI_SECURE_DEVICE */
|
||||
|
||||
/*
|
||||
* Place for general cpu/SoC FDT fixups. Board specific
|
||||
* fixups should remain in the board files which is where
|
||||
* this function should be called from.
|
||||
*/
|
||||
void ft_cpu_setup(void *fdt, bd_t *bd)
|
||||
{
|
||||
ft_hs_fixups(fdt, bd);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* HW data initialization for AM33xx.
|
||||
*
|
||||
* (C) Copyright 2017 Linaro Ltd.
|
||||
* Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*/
|
||||
|
||||
#include <asm/arch/omap.h>
|
||||
#include <asm/omap_common.h>
|
||||
|
||||
struct omap_sys_ctrl_regs const **ctrl =
|
||||
(struct omap_sys_ctrl_regs const **)OMAP_SRAM_SCRATCH_SYS_CTRL;
|
||||
|
||||
void hw_data_init(void)
|
||||
{
|
||||
*ctrl = &am33xx_ctrl;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* provide a default over-writable definition
|
||||
*/
|
||||
void __weak set_uart_mux_conf(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* provide a default over-writable definition
|
||||
*/
|
||||
void __weak set_mux_conf_regs(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* HW regs data for AM33xx.
|
||||
*
|
||||
* (C) Copyright 2017 Linaro Ltd.
|
||||
* Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*/
|
||||
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/omap_common.h>
|
||||
|
||||
struct omap_sys_ctrl_regs const am33xx_ctrl = {
|
||||
.control_status = CTRL_BASE + 0x40,
|
||||
};
|
||||
@@ -0,0 +1,214 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#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_sysboot_value(void) - return SYS_BOOT[4:0]
|
||||
*/
|
||||
u32 get_sysboot_value(void)
|
||||
{
|
||||
return readl(&cstat->statusreg) & SYSBOOT_MASK;
|
||||
}
|
||||
|
||||
u32 get_sys_clk_index(void)
|
||||
{
|
||||
struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
|
||||
u32 ind = readl(&ctrl->statusreg);
|
||||
|
||||
#ifdef CONFIG_AM43XX
|
||||
u32 src;
|
||||
src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
|
||||
if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
|
||||
return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
|
||||
CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
|
||||
else /* Value read from SYS BOOT pins */
|
||||
#endif
|
||||
return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
|
||||
CTRL_SYSBOOT_15_14_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DISPLAY_CPUINFO
|
||||
static char *cpu_revs[] = {
|
||||
"1.0",
|
||||
"2.0",
|
||||
"2.1"};
|
||||
|
||||
static char *cpu_revs_am43xx[] = {
|
||||
"1.0",
|
||||
"1.1",
|
||||
"1.2"};
|
||||
|
||||
static char *dev_types[] = {
|
||||
"TST",
|
||||
"EMU",
|
||||
"HS",
|
||||
"GP"};
|
||||
|
||||
/**
|
||||
* Print CPU information
|
||||
*/
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
char *cpu_s, *sec_s, *rev_s;
|
||||
char **cpu_rev_arr = cpu_revs;
|
||||
|
||||
switch (get_cpu_type()) {
|
||||
case AM335X:
|
||||
cpu_s = "AM335X";
|
||||
break;
|
||||
case TI81XX:
|
||||
cpu_s = "TI81XX";
|
||||
break;
|
||||
case AM437X:
|
||||
cpu_s = "AM437X";
|
||||
cpu_rev_arr = cpu_revs_am43xx;
|
||||
break;
|
||||
default:
|
||||
cpu_s = "Unknown CPU type";
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
|
||||
rev_s = cpu_rev_arr[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("CPU : %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 == 0) {
|
||||
/* No efuse in PG 1.0. Use max speed */
|
||||
return MPUPLL_M_720;
|
||||
} else if (sil_rev >= 1) {
|
||||
/* Check what the efuse says our max speed is. */
|
||||
int efuse_arm_mpu_max_freq, package_type;
|
||||
efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
|
||||
package_type = (efuse_arm_mpu_max_freq & PACKAGE_TYPE_MASK) >>
|
||||
PACKAGE_TYPE_SHIFT;
|
||||
|
||||
/* PG 2.0, efuse may not be set. */
|
||||
if (package_type == PACKAGE_TYPE_UNDEFINED || package_type ==
|
||||
PACKAGE_TYPE_RESERVED)
|
||||
return MPUPLL_M_800;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* unknown, use the PG1.0 max */
|
||||
return MPUPLL_M_720;
|
||||
}
|
||||
|
||||
int am335x_get_mpu_vdd(int sil_rev, int frequency)
|
||||
{
|
||||
int sel_mask = am335x_get_tps65910_mpu_vdd(sil_rev, frequency);
|
||||
|
||||
switch (sel_mask) {
|
||||
case TPS65910_OP_REG_SEL_1_3_2_5:
|
||||
return 1325000;
|
||||
case TPS65910_OP_REG_SEL_1_2_0:
|
||||
return 1200000;
|
||||
case TPS65910_OP_REG_SEL_1_1_0:
|
||||
return 1100000;
|
||||
default:
|
||||
return 1262500;
|
||||
}
|
||||
}
|
||||
|
||||
int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
|
||||
{
|
||||
/* For PG2.0 and later, we have one set of values. */
|
||||
if (sil_rev >= 1) {
|
||||
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_500:
|
||||
case MPUPLL_M_300:
|
||||
return TPS65910_OP_REG_SEL_1_1_0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Default to PG1.0 values. */
|
||||
return TPS65910_OP_REG_SEL_1_2_6;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* ti816x_emif4.c
|
||||
*
|
||||
* TI816x emif4 configuration file
|
||||
*
|
||||
* Copyright (C) 2017, Konsulko Group
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
/*********************************************************************
|
||||
* Init DDR3 on TI816X EVM
|
||||
*********************************************************************/
|
||||
static void ddr_init_settings(const struct cmd_control *ctrl, int emif)
|
||||
{
|
||||
/*
|
||||
* setup use_rank_delays to 1. This is only necessary when
|
||||
* multiple ranks are in use. Though the EVM does not have
|
||||
* multiple ranks, this is a good value to set.
|
||||
*/
|
||||
writel(1, DDRPHY_CONFIG_BASE + 0x134); // DATA0_REG_PHY_USE_RANK0_DELAYS
|
||||
writel(1, DDRPHY_CONFIG_BASE + 0x1d8); // DATA1_REG_PHY_USE_RANK0_DELAYS
|
||||
writel(1, DDRPHY_CONFIG_BASE + 0x27c); // DATA2_REG_PHY_USE_RANK0_DELAYS
|
||||
writel(1, DDRPHY_CONFIG_BASE + 0x320); // DATA3_REG_PHY_USE_RANK0_DELAYS
|
||||
|
||||
config_cmd_ctrl(ctrl, emif);
|
||||
|
||||
/* for ddr3 this needs to be set to 1 */
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x0F8); /* init mode */
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x104);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x19C);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x1A8);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x240);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x24C);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x2E4);
|
||||
writel(0x1, DDRPHY_CONFIG_BASE + 0x2F0);
|
||||
|
||||
/*
|
||||
* This represents the initial value for the leveling process. The
|
||||
* value is a ratio - so 0x100 represents one cycle. The real delay
|
||||
* is determined through the leveling process.
|
||||
*
|
||||
* During the leveling process, 0x20 is subtracted from the value, so
|
||||
* we have added that to the value we want to set. We also set the
|
||||
* values such that byte3 completes leveling after byte2 and byte1
|
||||
* after byte0.
|
||||
*/
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x0F0); /* data0 writelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x0F4); /* */
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x194); /* data1 writelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x198); /* */
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x238); /* data2 writelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x23c); /* */
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x2dc); /* data3 writelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x2e0); /* */
|
||||
|
||||
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x0FC); /* data0 gatelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x100);
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x1A0); /* data1 gatelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x1A4);
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x244); /* data2 gatelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x248);
|
||||
writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x2E8); /* data3 gatelvl init ratio */
|
||||
writel(0x0, DDRPHY_CONFIG_BASE + 0x2EC);
|
||||
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x00C); /* cmd0 io config - output impedance of pad */
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x010); /* cmd0 io clk config - output impedance of pad */
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x040); /* cmd1 io config - output impedance of pad */
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x044); /* cmd1 io clk config - output impedance of pad */
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x074); /* cmd2 io config - output impedance of pad */
|
||||
writel(0x5, DDRPHY_CONFIG_BASE + 0x078); /* cmd2 io clk config - output impedance of pad */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x0A8); /* data0 io config - output impedance of pad */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x0AC); /* data0 io clk config - output impedance of pad */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x14C); /* data1 io config - output impedance of pa */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x150); /* data1 io clk config - output impedance of pad */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x1F0); /* data2 io config - output impedance of pa */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x1F4); /* data2 io clk config - output impedance of pad */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x294); /* data3 io config - output impedance of pa */
|
||||
writel(0x4, DDRPHY_CONFIG_BASE + 0x298); /* data3 io clk config - output impedance of pad */
|
||||
}
|
||||
|
||||
static void ddr3_sw_levelling(const struct ddr_data *data, int emif)
|
||||
{
|
||||
/* Set the correct value to DDR_VTP_CTRL_0 */
|
||||
writel(0x6, (DDRPHY_CONFIG_BASE + 0x358));
|
||||
|
||||
writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x108));
|
||||
writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x1AC));
|
||||
writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x250));
|
||||
writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x2F4));
|
||||
|
||||
writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x0DC));
|
||||
writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x180));
|
||||
writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x224));
|
||||
writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x2C8));
|
||||
|
||||
writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x120));
|
||||
writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x1C4));
|
||||
writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x268));
|
||||
writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x30C));
|
||||
|
||||
writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x0C8));
|
||||
writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x16C));
|
||||
writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x210));
|
||||
writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x2B4));
|
||||
}
|
||||
|
||||
static struct dmm_lisa_map_regs *hw_lisa_map_regs =
|
||||
(struct dmm_lisa_map_regs *)DMM_BASE;
|
||||
|
||||
#define DMM_PAT_BASE_ADDR (DMM_BASE + 0x420)
|
||||
void config_dmm(const struct dmm_lisa_map_regs *regs)
|
||||
{
|
||||
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);
|
||||
|
||||
/* Enable Tiled Access */
|
||||
writel(0x80000000, DMM_PAT_BASE_ADDR);
|
||||
}
|
||||
|
||||
void config_ddr(const struct ddr_data *data, const struct cmd_control *ctrl,
|
||||
const struct emif_regs *regs,
|
||||
const struct dmm_lisa_map_regs *lisa_regs, int nrs)
|
||||
{
|
||||
int i;
|
||||
|
||||
enable_emif_clocks();
|
||||
|
||||
for (i = 0; i < nrs; i++)
|
||||
ddr_init_settings(ctrl, i);
|
||||
|
||||
enable_dmm_clocks();
|
||||
|
||||
/* Program the DMM to for non-interleaved configuration */
|
||||
config_dmm(lisa_regs);
|
||||
|
||||
/* Program EMIF CFG Registers */
|
||||
for (i = 0; i < nrs; i++) {
|
||||
set_sdram_timings(regs, i);
|
||||
config_sdram(regs, i);
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
for (i = 0; i < nrs; i++)
|
||||
ddr3_sw_levelling(data, i);
|
||||
|
||||
udelay(50000); /* Some delay needed */
|
||||
}
|
||||
Reference in New Issue
Block a user