GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,48 @@
if ARCH_KEYSTONE
choice
prompt "TI Keystone board select"
optional
config TARGET_K2HK_EVM
bool "TI Keystone 2 Kepler/Hawking EVM"
select SPL_BOARD_INIT if SPL
select CMD_DDR3
imply DM_I2C
imply SOC_TI
imply TI_KEYSTONE_SERDES
config TARGET_K2E_EVM
bool "TI Keystone 2 Edison EVM"
select SPL_BOARD_INIT if SPL
select CMD_DDR3
imply DM_I2C
imply SOC_TI
imply TI_KEYSTONE_SERDES
config TARGET_K2L_EVM
bool "TI Keystone 2 Lamar EVM"
select SPL_BOARD_INIT if SPL
select CMD_DDR3
imply DM_I2C
imply SOC_TI
imply TI_KEYSTONE_SERDES
config TARGET_K2G_EVM
bool "TI Keystone 2 Galileo EVM"
select BOARD_LATE_INIT
select SPL_BOARD_INIT if SPL
select TI_I2C_BOARD_DETECT
select CMD_DDR3
imply DM_I2C
imply SOC_TI
imply TI_KEYSTONE_SERDES
endchoice
config SYS_SOC
default "keystone"
source "board/ti/ks2_evm/Kconfig"
endif
@@ -0,0 +1,21 @@
#
# (C) Copyright 2012-2014
# Texas Instruments Incorporated, <www.ti.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += init.o
obj-y += psc.o
obj-y += clock.o
obj-y += mon.o
ifndef CONFIG_SPL_BUILD
obj-y += cmd_clock.o
obj-y += cmd_mon.o
obj-y += cmd_poweroff.o
endif
obj-y += msmc.o
obj-y += ddr3.o
obj-y += keystone.o
obj-$(CONFIG_TARGET_K2E_EVM) += ddr3_spd.o
obj-$(CONFIG_TARGET_K2HK_EVM) += ddr3_spd.o
@@ -0,0 +1,420 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone2: pll initialization
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <asm/arch/clock.h>
#include <asm/arch/clock_defs.h>
/* DEV and ARM speed definitions as specified in DEVSPEED register */
int __weak speeds[DEVSPEED_NUMSPDS] = {
SPD1000,
SPD1200,
SPD1350,
SPD1400,
SPD1500,
SPD1400,
SPD1350,
SPD1200,
SPD1000,
SPD800,
};
const struct keystone_pll_regs keystone_pll_regs[] = {
[CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
[PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
[TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1},
[DDR3A_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
[DDR3B_PLL] = {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1},
[UART_PLL] = {KS2_UARTPLLCTL0, KS2_UARTPLLCTL1},
};
inline void pll_pa_clk_sel(void)
{
setbits_le32(keystone_pll_regs[PASS_PLL].reg1, CFG_PLLCTL1_PAPLL_MASK);
}
static void wait_for_completion(const struct pll_init_data *data)
{
int i;
for (i = 0; i < 100; i++) {
sdelay(450);
if (!(pllctl_reg_read(data->pll, stat) & PLLSTAT_GOSTAT_MASK))
break;
}
}
static inline void bypass_main_pll(const struct pll_init_data *data)
{
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC_MASK |
PLLCTL_PLLEN_MASK);
/* 4 cycles of reference clock CLKIN*/
sdelay(340);
}
static void configure_mult_div(const struct pll_init_data *data)
{
u32 pllm, plld, bwadj;
pllm = data->pll_m - 1;
plld = (data->pll_d - 1) & CFG_PLLCTL0_PLLD_MASK;
/* Program Multiplier */
if (data->pll == MAIN_PLL)
pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);
clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_PLLM_MASK,
pllm << CFG_PLLCTL0_PLLM_SHIFT);
/* Program BWADJ */
bwadj = (data->pll_m - 1) >> 1; /* Divide pllm by 2 */
clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_BWADJ_MASK,
(bwadj << CFG_PLLCTL0_BWADJ_SHIFT) &
CFG_PLLCTL0_BWADJ_MASK);
bwadj = bwadj >> CFG_PLLCTL0_BWADJ_BITS;
clrsetbits_le32(keystone_pll_regs[data->pll].reg1,
CFG_PLLCTL1_BWADJ_MASK, bwadj);
/* Program Divider */
clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_PLLD_MASK, plld);
}
void configure_main_pll(const struct pll_init_data *data)
{
u32 tmp, pllod, i, alnctl_val = 0;
u32 *offset;
pllod = data->pll_od - 1;
/* 100 micro sec for stabilization */
sdelay(210000);
tmp = pllctl_reg_read(data->pll, secctl);
/* Check for Bypass */
if (tmp & SECCTL_BYPASS_MASK) {
setbits_le32(keystone_pll_regs[data->pll].reg1,
CFG_PLLCTL1_ENSAT_MASK);
bypass_main_pll(data);
/* Powerdown and powerup Main Pll */
pllctl_reg_setbits(data->pll, secctl, SECCTL_BYPASS_MASK);
pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
/* 5 micro sec */
sdelay(21000);
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
} else {
bypass_main_pll(data);
}
configure_mult_div(data);
/* Program Output Divider */
pllctl_reg_rmw(data->pll, secctl, SECCTL_OP_DIV_MASK,
((pllod << SECCTL_OP_DIV_SHIFT) & SECCTL_OP_DIV_MASK));
/* Program PLLDIVn */
wait_for_completion(data);
for (i = 0; i < PLLDIV_MAX; i++) {
if (i < 3)
offset = pllctl_reg(data->pll, div1) + i;
else
offset = pllctl_reg(data->pll, div4) + (i - 3);
if (divn_val[i] != -1) {
__raw_writel(divn_val[i] | PLLDIV_ENABLE_MASK, offset);
alnctl_val |= BIT(i);
}
}
if (alnctl_val) {
pllctl_reg_setbits(data->pll, alnctl, alnctl_val);
/*
* Set GOSET bit in PLLCMD to initiate the GO operation
* to change the divide
*/
pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GOSTAT_MASK);
wait_for_completion(data);
}
/* Reset PLL */
pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
sdelay(21000); /* Wait for a minimum of 7 us*/
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
sdelay(105000); /* Wait for PLL Lock time (min 50 us) */
/* Enable PLL */
pllctl_reg_clrbits(data->pll, secctl, SECCTL_BYPASS_MASK);
pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN_MASK);
}
void configure_secondary_pll(const struct pll_init_data *data)
{
int pllod = data->pll_od - 1;
/* Enable Glitch free bypass for ARM PLL */
if (cpu_is_k2hk() && data->pll == TETRIS_PLL)
clrbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);
/* Enable Bypass mode */
setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_ENSAT_MASK);
setbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_BYPASS_MASK);
configure_mult_div(data);
/* Program Output Divider */
clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_CLKOD_MASK,
(pllod << CFG_PLLCTL0_CLKOD_SHIFT) &
CFG_PLLCTL0_CLKOD_MASK);
/* Reset PLL */
setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
/* Wait for 5 micro seconds */
sdelay(21000);
/* Select the Output of PASS PLL as input to PASS */
if (data->pll == PASS_PLL && cpu_is_k2hk())
pll_pa_clk_sel();
clrbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
/* Wait for 500 * REFCLK cucles * (PLLD + 1) */
sdelay(105000);
/* Switch to PLL mode */
clrbits_le32(keystone_pll_regs[data->pll].reg0,
CFG_PLLCTL0_BYPASS_MASK);
/* Select the Output of ARM PLL as input to ARM */
if (cpu_is_k2hk() && data->pll == TETRIS_PLL)
setbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);
}
void init_pll(const struct pll_init_data *data)
{
if (data->pll == MAIN_PLL)
configure_main_pll(data);
else
configure_secondary_pll(data);
/*
* This is required to provide a delay between multiple
* consequent PPL configurations
*/
sdelay(210000);
}
void init_plls(void)
{
struct pll_init_data *data;
int pll;
for (pll = MAIN_PLL; pll < MAX_PLL_COUNT; pll++) {
data = get_pll_init_data(pll);
if (data)
init_pll(data);
}
}
static int get_max_speed(u32 val, u32 speed_supported, int *spds)
{
int speed;
/* Left most setbit gives the speed */
for (speed = DEVSPEED_NUMSPDS; speed >= 0; speed--) {
if ((val & BIT(speed)) & speed_supported)
return spds[speed];
}
/* If no bit is set, return minimum speed */
if (cpu_is_k2g())
return SPD200;
else
return SPD800;
}
static inline u32 read_efuse_bootrom(void)
{
if (cpu_is_k2hk() && (cpu_revision() <= 1))
return __raw_readl(KS2_REV1_DEVSPEED);
else
return __raw_readl(KS2_EFUSE_BOOTROM);
}
int get_max_arm_speed(int *spds)
{
u32 armspeed = read_efuse_bootrom();
armspeed = (armspeed & DEVSPEED_ARMSPEED_MASK) >>
DEVSPEED_ARMSPEED_SHIFT;
return get_max_speed(armspeed, ARM_SUPPORTED_SPEEDS, spds);
}
int get_max_dev_speed(int *spds)
{
u32 devspeed = read_efuse_bootrom();
devspeed = (devspeed & DEVSPEED_DEVSPEED_MASK) >>
DEVSPEED_DEVSPEED_SHIFT;
return get_max_speed(devspeed, DEV_SUPPORTED_SPEEDS, spds);
}
/**
* pll_freq_get - get pll frequency
* @pll: pll identifier
*/
static unsigned long pll_freq_get(int pll)
{
unsigned long mult = 1, prediv = 1, output_div = 2;
unsigned long ret;
u32 tmp, reg;
if (pll == MAIN_PLL) {
ret = get_external_clk(sys_clk);
if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN_MASK) {
/* PLL mode */
tmp = __raw_readl(KS2_MAINPLLCTL0);
prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
mult = ((tmp & CFG_PLLCTL0_PLLM_HI_MASK) >>
CFG_PLLCTL0_PLLM_SHIFT |
(pllctl_reg_read(pll, mult) &
PLLM_MULT_LO_MASK)) + 1;
output_div = ((pllctl_reg_read(pll, secctl) &
SECCTL_OP_DIV_MASK) >>
SECCTL_OP_DIV_SHIFT) + 1;
ret = ret / prediv / output_div * mult;
}
} else {
switch (pll) {
case PASS_PLL:
ret = get_external_clk(pa_clk);
reg = KS2_PASSPLLCTL0;
break;
case TETRIS_PLL:
ret = get_external_clk(tetris_clk);
reg = KS2_ARMPLLCTL0;
break;
case DDR3A_PLL:
ret = get_external_clk(ddr3a_clk);
reg = KS2_DDR3APLLCTL0;
break;
case DDR3B_PLL:
ret = get_external_clk(ddr3b_clk);
reg = KS2_DDR3BPLLCTL0;
break;
case UART_PLL:
ret = get_external_clk(uart_clk);
reg = KS2_UARTPLLCTL0;
break;
default:
return 0;
}
tmp = __raw_readl(reg);
if (!(tmp & CFG_PLLCTL0_BYPASS_MASK)) {
/* Bypass disabled */
prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
mult = ((tmp & CFG_PLLCTL0_PLLM_MASK) >>
CFG_PLLCTL0_PLLM_SHIFT) + 1;
output_div = ((tmp & CFG_PLLCTL0_CLKOD_MASK) >>
CFG_PLLCTL0_CLKOD_SHIFT) + 1;
ret = ((ret / prediv) * mult) / output_div;
}
}
return ret;
}
unsigned long ks_clk_get_rate(unsigned int clk)
{
unsigned long freq = 0;
switch (clk) {
case core_pll_clk:
freq = pll_freq_get(CORE_PLL);
break;
case pass_pll_clk:
freq = pll_freq_get(PASS_PLL);
break;
case tetris_pll_clk:
if (!cpu_is_k2e())
freq = pll_freq_get(TETRIS_PLL);
break;
case ddr3a_pll_clk:
freq = pll_freq_get(DDR3A_PLL);
break;
case ddr3b_pll_clk:
if (cpu_is_k2hk())
freq = pll_freq_get(DDR3B_PLL);
break;
case uart_pll_clk:
if (cpu_is_k2g())
freq = pll_freq_get(UART_PLL);
break;
case sys_clk0_1_clk:
case sys_clk0_clk:
freq = pll_freq_get(CORE_PLL) / pll0div_read(1);
break;
case sys_clk1_clk:
return pll_freq_get(CORE_PLL) / pll0div_read(2);
break;
case sys_clk2_clk:
freq = pll_freq_get(CORE_PLL) / pll0div_read(3);
break;
case sys_clk3_clk:
freq = pll_freq_get(CORE_PLL) / pll0div_read(4);
break;
case sys_clk0_2_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 2;
break;
case sys_clk0_3_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 3;
break;
case sys_clk0_4_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 4;
break;
case sys_clk0_6_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 6;
break;
case sys_clk0_8_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 8;
break;
case sys_clk0_12_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 12;
break;
case sys_clk0_24_clk:
freq = ks_clk_get_rate(sys_clk0_clk) / 24;
break;
case sys_clk1_3_clk:
freq = ks_clk_get_rate(sys_clk1_clk) / 3;
break;
case sys_clk1_4_clk:
freq = ks_clk_get_rate(sys_clk1_clk) / 4;
break;
case sys_clk1_6_clk:
freq = ks_clk_get_rate(sys_clk1_clk) / 6;
break;
case sys_clk1_12_clk:
freq = ks_clk_get_rate(sys_clk1_clk) / 12;
break;
default:
break;
}
return freq;
}
@@ -0,0 +1,137 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* keystone2: commands for clocks
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <command.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clock.h>
#include <asm/arch/psc_defs.h>
struct pll_init_data cmd_pll_data = {
.pll = MAIN_PLL,
.pll_m = 16,
.pll_d = 1,
.pll_od = 2,
};
int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc != 5)
goto pll_cmd_usage;
if (strncmp(argv[1], "pa", 2) == 0)
cmd_pll_data.pll = PASS_PLL;
#ifndef CONFIG_SOC_K2E
else if (strncmp(argv[1], "arm", 3) == 0)
cmd_pll_data.pll = TETRIS_PLL;
#endif
#ifdef CONFIG_SOC_K2HK
else if (strncmp(argv[1], "ddr3a", 5) == 0)
cmd_pll_data.pll = DDR3A_PLL;
else if (strncmp(argv[1], "ddr3b", 5) == 0)
cmd_pll_data.pll = DDR3B_PLL;
#else
else if (strncmp(argv[1], "ddr3", 4) == 0)
cmd_pll_data.pll = DDR3_PLL;
#endif
else
goto pll_cmd_usage;
cmd_pll_data.pll_m = simple_strtoul(argv[2], NULL, 10);
cmd_pll_data.pll_d = simple_strtoul(argv[3], NULL, 10);
cmd_pll_data.pll_od = simple_strtoul(argv[4], NULL, 10);
printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
cmd_pll_data.pll, cmd_pll_data.pll_m,
cmd_pll_data.pll_d, cmd_pll_data.pll_od);
init_pll(&cmd_pll_data);
return 0;
pll_cmd_usage:
return cmd_usage(cmdtp);
}
U_BOOT_CMD(
pllset, 5, 0, do_pll_cmd,
"set pll multiplier and pre divider",
PLLSET_CMD_LIST " <mult> <div> <OD>\n"
);
int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int clk;
unsigned long freq;
if (argc != 2)
goto getclk_cmd_usage;
clk = simple_strtoul(argv[1], NULL, 10);
freq = ks_clk_get_rate(clk);
if (freq)
printf("clock index [%d] - frequency %lu\n", clk, freq);
else
printf("clock index [%d] Not available\n", clk);
return 0;
getclk_cmd_usage:
return cmd_usage(cmdtp);
}
U_BOOT_CMD(
getclk, 2, 0, do_getclk_cmd,
"get clock rate",
"<clk index>\n"
"The indexes for clocks:\n"
CLOCK_INDEXES_LIST
);
int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int psc_module;
int res;
if (argc != 3)
goto psc_cmd_usage;
psc_module = simple_strtoul(argv[1], NULL, 10);
if (strcmp(argv[2], "en") == 0) {
res = psc_enable_module(psc_module);
printf("psc_enable_module(%d) - %s\n", psc_module,
(res) ? "ERROR" : "OK");
return 0;
}
if (strcmp(argv[2], "di") == 0) {
res = psc_disable_module(psc_module);
printf("psc_disable_module(%d) - %s\n", psc_module,
(res) ? "ERROR" : "OK");
return 0;
}
if (strcmp(argv[2], "domain") == 0) {
res = psc_disable_domain(psc_module);
printf("psc_disable_domain(%d) - %s\n", psc_module,
(res) ? "ERROR" : "OK");
return 0;
}
psc_cmd_usage:
return cmd_usage(cmdtp);
}
U_BOOT_CMD(
psc, 3, 0, do_psc_cmd,
"<enable/disable psc module os disable domain>",
"<mod/domain index> <en|di|domain>\n"
"Intended to control Power and Sleep Controller (PSC) domains and\n"
"modules. The module or domain index exectly corresponds to ones\n"
"listed in official TRM. For instance, to enable MSMC RAM clock\n"
"domain use command: psc 14 en.\n"
);
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* K2HK: secure kernel command file
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <command.h>
#include <image.h>
#include <mach/mon.h>
asm(".arch_extension sec\n\t");
static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size;
int rcode = 0;
struct image_header *header;
u32 ecrypt_bm_addr = 0;
if (argc < 2)
return CMD_RET_USAGE;
freq = CONFIG_SYS_HZ_CLOCK;
addr = simple_strtoul(argv[1], NULL, 16);
header = (struct image_header *)addr;
if (image_get_magic(header) != IH_MAGIC) {
printf("## Please update monitor image\n");
return -EFAULT;
}
load_addr = image_get_load(header);
size = image_get_data_size(header);
memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)),
size);
if (argc >= 3)
ecrypt_bm_addr = simple_strtoul(argv[2], NULL, 16);
rcode = mon_install(load_addr, dpsc_base, freq, ecrypt_bm_addr);
printf("## installed monitor @ 0x%x, freq [%d], status %d\n",
load_addr, freq, rcode);
return 0;
}
U_BOOT_CMD(mon_install, 3, 0, do_mon_install,
"Install boot kernel at 'addr'",
""
);
static void core_spin(void)
{
while (1) {
asm volatile (
"dsb\n"
"isb\n"
"wfi\n"
);
}
}
int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
int rcode = 0, core_id, on;
void (*fn)(void);
fn = core_spin;
if (argc < 3)
return CMD_RET_USAGE;
core_id = simple_strtoul(argv[1], NULL, 16);
on = simple_strtoul(argv[2], NULL, 16);
if (on)
rcode = mon_power_on(core_id, fn);
else
rcode = mon_power_off(core_id);
if (on) {
if (!rcode)
printf("core %d powered on successfully\n", core_id);
else
printf("core %d power on failure\n", core_id);
} else {
printf("core %d powered off successfully\n", core_id);
}
return 0;
}
U_BOOT_CMD(mon_power, 3, 0, do_mon_power,
"Power On/Off secondary core",
"mon_power <coreid> <oper>\n"
"- coreid (1-3) and oper (1 - ON, 0 - OFF)\n"
""
);
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone EVM : Power off
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <command.h>
#include <asm/arch/mon.h>
#include <asm/arch/psc_defs.h>
#include <asm/arch/hardware.h>
int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
mon_power_off(0);
psc_disable_module(KS2_LPSC_TETRIS);
psc_disable_domain(KS2_TETRIS_PWR_DOMAIN);
asm volatile ("isb\n"
"dsb\n"
"wfi\n");
return 0;
}
@@ -0,0 +1,34 @@
# Copyright 2015 Texas Instruments Incorporated, <www.ti.com>
#
# Lokesh Vutla <lokeshvutla@ti.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
include $(srctree)/arch/arm/mach-omap2/config_secure.mk
ifndef CONFIG_SPL_BUILD
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
ALL-y += u-boot_HS_MLO
else
ALL-y += MLO
endif
endif
MKIMAGEFLAGS_u-boot-spl.gph = -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n SPL
spl/u-boot-spl.gph: spl/u-boot-spl.bin FORCE
$(call if_changed,mkimage)
OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
--gap-fill=0
u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE
$(call if_changed,pad_cat)
ifndef CONFIG_SPL_BUILD
MKIMAGEFLAGS_MLO = -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -n U-Boot
MLO: u-boot.bin FORCE
$(call if_changed,mkimage)
@dd if=/dev/zero bs=8 count=1 2>/dev/null >> $@
endif
@@ -0,0 +1,448 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone2: DDR3 initialization
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <asm/io.h>
#include <common.h>
#include <asm/arch/msmc.h>
#include <asm/arch/ddr3.h>
#include <asm/arch/psc_defs.h>
#include <asm/ti-common/ti-edma3.h>
#define DDR3_EDMA_BLK_SIZE_SHIFT 10
#define DDR3_EDMA_BLK_SIZE (1 << DDR3_EDMA_BLK_SIZE_SHIFT)
#define DDR3_EDMA_BCNT 0x8000
#define DDR3_EDMA_CCNT 1
#define DDR3_EDMA_XF_SIZE (DDR3_EDMA_BLK_SIZE * DDR3_EDMA_BCNT)
#define DDR3_EDMA_SLOT_NUM 1
void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
{
unsigned int tmp;
while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET)
& 0x00000001) != 0x00000001)
;
__raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET);
tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET);
tmp &= ~(phy_cfg->pgcr1_mask);
tmp |= phy_cfg->pgcr1_val;
__raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET);
__raw_writel(phy_cfg->ptr0, base + KS2_DDRPHY_PTR0_OFFSET);
__raw_writel(phy_cfg->ptr1, base + KS2_DDRPHY_PTR1_OFFSET);
__raw_writel(phy_cfg->ptr3, base + KS2_DDRPHY_PTR3_OFFSET);
__raw_writel(phy_cfg->ptr4, base + KS2_DDRPHY_PTR4_OFFSET);
tmp = __raw_readl(base + KS2_DDRPHY_DCR_OFFSET);
tmp &= ~(phy_cfg->dcr_mask);
tmp |= phy_cfg->dcr_val;
__raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET);
__raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET);
__raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET);
__raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET);
__raw_writel(phy_cfg->mr0, base + KS2_DDRPHY_MR0_OFFSET);
__raw_writel(phy_cfg->mr1, base + KS2_DDRPHY_MR1_OFFSET);
__raw_writel(phy_cfg->mr2, base + KS2_DDRPHY_MR2_OFFSET);
__raw_writel(phy_cfg->dtcr, base + KS2_DDRPHY_DTCR_OFFSET);
__raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET);
__raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET);
__raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET);
__raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET);
__raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET);
while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
;
if (cpu_is_k2g()) {
clrsetbits_le32(base + KS2_DDRPHY_DATX8_2_OFFSET,
phy_cfg->datx8_2_mask,
phy_cfg->datx8_2_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_3_OFFSET,
phy_cfg->datx8_3_mask,
phy_cfg->datx8_3_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_4_OFFSET,
phy_cfg->datx8_4_mask,
phy_cfg->datx8_4_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_5_OFFSET,
phy_cfg->datx8_5_mask,
phy_cfg->datx8_5_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_6_OFFSET,
phy_cfg->datx8_6_mask,
phy_cfg->datx8_6_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_7_OFFSET,
phy_cfg->datx8_7_mask,
phy_cfg->datx8_7_val);
clrsetbits_le32(base + KS2_DDRPHY_DATX8_8_OFFSET,
phy_cfg->datx8_8_mask,
phy_cfg->datx8_8_val);
}
__raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET);
while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
;
}
void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
{
__raw_writel(emif_cfg->sdcfg, base + KS2_DDR3_SDCFG_OFFSET);
__raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET);
__raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET);
__raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET);
__raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET);
__raw_writel(emif_cfg->zqcfg, base + KS2_DDR3_ZQCFG_OFFSET);
__raw_writel(emif_cfg->sdrfc, base + KS2_DDR3_SDRFC_OFFSET);
}
int ddr3_ecc_support_rmw(u32 base)
{
u32 value = __raw_readl(base + KS2_DDR3_MIDR_OFFSET);
/* Check the DDR3 controller ID reg if the controllers
supports ECC RMW or not */
if (value == 0x40461C02)
return 1;
return 0;
}
static void ddr3_ecc_config(u32 base, u32 value)
{
u32 data;
__raw_writel(value, base + KS2_DDR3_ECC_CTRL_OFFSET);
udelay(100000); /* delay required to synchronize across clock domains */
if (value & KS2_DDR3_ECC_EN) {
/* Clear the 1-bit error count */
data = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
__raw_writel(data, base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
/* enable the ECC interrupt */
__raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS |
KS2_DDR3_WR_ECC_ERR_SYS,
base + KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET);
/* Clear the ECC error interrupt status */
__raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS |
KS2_DDR3_WR_ECC_ERR_SYS,
base + KS2_DDR3_ECC_INT_STATUS_OFFSET);
}
}
static void ddr3_reset_data(u32 base, u32 ddr3_size)
{
u32 mpax[2];
u32 seg_num;
u32 seg, blks, dst, edma_blks;
struct edma3_slot_config slot;
struct edma3_channel_config edma_channel;
u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, };
/* Setup an edma to copy the 1k block to the entire DDR */
puts("\nClear entire DDR3 memory to enable ECC\n");
/* save the SES MPAX regs */
if (cpu_is_k2g())
msmc_get_ses_mpax(K2G_MSMC_SEGMENT_ARM, 0, mpax);
else
msmc_get_ses_mpax(K2HKLE_MSMC_SEGMENT_ARM, 0, mpax);
/* setup edma slot 1 configuration */
slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB |
EDMA3_SLOPT_COMP_CODE(0) |
EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC;
slot.bcnt = DDR3_EDMA_BCNT;
slot.acnt = DDR3_EDMA_BLK_SIZE;
slot.ccnt = DDR3_EDMA_CCNT;
slot.src_bidx = 0;
slot.dst_bidx = DDR3_EDMA_BLK_SIZE;
slot.src_cidx = 0;
slot.dst_cidx = 0;
slot.link = EDMA3_PARSET_NULL_LINK;
slot.bcntrld = 0;
edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot);
/* configure quik edma channel */
edma_channel.slot = DDR3_EDMA_SLOT_NUM;
edma_channel.chnum = 0;
edma_channel.complete_code = 0;
/* event trigger after dst update */
edma_channel.trigger_slot_word = EDMA3_TWORD(dst);
qedma3_start(KS2_EDMA0_BASE, &edma_channel);
/* DDR3 size in segments (4KB seg size) */
seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT);
for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) {
/* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF
access slave interface so that edma driver can access */
if (cpu_is_k2g()) {
msmc_map_ses_segment(K2G_MSMC_SEGMENT_ARM, 0,
base >> KS2_MSMC_SEG_SIZE_SHIFT,
KS2_MSMC_DST_SEG_BASE + seg,
MPAX_SEG_2G);
} else {
msmc_map_ses_segment(K2HKLE_MSMC_SEGMENT_ARM, 0,
base >> KS2_MSMC_SEG_SIZE_SHIFT,
KS2_MSMC_DST_SEG_BASE + seg,
MPAX_SEG_2G);
}
if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM)
edma_blks = KS2_MSMC_MAP_SEG_NUM <<
(KS2_MSMC_SEG_SIZE_SHIFT
- DDR3_EDMA_BLK_SIZE_SHIFT);
else
edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT
- DDR3_EDMA_BLK_SIZE_SHIFT);
/* Use edma driver to scrub 2GB DDR memory */
for (dst = base, blks = 0; blks < edma_blks;
blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) {
edma3_set_src_addr(KS2_EDMA0_BASE,
edma_channel.slot, (u32)edma_src);
edma3_set_dest_addr(KS2_EDMA0_BASE,
edma_channel.slot, (u32)dst);
while (edma3_check_for_transfer(KS2_EDMA0_BASE,
&edma_channel))
udelay(10);
}
}
qedma3_stop(KS2_EDMA0_BASE, &edma_channel);
/* restore the SES MPAX regs */
if (cpu_is_k2g())
msmc_set_ses_mpax(K2G_MSMC_SEGMENT_ARM, 0, mpax);
else
msmc_set_ses_mpax(K2HKLE_MSMC_SEGMENT_ARM, 0, mpax);
}
static void ddr3_ecc_init_range(u32 base)
{
u32 ecc_val = KS2_DDR3_ECC_EN;
u32 rmw = ddr3_ecc_support_rmw(base);
if (rmw)
ecc_val |= KS2_DDR3_ECC_RMW_EN;
__raw_writel(0, base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
ddr3_ecc_config(base, ecc_val);
}
void ddr3_enable_ecc(u32 base, int test)
{
u32 ecc_val = KS2_DDR3_ECC_ENABLE;
u32 rmw = ddr3_ecc_support_rmw(base);
if (test)
ecc_val |= KS2_DDR3_ECC_ADDR_RNG_1_EN;
if (!rmw) {
if (!test)
/* by default, disable ecc when rmw = 0 and no
ecc test */
ecc_val = 0;
} else {
ecc_val |= KS2_DDR3_ECC_RMW_EN;
}
ddr3_ecc_config(base, ecc_val);
}
void ddr3_disable_ecc(u32 base)
{
ddr3_ecc_config(base, 0);
}
#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L)
static void cic_init(u32 base)
{
/* Disable CIC global interrupts */
__raw_writel(0, base + KS2_CIC_GLOBAL_ENABLE);
/* Set to normal mode, no nesting, no priority hold */
__raw_writel(0, base + KS2_CIC_CTRL);
__raw_writel(0, base + KS2_CIC_HOST_CTRL);
/* Enable CIC global interrupts */
__raw_writel(1, base + KS2_CIC_GLOBAL_ENABLE);
}
static void cic_map_cic_to_gic(u32 base, u32 chan_num, u32 irq_num)
{
/* Map the system interrupt to a CIC channel */
__raw_writeb(chan_num, base + KS2_CIC_CHAN_MAP(0) + irq_num);
/* Enable CIC system interrupt */
__raw_writel(irq_num, base + KS2_CIC_SYS_ENABLE_IDX_SET);
/* Enable CIC Host interrupt */
__raw_writel(chan_num, base + KS2_CIC_HOST_ENABLE_IDX_SET);
}
static void ddr3_map_ecc_cic2_irq(u32 base)
{
cic_init(base);
cic_map_cic_to_gic(base, KS2_CIC2_DDR3_ECC_CHAN_NUM,
KS2_CIC2_DDR3_ECC_IRQ_NUM);
}
#endif
void ddr3_init_ecc(u32 base, u32 ddr3_size)
{
if (!ddr3_ecc_support_rmw(base)) {
ddr3_disable_ecc(base);
return;
}
ddr3_ecc_init_range(base);
ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size);
/* mapping DDR3 ECC system interrupt from CIC2 to GIC */
#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L)
ddr3_map_ecc_cic2_irq(KS2_CIC2_BASE);
#endif
ddr3_enable_ecc(base, 0);
}
void ddr3_check_ecc_int(u32 base)
{
char *env;
int ecc_test = 0;
u32 value = __raw_readl(base + KS2_DDR3_ECC_INT_STATUS_OFFSET);
env = env_get("ecc_test");
if (env)
ecc_test = simple_strtol(env, NULL, 0);
if (value & KS2_DDR3_WR_ECC_ERR_SYS)
puts("DDR3 ECC write error interrupted\n");
if (value & KS2_DDR3_2B_ECC_ERR_SYS) {
puts("DDR3 ECC 2-bit error interrupted\n");
if (!ecc_test) {
puts("Reseting the device ...\n");
reset_cpu(0);
}
}
value = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
if (value) {
printf("1-bit ECC err count: 0x%x\n", value);
value = __raw_readl(base +
KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET);
printf("1-bit ECC err address log: 0x%x\n", value);
}
}
void ddr3_reset_ddrphy(void)
{
u32 tmp;
/* Assert DDR3A PHY reset */
tmp = readl(KS2_DDR3APLLCTL1);
tmp |= KS2_DDR3_PLLCTRL_PHY_RESET;
writel(tmp, KS2_DDR3APLLCTL1);
/* wait 10us to catch the reset */
udelay(10);
/* Release DDR3A PHY reset */
tmp = readl(KS2_DDR3APLLCTL1);
tmp &= ~KS2_DDR3_PLLCTRL_PHY_RESET;
__raw_writel(tmp, KS2_DDR3APLLCTL1);
}
#ifdef CONFIG_SOC_K2HK
/**
* ddr3_reset_workaround - reset workaround in case if leveling error
* detected for PG 1.0 and 1.1 k2hk SoCs
*/
void ddr3_err_reset_workaround(void)
{
unsigned int tmp;
unsigned int tmp_a;
unsigned int tmp_b;
/*
* Check for PGSR0 error bits of DDR3 PHY.
* Check for WLERR, QSGERR, WLAERR,
* RDERR, WDERR, REERR, WEERR error to see if they are set or not
*/
tmp_a = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET);
tmp_b = __raw_readl(KS2_DDR3B_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET);
if (((tmp_a & 0x0FE00000) != 0) || ((tmp_b & 0x0FE00000) != 0)) {
printf("DDR Leveling Error Detected!\n");
printf("DDR3A PGSR0 = 0x%x\n", tmp_a);
printf("DDR3B PGSR0 = 0x%x\n", tmp_b);
/*
* Write Keys to KICK registers to enable writes to registers
* in boot config space
*/
__raw_writel(KS2_KICK0_MAGIC, KS2_KICK0);
__raw_writel(KS2_KICK1_MAGIC, KS2_KICK1);
/*
* Move DDR3A Module out of reset isolation by setting
* MDCTL23[12] = 0
*/
tmp_a = __raw_readl(KS2_PSC_BASE +
PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A));
tmp_a = PSC_REG_MDCTL_SET_RESET_ISO(tmp_a, 0);
__raw_writel(tmp_a, KS2_PSC_BASE +
PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A));
/*
* Move DDR3B Module out of reset isolation by setting
* MDCTL24[12] = 0
*/
tmp_b = __raw_readl(KS2_PSC_BASE +
PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B));
tmp_b = PSC_REG_MDCTL_SET_RESET_ISO(tmp_b, 0);
__raw_writel(tmp_b, KS2_PSC_BASE +
PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B));
/*
* Write 0x5A69 Key to RSTCTRL[15:0] to unlock writes
* to RSTCTRL and RSTCFG
*/
tmp = __raw_readl(KS2_RSTCTRL);
tmp &= KS2_RSTCTRL_MASK;
tmp |= KS2_RSTCTRL_KEY;
__raw_writel(tmp, KS2_RSTCTRL);
/*
* Set PLL Controller to drive hard reset on SW trigger by
* setting RSTCFG[13] = 0
*/
tmp = __raw_readl(KS2_RSTCTRL_RSCFG);
tmp &= ~KS2_RSTYPE_PLL_SOFT;
__raw_writel(tmp, KS2_RSTCTRL_RSCFG);
reset_cpu(0);
}
}
#endif
@@ -0,0 +1,469 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone2: DDR3 SPD configuration
*
* (C) Copyright 2015-2016 Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <i2c.h>
#include <ddr_spd.h>
#include <asm/arch/ddr3.h>
#include <asm/arch/hardware.h>
#define DUMP_DDR_CONFIG 0 /* set to 1 to debug */
#define debug_ddr_cfg(fmt, args...) \
debug_cond(DUMP_DDR_CONFIG, fmt, ##args)
static void dump_phy_config(struct ddr3_phy_config *ptr)
{
debug_ddr_cfg("\npllcr 0x%08X\n", ptr->pllcr);
debug_ddr_cfg("pgcr1_mask 0x%08X\n", ptr->pgcr1_mask);
debug_ddr_cfg("pgcr1_val 0x%08X\n", ptr->pgcr1_val);
debug_ddr_cfg("ptr0 0x%08X\n", ptr->ptr0);
debug_ddr_cfg("ptr1 0x%08X\n", ptr->ptr1);
debug_ddr_cfg("ptr2 0x%08X\n", ptr->ptr2);
debug_ddr_cfg("ptr3 0x%08X\n", ptr->ptr3);
debug_ddr_cfg("ptr4 0x%08X\n", ptr->ptr4);
debug_ddr_cfg("dcr_mask 0x%08X\n", ptr->dcr_mask);
debug_ddr_cfg("dcr_val 0x%08X\n", ptr->dcr_val);
debug_ddr_cfg("dtpr0 0x%08X\n", ptr->dtpr0);
debug_ddr_cfg("dtpr1 0x%08X\n", ptr->dtpr1);
debug_ddr_cfg("dtpr2 0x%08X\n", ptr->dtpr2);
debug_ddr_cfg("mr0 0x%08X\n", ptr->mr0);
debug_ddr_cfg("mr1 0x%08X\n", ptr->mr1);
debug_ddr_cfg("mr2 0x%08X\n", ptr->mr2);
debug_ddr_cfg("dtcr 0x%08X\n", ptr->dtcr);
debug_ddr_cfg("pgcr2 0x%08X\n", ptr->pgcr2);
debug_ddr_cfg("zq0cr1 0x%08X\n", ptr->zq0cr1);
debug_ddr_cfg("zq1cr1 0x%08X\n", ptr->zq1cr1);
debug_ddr_cfg("zq2cr1 0x%08X\n", ptr->zq2cr1);
debug_ddr_cfg("pir_v1 0x%08X\n", ptr->pir_v1);
debug_ddr_cfg("pir_v2 0x%08X\n\n", ptr->pir_v2);
};
static void dump_emif_config(struct ddr3_emif_config *ptr)
{
debug_ddr_cfg("\nsdcfg 0x%08X\n", ptr->sdcfg);
debug_ddr_cfg("sdtim1 0x%08X\n", ptr->sdtim1);
debug_ddr_cfg("sdtim2 0x%08X\n", ptr->sdtim2);
debug_ddr_cfg("sdtim3 0x%08X\n", ptr->sdtim3);
debug_ddr_cfg("sdtim4 0x%08X\n", ptr->sdtim4);
debug_ddr_cfg("zqcfg 0x%08X\n", ptr->zqcfg);
debug_ddr_cfg("sdrfc 0x%08X\n\n", ptr->sdrfc);
};
#define TEMP NORMAL_TEMP
#define VBUS_CLKPERIOD 1.875 /* Corresponds to vbus=533MHz, */
#define PLLGS_VAL (4000.0 / VBUS_CLKPERIOD) /* 4 us */
#define PLLPD_VAL (1000.0 / VBUS_CLKPERIOD) /* 1 us */
#define PLLLOCK_VAL (100000.0 / VBUS_CLKPERIOD) /* 100 us */
#define PLLRST_VAL (9000.0 / VBUS_CLKPERIOD) /* 9 us */
#define PHYRST_VAL 0x10
#define DDR_TERM RZQ_4_TERM
#define SDRAM_DRIVE RZQ_7_IMP
#define DYN_ODT ODT_DISABLE
enum srt {
NORMAL_TEMP,
EXTENDED_TEMP
};
enum out_impedance {
RZQ_6_IMP = 0,
RZQ_7_IMP
};
enum die_term {
ODT_DISABLE = 0,
RZQ_4_TERM,
RZQ_2_TERM,
RZQ_6_TERM,
RZQ_12_TERM,
RZQ_8_TERM
};
struct ddr3_sodimm {
u32 t_ck;
u32 freqsel;
u32 t_xp;
u32 t_cke;
u32 t_pllpd;
u32 t_pllgs;
u32 t_phyrst;
u32 t_plllock;
u32 t_pllrst;
u32 t_rfc;
u32 t_xs;
u32 t_dinit0;
u32 t_dinit1;
u32 t_dinit2;
u32 t_dinit3;
u32 t_rtp;
u32 t_wtr;
u32 t_rp;
u32 t_rcd;
u32 t_ras;
u32 t_rrd;
u32 t_rc;
u32 t_faw;
u32 t_mrd;
u32 t_mod;
u32 t_wlo;
u32 t_wlmrd;
u32 t_xsdll;
u32 t_xpdll;
u32 t_ckesr;
u32 t_dllk;
u32 t_wr;
u32 t_wr_bin;
u32 cas;
u32 cwl;
u32 asr;
u32 pasr;
u32 t_refprd;
u8 sdram_type;
u8 ibank;
u8 pagesize;
u8 t_rrd2;
u8 t_ras_max;
u8 t_zqcs;
u32 refresh_rate;
u8 t_csta;
u8 rank;
u8 mirrored;
u8 buswidth;
};
static u8 cas_latancy(u16 temp)
{
int loop;
u8 cas_bin = 0;
for (loop = 0; loop < 32; loop += 2, temp >>= 1) {
if (temp & 0x0001)
cas_bin = (loop > 15) ? loop - 15 : loop;
}
return cas_bin;
}
static int ddr3_get_size_in_mb(ddr3_spd_eeprom_t *buf)
{
return (((buf->organization & 0x38) >> 3) + 1) *
(256 << (buf->density_banks & 0xf));
}
static int ddrtimingcalculation(ddr3_spd_eeprom_t *buf, struct ddr3_sodimm *spd,
struct ddr3_spd_cb *spd_cb)
{
u32 mtb, clk_freq;
if ((buf->mem_type != 0x0b) ||
((buf->density_banks & 0x70) != 0x00))
return 1;
spd->sdram_type = 0x03;
spd->ibank = 0x03;
mtb = buf->mtb_dividend * 1000 / buf->mtb_divisor;
spd->t_ck = buf->tck_min * mtb;
spd_cb->ddrspdclock = 2000000 / spd->t_ck;
clk_freq = spd_cb->ddrspdclock / 2;
spd->rank = ((buf->organization & 0x38) >> 3) + 1;
if (spd->rank > 2)
return 1;
spd->pagesize = (buf->addressing & 0x07) + 1;
if (spd->pagesize > 3)
return 1;
spd->buswidth = 8 << (buf->bus_width & 0x7);
if ((spd->buswidth < 16) || (spd->buswidth > 64))
return 1;
spd->mirrored = buf->mod_section.unbuffered.addr_mapping & 1;
printf("DDR3A Speed will be configured for %d Operation.\n",
spd_cb->ddrspdclock);
if (spd_cb->ddrspdclock == 1333) {
spd->t_xp = ((3 * spd->t_ck) > 6000) ?
3 : ((5999 / spd->t_ck) + 1);
spd->t_cke = ((3 * spd->t_ck) > 5625) ?
3 : ((5624 / spd->t_ck) + 1);
} else if (spd_cb->ddrspdclock == 1600) {
spd->t_xp = ((3 * spd->t_ck) > 6000) ?
3 : ((5999 / spd->t_ck) + 1);
spd->t_cke = ((3 * spd->t_ck) > 5000) ?
3 : ((4999 / spd->t_ck) + 1);
} else {
printf("Unsupported DDR3 speed %d\n", spd_cb->ddrspdclock);
return 1;
}
spd->t_xpdll = (spd->t_ck > 2400) ? 10 : 24000 / spd->t_ck;
spd->t_ckesr = spd->t_cke + 1;
/* SPD Calculated Values */
spd->cas = cas_latancy((buf->caslat_msb << 8) |
buf->caslat_lsb);
spd->t_wr = (buf->twr_min * mtb) / spd->t_ck;
spd->t_wr_bin = (spd->t_wr / 2) & 0x07;
spd->t_rcd = ((buf->trcd_min * mtb) - 1) / spd->t_ck + 1;
spd->t_rrd = ((buf->trrd_min * mtb) - 1) / spd->t_ck + 1;
spd->t_rp = (((buf->trp_min * mtb) - 1) / spd->t_ck) + 1;
spd->t_ras = (((buf->tras_trc_ext & 0x0f) << 8 | buf->tras_min_lsb) *
mtb) / spd->t_ck;
spd->t_rc = (((((buf->tras_trc_ext & 0xf0) << 4) | buf->trc_min_lsb) *
mtb) - 1) / spd->t_ck + 1;
spd->t_rfc = (buf->trfc_min_lsb | (buf->trfc_min_msb << 8)) * mtb /
1000;
spd->t_wtr = (buf->twtr_min * mtb) / spd->t_ck;
spd->t_rtp = (buf->trtp_min * mtb) / spd->t_ck;
spd->t_xs = (((spd->t_rfc + 10) * 1000) / spd->t_ck);
spd->t_rfc = ((spd->t_rfc * 1000) - 1) / spd->t_ck + 1;
spd->t_faw = (((buf->tfaw_msb << 8) | buf->tfaw_min) * mtb) / spd->t_ck;
spd->t_rrd2 = ((((buf->tfaw_msb << 8) |
buf->tfaw_min) * mtb) / (4 * spd->t_ck)) - 1;
/* Hard-coded values */
spd->t_mrd = 0x00;
spd->t_mod = 0x00;
spd->t_wlo = 0x0C;
spd->t_wlmrd = 0x28;
spd->t_xsdll = 0x200;
spd->t_ras_max = 0x0F;
spd->t_csta = 0x05;
spd->t_dllk = 0x200;
/* CAS Write Latency */
if (spd->t_ck >= 2500)
spd->cwl = 0;
else if (spd->t_ck >= 1875)
spd->cwl = 1;
else if (spd->t_ck >= 1500)
spd->cwl = 2;
else if (spd->t_ck >= 1250)
spd->cwl = 3;
else if (spd->t_ck >= 1071)
spd->cwl = 4;
else
spd->cwl = 5;
/* SD:RAM Thermal and Refresh Options */
spd->asr = (buf->therm_ref_opt & 0x04) >> 2;
spd->pasr = (buf->therm_ref_opt & 0x80) >> 7;
spd->t_zqcs = 64;
spd->t_refprd = (TEMP == NORMAL_TEMP) ? 7812500 : 3906250;
spd->t_refprd = spd->t_refprd / spd->t_ck;
spd->refresh_rate = spd->t_refprd;
spd->t_refprd = spd->t_refprd * 5;
/* Set MISC PHY space registers fields */
if ((clk_freq / 2) >= 166 && (clk_freq / 2 < 275))
spd->freqsel = 0x03;
else if ((clk_freq / 2) > 225 && (clk_freq / 2 < 385))
spd->freqsel = 0x01;
else if ((clk_freq / 2) > 335 && (clk_freq / 2 < 534))
spd->freqsel = 0x00;
spd->t_dinit0 = 500000000 / spd->t_ck; /* CKE low time 500 us */
spd->t_dinit1 = spd->t_xs;
spd->t_dinit2 = 200000000 / spd->t_ck; /* Reset low time 200 us */
/* Time from ZQ initialization command to first command (1 us) */
spd->t_dinit3 = 1000000 / spd->t_ck;
spd->t_pllgs = PLLGS_VAL + 1;
spd->t_pllpd = PLLPD_VAL + 1;
spd->t_plllock = PLLLOCK_VAL + 1;
spd->t_pllrst = PLLRST_VAL;
spd->t_phyrst = PHYRST_VAL;
spd_cb->ddr_size_gbyte = ddr3_get_size_in_mb(buf) / 1024;
return 0;
}
static void init_ddr3param(struct ddr3_spd_cb *spd_cb,
struct ddr3_sodimm *spd)
{
spd_cb->phy_cfg.pllcr = (spd->freqsel & 3) << 18 | 0xE << 13;
spd_cb->phy_cfg.pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK);
spd_cb->phy_cfg.pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23));
spd_cb->phy_cfg.ptr0 = ((spd->t_pllpd & 0x7ff) << 21) |
((spd->t_pllgs & 0x7fff) << 6) | (spd->t_phyrst & 0x3f);
spd_cb->phy_cfg.ptr1 = ((spd->t_plllock & 0xffff) << 16) |
(spd->t_pllrst & 0x1fff);
spd_cb->phy_cfg.ptr2 = 0;
spd_cb->phy_cfg.ptr3 = ((spd->t_dinit1 & 0x1ff) << 20) |
(spd->t_dinit0 & 0xfffff);
spd_cb->phy_cfg.ptr4 = ((spd->t_dinit3 & 0x3ff) << 18) |
(spd->t_dinit2 & 0x3ffff);
spd_cb->phy_cfg.dcr_mask = PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK;
spd_cb->phy_cfg.dcr_val = 1 << 10;
if (spd->mirrored) {
spd_cb->phy_cfg.dcr_mask |= NOSRA_MASK | UDIMM_MASK;
spd_cb->phy_cfg.dcr_val |= (1 << 27) | (1 << 29);
}
spd_cb->phy_cfg.dtpr0 = (spd->t_rc & 0x3f) << 26 |
(spd->t_rrd & 0xf) << 22 |
(spd->t_ras & 0x3f) << 16 | (spd->t_rcd & 0xf) << 12 |
(spd->t_rp & 0xf) << 8 | (spd->t_wtr & 0xf) << 4 |
(spd->t_rtp & 0xf);
spd_cb->phy_cfg.dtpr1 = (spd->t_wlo & 0xf) << 26 |
(spd->t_wlmrd & 0x3f) << 20 | (spd->t_rfc & 0x1ff) << 11 |
(spd->t_faw & 0x3f) << 5 | (spd->t_mod & 0x7) << 2 |
(spd->t_mrd & 0x3);
spd_cb->phy_cfg.dtpr2 = 0 << 31 | 1 << 30 | 0 << 29 |
(spd->t_dllk & 0x3ff) << 19 | (spd->t_ckesr & 0xf) << 15;
spd_cb->phy_cfg.dtpr2 |= (((spd->t_xp > spd->t_xpdll) ?
spd->t_xp : spd->t_xpdll) &
0x1f) << 10;
spd_cb->phy_cfg.dtpr2 |= (((spd->t_xs > spd->t_xsdll) ?
spd->t_xs : spd->t_xsdll) &
0x3ff);
spd_cb->phy_cfg.mr0 = 1 << 12 | (spd->t_wr_bin & 0x7) << 9 | 0 << 8 |
0 << 7 | ((spd->cas & 0x0E) >> 1) << 4 | 0 << 3 |
(spd->cas & 0x01) << 2;
spd_cb->phy_cfg.mr1 = 0 << 12 | 0 << 11 | 0 << 7 | 0 << 3 |
((DDR_TERM >> 2) & 1) << 9 | ((DDR_TERM >> 1) & 1) << 6 |
(DDR_TERM & 0x1) << 2 | ((SDRAM_DRIVE >> 1) & 1) << 5 |
(SDRAM_DRIVE & 1) << 1 | 0 << 0;
spd_cb->phy_cfg.mr2 = DYN_ODT << 9 | TEMP << 7 | (spd->asr & 1) << 6 |
(spd->cwl & 7) << 3 | (spd->pasr & 7);
spd_cb->phy_cfg.dtcr = (spd->rank == 2) ? 0x730035C7 : 0x710035C7;
spd_cb->phy_cfg.pgcr2 = (0xF << 20) | ((int)spd->t_refprd & 0x3ffff);
spd_cb->phy_cfg.zq0cr1 = 0x0000005D;
spd_cb->phy_cfg.zq1cr1 = 0x0000005B;
spd_cb->phy_cfg.zq2cr1 = 0x0000005B;
spd_cb->phy_cfg.pir_v1 = 0x00000033;
spd_cb->phy_cfg.pir_v2 = 0x0000FF81;
/* EMIF Registers */
spd_cb->emif_cfg.sdcfg = spd->sdram_type << 29 | (DDR_TERM & 7) << 25 |
(DYN_ODT & 3) << 22 | (spd->cwl & 0x7) << 14 |
(spd->cas & 0xf) << 8 | (spd->ibank & 3) << 5 |
(spd->buswidth & 3) << 12 | (spd->pagesize & 3);
if (spd->rank == 2)
spd_cb->emif_cfg.sdcfg |= 1 << 3;
spd_cb->emif_cfg.sdtim1 = ((spd->t_wr - 1) & 0x1f) << 25 |
((spd->t_ras - 1) & 0x7f) << 18 |
((spd->t_rc - 1) & 0xff) << 10 |
(spd->t_rrd2 & 0x3f) << 4 |
((spd->t_wtr - 1) & 0xf);
spd_cb->emif_cfg.sdtim2 = 0x07 << 10 | ((spd->t_rp - 1) & 0x1f) << 5 |
((spd->t_rcd - 1) & 0x1f);
spd_cb->emif_cfg.sdtim3 = ((spd->t_xp - 2) & 0xf) << 28 |
((spd->t_xs - 1) & 0x3ff) << 18 |
((spd->t_xsdll - 1) & 0x3ff) << 8 |
((spd->t_rtp - 1) & 0xf) << 4 | ((spd->t_cke) & 0xf);
spd_cb->emif_cfg.sdtim4 = (spd->t_csta & 0xf) << 28 |
((spd->t_ckesr - 1) & 0xf) << 24 |
((spd->t_zqcs - 1) & 0xff) << 16 |
((spd->t_rfc - 1) & 0x3ff) << 4 |
(spd->t_ras_max & 0xf);
spd_cb->emif_cfg.sdrfc = (spd->refresh_rate - 1) & 0xffff;
/* TODO zqcfg value fixed ,May be required correction for K2E evm. */
spd_cb->emif_cfg.zqcfg = (spd->rank == 2) ? 0xF0073200 : 0x70073200;
}
static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
{
int ret;
#ifndef CONFIG_DM_I2C
int old_bus;
i2c_init(CONFIG_SYS_DAVINCI_I2C_SPEED, CONFIG_SYS_DAVINCI_I2C_SLAVE);
old_bus = i2c_get_bus_num();
i2c_set_bus_num(1);
ret = i2c_read(0x53, 0, 1, (unsigned char *)spd_params, 256);
i2c_set_bus_num(old_bus);
#else
struct udevice *dev;
ret = i2c_get_chip_for_busnum(1, 0x53, 1, &dev);
if (!ret)
ret = dm_i2c_read(dev, 0, (unsigned char *)spd_params, 256);
#endif
if (ret) {
printf("Cannot read DIMM params\n");
return 1;
}
if (ddr3_spd_check(spd_params))
return 1;
return 0;
}
int ddr3_get_size(void)
{
ddr3_spd_eeprom_t spd_params;
if (ddr3_read_spd(&spd_params))
return 0;
return ddr3_get_size_in_mb(&spd_params) / 1024;
}
int ddr3_get_dimm_params_from_spd(struct ddr3_spd_cb *spd_cb)
{
struct ddr3_sodimm spd;
ddr3_spd_eeprom_t spd_params;
memset(&spd, 0, sizeof(spd));
if (ddr3_read_spd(&spd_params))
return 1;
if (ddrtimingcalculation(&spd_params, &spd, spd_cb)) {
printf("Timing caclulation error\n");
return 1;
}
strncpy(spd_cb->dimm_name, (char *)spd_params.mpart, 18);
spd_cb->dimm_name[18] = '\0';
init_ddr3param(spd_cb, &spd);
dump_emif_config(&spd_cb->emif_cfg);
dump_phy_config(&spd_cb->phy_cfg);
return 0;
}
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2E: Clock management APIs
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_CLOCK_K2E_H
#define __ASM_ARCH_CLOCK_K2E_H
#define PLLSET_CMD_LIST "<pa|ddr3>"
#define KS2_CLK1_6 sys_clk0_6_clk
#define CORE_PLL_800 {CORE_PLL, 16, 1, 2}
#define CORE_PLL_850 {CORE_PLL, 17, 1, 2}
#define CORE_PLL_1000 {CORE_PLL, 20, 1, 2}
#define CORE_PLL_1200 {CORE_PLL, 24, 1, 2}
#define PASS_PLL_1000 {PASS_PLL, 20, 1, 2}
#define CORE_PLL_1250 {CORE_PLL, 25, 1, 2}
#define CORE_PLL_1350 {CORE_PLL, 27, 1, 2}
#define CORE_PLL_1400 {CORE_PLL, 28, 1, 2}
#define CORE_PLL_1500 {CORE_PLL, 30, 1, 2}
#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2}
#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4}
#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2}
#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6}
/* k2e DEV supports 800, 850, 1000, 1250, 1350, 1400, 1500 MHz */
#define DEV_SUPPORTED_SPEEDS 0xFFF
#define ARM_SUPPORTED_SPEEDS 0
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2G: Clock data
*
* (C) Copyright 2015
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_CLOCK_K2G_H
#define __ASM_ARCH_CLOCK_K2G_H
#define PLLSET_CMD_LIST "<pa|arm|ddr3>"
#define DEV_SUPPORTED_SPEEDS 0xff
#define ARM_SUPPORTED_SPEEDS 0x3ff
#define KS2_CLK1_6 sys_clk0_6_clk
#endif
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2HK: Clock management APIs
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_CLOCK_K2HK_H
#define __ASM_ARCH_CLOCK_K2HK_H
#define PLLSET_CMD_LIST "<pa|arm|ddr3a|ddr3b>"
#define KS2_CLK1_6 sys_clk0_6_clk
#define CORE_PLL_799 {CORE_PLL, 13, 1, 2}
#define CORE_PLL_983 {CORE_PLL, 16, 1, 2}
#define CORE_PLL_999 {CORE_PLL, 122, 15, 1}
#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2}
#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2}
#define CORE_PLL_1200 {CORE_PLL, 625, 32, 2}
#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2}
#define PASS_PLL_983 {PASS_PLL, 16, 1, 2}
#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2}
#define TETRIS_PLL_500 {TETRIS_PLL, 8, 1, 2}
#define TETRIS_PLL_750 {TETRIS_PLL, 12, 1, 2}
#define TETRIS_PLL_800 {TETRIS_PLL, 32, 5, 1}
#define TETRIS_PLL_687 {TETRIS_PLL, 11, 1, 2}
#define TETRIS_PLL_625 {TETRIS_PLL, 10, 1, 2}
#define TETRIS_PLL_812 {TETRIS_PLL, 13, 1, 2}
#define TETRIS_PLL_875 {TETRIS_PLL, 14, 1, 2}
#define TETRIS_PLL_1000 {TETRIS_PLL, 40, 5, 1}
#define TETRIS_PLL_1188 {TETRIS_PLL, 19, 2, 1}
#define TETRIS_PLL_1200 {TETRIS_PLL, 48, 5, 1}
#define TETRIS_PLL_1350 {TETRIS_PLL, 54, 5, 1}
#define TETRIS_PLL_1375 {TETRIS_PLL, 22, 2, 1}
#define TETRIS_PLL_1400 {TETRIS_PLL, 56, 5, 1}
#define DDR3_PLL_200(x) {DDR3##x##_PLL, 4, 1, 2}
#define DDR3_PLL_400(x) {DDR3##x##_PLL, 16, 1, 4}
#define DDR3_PLL_800(x) {DDR3##x##_PLL, 16, 1, 2}
#define DDR3_PLL_333(x) {DDR3##x##_PLL, 20, 1, 6}
/* k2h DEV supports 800, 1000, 1200 MHz */
#define DEV_SUPPORTED_SPEEDS 0x383
/* k2h ARM supportd 800, 1000, 1200, 1350, 1400 MHz */
#define ARM_SUPPORTED_SPEEDS 0x3EF
#endif
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2L: Clock management APIs
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_CLOCK_K2L_H
#define __ASM_ARCH_CLOCK_K2L_H
#define PLLSET_CMD_LIST "<pa|arm|ddr3>"
#define KS2_CLK1_6 sys_clk0_6_clk
#define CORE_PLL_799 {CORE_PLL, 13, 1, 2}
#define CORE_PLL_983 {CORE_PLL, 16, 1, 2}
#define CORE_PLL_1000 {CORE_PLL, 114, 7, 2}
#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2}
#define CORE_PLL_1198 {CORE_PLL, 39, 2, 2}
#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2}
#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2}
#define PASS_PLL_983 {PASS_PLL, 16, 1, 2}
#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2}
#define TETRIS_PLL_491 {TETRIS_PLL, 8, 1, 2}
#define TETRIS_PLL_737 {TETRIS_PLL, 12, 1, 2}
#define TETRIS_PLL_799 {TETRIS_PLL, 13, 1, 2}
#define TETRIS_PLL_983 {TETRIS_PLL, 16, 1, 2}
#define TETRIS_PLL_1000 {TETRIS_PLL, 114, 7, 2}
#define TETRIS_PLL_1167 {TETRIS_PLL, 19, 1, 2}
#define TETRIS_PLL_1198 {TETRIS_PLL, 39, 2, 2}
#define TETRIS_PLL_1228 {TETRIS_PLL, 20, 1, 2}
#define TETRIS_PLL_1352 {TETRIS_PLL, 22, 1, 2}
#define TETRIS_PLL_1401 {TETRIS_PLL, 114, 5, 2}
#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2}
#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4}
#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2}
#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6}
/* k2l DEV supports 800, 1000, 1200 MHz */
#define DEV_SUPPORTED_SPEEDS 0x383
/* k2l ARM supportd 800, 1000, 1200, 1350, 1400 MHz */
#define ARM_SUPPORTED_SPEEDS 0x3ef
#endif
@@ -0,0 +1,133 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* keystone2: common clock header file
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_CLOCK_H
#define __ASM_ARCH_CLOCK_H
#ifndef __ASSEMBLY__
#ifdef CONFIG_SOC_K2HK
#include <asm/arch/clock-k2hk.h>
#endif
#ifdef CONFIG_SOC_K2E
#include <asm/arch/clock-k2e.h>
#endif
#ifdef CONFIG_SOC_K2L
#include <asm/arch/clock-k2l.h>
#endif
#ifdef CONFIG_SOC_K2G
#include <asm/arch/clock-k2g.h>
#endif
#define CORE_PLL MAIN_PLL
#define DDR3_PLL DDR3A_PLL
#define NSS_PLL PASS_PLL
#define CLK_LIST(CLK)\
CLK(0, core_pll_clk)\
CLK(1, pass_pll_clk)\
CLK(2, tetris_pll_clk)\
CLK(3, ddr3a_pll_clk)\
CLK(4, ddr3b_pll_clk)\
CLK(5, sys_clk0_clk)\
CLK(6, sys_clk0_1_clk)\
CLK(7, sys_clk0_2_clk)\
CLK(8, sys_clk0_3_clk)\
CLK(9, sys_clk0_4_clk)\
CLK(10, sys_clk0_6_clk)\
CLK(11, sys_clk0_8_clk)\
CLK(12, sys_clk0_12_clk)\
CLK(13, sys_clk0_24_clk)\
CLK(14, sys_clk1_clk)\
CLK(15, sys_clk1_3_clk)\
CLK(16, sys_clk1_4_clk)\
CLK(17, sys_clk1_6_clk)\
CLK(18, sys_clk1_12_clk)\
CLK(19, sys_clk2_clk)\
CLK(20, sys_clk3_clk)\
CLK(21, uart_pll_clk)
#include <asm/types.h>
#define GENERATE_ENUM(NUM, ENUM) ENUM = NUM,
#define GENERATE_INDX_STR(NUM, STRING) #NUM"\t- "#STRING"\n"
#define CLOCK_INDEXES_LIST CLK_LIST(GENERATE_INDX_STR)
enum {
SPD200,
SPD400,
SPD600,
SPD800,
SPD850,
SPD900,
SPD1000,
SPD1200,
SPD1250,
SPD1350,
SPD1400,
SPD1500,
NUM_SPDS,
};
/* PLL identifiers */
enum {
MAIN_PLL,
TETRIS_PLL,
PASS_PLL,
DDR3A_PLL,
DDR3B_PLL,
UART_PLL,
MAX_PLL_COUNT,
};
enum ext_clk_e {
sys_clk,
alt_core_clk,
pa_clk,
tetris_clk,
ddr3a_clk,
ddr3b_clk,
uart_clk,
ext_clk_count /* number of external clocks */
};
enum clk_e {
CLK_LIST(GENERATE_ENUM)
};
struct keystone_pll_regs {
u32 reg0;
u32 reg1;
};
/* PLL configuration data */
struct pll_init_data {
int pll;
int pll_m; /* PLL Multiplier */
int pll_d; /* PLL divider */
int pll_od; /* PLL output divider */
};
extern const struct keystone_pll_regs keystone_pll_regs[];
extern s16 divn_val[];
extern int speeds[];
void init_plls(void);
void init_pll(const struct pll_init_data *data);
struct pll_init_data *get_pll_init_data(int pll);
unsigned long ks_clk_get_rate(unsigned int clk);
int get_max_dev_speed(int *spds);
int get_max_arm_speed(int *spds);
void pll_pa_clk_sel(void);
unsigned int get_external_clk(u32 clk);
#endif
#endif
@@ -0,0 +1,132 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* keystone2: common pll clock definitions
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _CLOCK_DEFS_H_
#define _CLOCK_DEFS_H_
#include <asm/arch/hardware.h>
/* PLL Control Registers */
struct pllctl_regs {
u32 ctl; /* 00 */
u32 ocsel; /* 04 */
u32 secctl; /* 08 */
u32 resv0;
u32 mult; /* 10 */
u32 prediv; /* 14 */
u32 div1; /* 18 */
u32 div2; /* 1c */
u32 div3; /* 20 */
u32 oscdiv1; /* 24 */
u32 resv1; /* 28 */
u32 bpdiv; /* 2c */
u32 wakeup; /* 30 */
u32 resv2;
u32 cmd; /* 38 */
u32 stat; /* 3c */
u32 alnctl; /* 40 */
u32 dchange; /* 44 */
u32 cken; /* 48 */
u32 ckstat; /* 4c */
u32 systat; /* 50 */
u32 ckctl; /* 54 */
u32 resv3[2];
u32 div4; /* 60 */
u32 div5; /* 64 */
u32 div6; /* 68 */
u32 div7; /* 6c */
u32 div8; /* 70 */
u32 div9; /* 74 */
u32 div10; /* 78 */
u32 div11; /* 7c */
u32 div12; /* 80 */
};
static struct pllctl_regs *pllctl_regs[] = {
(struct pllctl_regs *)(KS2_CLOCK_BASE + 0x100)
};
#define pllctl_reg(pll, reg) (&(pllctl_regs[pll]->reg))
#define pllctl_reg_read(pll, reg) __raw_readl(pllctl_reg(pll, reg))
#define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg))
#define pllctl_reg_rmw(pll, reg, mask, val) \
pllctl_reg_write(pll, reg, \
(pllctl_reg_read(pll, reg) & ~(mask)) | val)
#define pllctl_reg_setbits(pll, reg, mask) \
pllctl_reg_rmw(pll, reg, 0, mask)
#define pllctl_reg_clrbits(pll, reg, mask) \
pllctl_reg_rmw(pll, reg, mask, 0)
#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1)
/* PLLCTL Bits */
#define PLLCTL_PLLENSRC_SHIF 5
#define PLLCTL_PLLENSRC_MASK BIT(5)
#define PLLCTL_PLLRST_SHIFT 3
#define PLLCTL_PLLRST_MASK BIT(3)
#define PLLCTL_PLLPWRDN_SHIFT 1
#define PLLCTL_PLLPWRDN_MASK BIT(1)
#define PLLCTL_PLLEN_SHIFT 0
#define PLLCTL_PLLEN_MASK BIT(0)
/* SECCTL Bits */
#define SECCTL_BYPASS_SHIFT 23
#define SECCTL_BYPASS_MASK BIT(23)
#define SECCTL_OP_DIV_SHIFT 19
#define SECCTL_OP_DIV_MASK (0xf << 19)
/* PLLM Bits */
#define PLLM_MULT_LO_SHIFT 0
#define PLLM_MULT_LO_MASK 0x3f
#define PLLM_MULT_LO_BITS 6
/* PLLDIVn Bits */
#define PLLDIV_ENABLE_SHIFT 15
#define PLLDIV_ENABLE_MASK BIT(15)
#define PLLDIV_RATIO_SHIFT 0x0
#define PLLDIV_RATIO_MASK 0xff
#define PLLDIV_MAX 16
/* PLLCMD Bits */
#define PLLCMD_GOSET_SHIFT 0
#define PLLCMD_GOSET_MASK BIT(0)
/* PLLSTAT Bits */
#define PLLSTAT_GOSTAT_SHIFT 0
#define PLLSTAT_GOSTAT_MASK BIT(0)
/* Device Config PLLCTL0 */
#define CFG_PLLCTL0_BWADJ_SHIFT 24
#define CFG_PLLCTL0_BWADJ_MASK (0xff << 24)
#define CFG_PLLCTL0_BWADJ_BITS 8
#define CFG_PLLCTL0_BYPASS_SHIFT 23
#define CFG_PLLCTL0_BYPASS_MASK BIT(23)
#define CFG_PLLCTL0_CLKOD_SHIFT 19
#define CFG_PLLCTL0_CLKOD_MASK (0xf << 19)
#define CFG_PLLCTL0_PLLM_HI_SHIFT 12
#define CFG_PLLCTL0_PLLM_HI_MASK (0x7f << 12)
#define CFG_PLLCTL0_PLLM_SHIFT 6
#define CFG_PLLCTL0_PLLM_MASK (0x1fff << 6)
#define CFG_PLLCTL0_PLLD_SHIFT 0
#define CFG_PLLCTL0_PLLD_MASK 0x3f
/* Device Config PLLCTL1 */
#define CFG_PLLCTL1_RST_SHIFT 14
#define CFG_PLLCTL1_RST_MASK BIT(14)
#define CFG_PLLCTL1_PAPLL_SHIFT 13
#define CFG_PLLCTL1_PAPLL_MASK BIT(13)
#define CFG_PLLCTL1_ENSAT_SHIFT 6
#define CFG_PLLCTL1_ENSAT_MASK BIT(6)
#define CFG_PLLCTL1_BWADJ_SHIFT 0
#define CFG_PLLCTL1_BWADJ_MASK 0xf
#define MISC_CTL1_ARM_PLL_EN BIT(13)
#endif /* _CLOCK_DEFS_H_ */
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* DDR3
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _DDR3_H_
#define _DDR3_H_
#include <asm/arch/hardware.h>
struct ddr3_phy_config {
unsigned int pllcr;
unsigned int pgcr1_mask;
unsigned int pgcr1_val;
unsigned int ptr0;
unsigned int ptr1;
unsigned int ptr2;
unsigned int ptr3;
unsigned int ptr4;
unsigned int dcr_mask;
unsigned int dcr_val;
unsigned int dtpr0;
unsigned int dtpr1;
unsigned int dtpr2;
unsigned int mr0;
unsigned int mr1;
unsigned int mr2;
unsigned int dtcr;
unsigned int pgcr2;
unsigned int zq0cr1;
unsigned int zq1cr1;
unsigned int zq2cr1;
unsigned int pir_v1;
unsigned int datx8_2_mask;
unsigned int datx8_2_val;
unsigned int datx8_3_mask;
unsigned int datx8_3_val;
unsigned int datx8_4_mask;
unsigned int datx8_4_val;
unsigned int datx8_5_mask;
unsigned int datx8_5_val;
unsigned int datx8_6_mask;
unsigned int datx8_6_val;
unsigned int datx8_7_mask;
unsigned int datx8_7_val;
unsigned int datx8_8_mask;
unsigned int datx8_8_val;
unsigned int pir_v2;
};
struct ddr3_emif_config {
unsigned int sdcfg;
unsigned int sdtim1;
unsigned int sdtim2;
unsigned int sdtim3;
unsigned int sdtim4;
unsigned int zqcfg;
unsigned int sdrfc;
};
struct ddr3_spd_cb {
char dimm_name[32];
struct ddr3_phy_config phy_cfg;
struct ddr3_emif_config emif_cfg;
unsigned int ddrspdclock;
int ddr_size_gbyte;
};
u32 ddr3_init(void);
void ddr3_reset_ddrphy(void);
void ddr3_init_ecc(u32 base, u32 ddr3_size);
void ddr3_disable_ecc(u32 base);
void ddr3_check_ecc_int(u32 base);
int ddr3_ecc_support_rmw(u32 base);
void ddr3_err_reset_workaround(void);
void ddr3_enable_ecc(u32 base, int test);
void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg);
void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg);
int ddr3_get_size(void);
#endif
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2E: SoC definitions
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_HARDWARE_K2E_H
#define __ASM_ARCH_HARDWARE_K2E_H
/* PA SS Registers */
#define KS2_PASS_BASE 0x24000000
/* Power and Sleep Controller (PSC) Domains */
#define KS2_LPSC_MOD_RST 0
#define KS2_LPSC_USB_1 1
#define KS2_LPSC_USB 2
#define KS2_LPSC_EMIF25_SPI 3
#define KS2_LPSC_TSIP 4
#define KS2_LPSC_DEBUGSS_TRC 5
#define KS2_LPSC_TETB_TRC 6
#define KS2_LPSC_PKTPROC 7
#define KS2_LPSC_PA KS2_LPSC_PKTPROC
#define KS2_LPSC_SGMII 8
#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII
#define KS2_LPSC_CRYPTO 9
#define KS2_LPSC_PCIE 10
#define KS2_LPSC_VUSR0 12
#define KS2_LPSC_CHIP_SRSS 13
#define KS2_LPSC_MSMC 14
#define KS2_LPSC_EMIF4F_DDR3 23
#define KS2_LPSC_PCIE_1 27
#define KS2_LPSC_XGE 50
/* Chip Interrupt Controller */
#define KS2_CIC2_DDR3_ECC_IRQ_NUM -1 /* not defined in K2E */
#define KS2_CIC2_DDR3_ECC_CHAN_NUM -1 /* not defined in K2E */
/* SGMII SerDes */
#define KS2_SGMII_SERDES2_BASE 0x02324000
#define KS2_LANES_PER_SGMII_SERDES 4
/* Number of DSP cores */
#define KS2_NUM_DSPS 1
/* NETCP pktdma */
#define KS2_NETCP_PDMA_CTRL_BASE 0x24186000
#define KS2_NETCP_PDMA_TX_BASE 0x24187000
#define KS2_NETCP_PDMA_TX_CH_NUM 21
#define KS2_NETCP_PDMA_RX_BASE 0x24188000
#define KS2_NETCP_PDMA_RX_CH_NUM 91
#define KS2_NETCP_PDMA_SCHED_BASE 0x24186100
#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x24189000
#define KS2_NETCP_PDMA_RX_FLOW_NUM 96
#define KS2_NETCP_PDMA_TX_SND_QUEUE 896
/* NETCP */
#define KS2_NETCP_BASE 0x24000000
#endif
@@ -0,0 +1,112 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2G: SoC definitions
*
* (C) Copyright 2015
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_HARDWARE_K2G_H
#define __ASM_ARCH_HARDWARE_K2G_H
#define KS2_NUM_DSPS 1
/* Power and Sleep Controller (PSC) Domains */
#define KS2_LPSC_ALWAYSON 0
#define KS2_LPSC_PMMC 1
#define KS2_LPSC_DEBUG 2
#define KS2_LPSC_NSS 3
#define KS2_LPSC_SA 4
#define KS2_LPSC_TERANET 5
#define KS2_LPSC_SYS_COMP 6
#define KS2_LPSC_QSPI 7
#define KS2_LPSC_MMC 8
#define KS2_LPSC_GPMC 9
#define KS2_LPSC_MLB 11
#define KS2_LPSC_EHRPWM 12
#define KS2_LPSC_EQEP 13
#define KS2_LPSC_ECAP 14
#define KS2_LPSC_MCASP 15
#define KS2_LPSC_SR 16
#define KS2_LPSC_MSMC 17
#ifdef KS2_LPSC_GEM_0
#undef KS2_LPSC_GEM_0
#endif
#define KS2_LPSC_GEM_0 18
#define KS2_LPSC_ARM 19
#define KS2_LPSC_ASRC 20
#define KS2_LPSC_ICSS 21
#define KS2_LPSC_DSS 23
#define KS2_LPSC_PCIE 24
#define KS2_LPSC_USB_0 25
#define KS2_LPSC_USB KS2_LPSC_USB_0
#define KS2_LPSC_USB_1 26
#define KS2_LPSC_DDR3 27
#define KS2_LPSC_SPARE0_LPSC0 28
#define KS2_LPSC_SPARE0_LPSC1 29
#define KS2_LPSC_SPARE1_LPSC0 30
#define KS2_LPSC_SPARE1_LPSC1 31
#define KS2_LPSC_CPGMAC KS2_LPSC_NSS
#define KS2_LPSC_CRYPTO KS2_LPSC_SA
/* SGMII SerDes */
#define KS2_LANES_PER_SGMII_SERDES 4
/* NETCP pktdma */
#define KS2_NETCP_PDMA_CTRL_BASE 0x04010000
#define KS2_NETCP_PDMA_TX_BASE 0x04011000
#define KS2_NETCP_PDMA_TX_CH_NUM 21
#define KS2_NETCP_PDMA_RX_BASE 0x04012000
#define KS2_NETCP_PDMA_RX_CH_NUM 32
#define KS2_NETCP_PDMA_SCHED_BASE 0x04010100
#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x04013000
#define KS2_NETCP_PDMA_RX_FLOW_NUM 32
#define KS2_NETCP_PDMA_TX_SND_QUEUE 5
/* NETCP */
#define KS2_NETCP_BASE 0x04000000
#define K2G_GPIO0_BASE 0X02603000
#define K2G_GPIO1_BASE 0X0260a000
#define K2G_GPIO0_BANK0_BASE K2G_GPIO0_BASE + 0x10
#define K2G_GPIO1_BANK2_BASE K2G_GPIO1_BASE + 0x38
#define K2G_GPIO_DIR_OFFSET 0x0
#define K2G_GPIO_OUTDATA_OFFSET 0x4
#define K2G_GPIO_SETDATA_OFFSET 0x8
#define K2G_GPIO_CLRDATA_OFFSET 0xC
/* BOOTCFG RESETMUX8 */
#define KS2_RSTMUX8 (KS2_DEVICE_STATE_CTRL_BASE + 0x328)
/* RESETMUX register definitions */
#define RSTMUX_LOCK8_SHIFT 0x0
#define RSTMUX_LOCK8_MASK (0x1 << 0)
#define RSTMUX_OMODE8_SHIFT 0x1
#define RSTMUX_OMODE8_MASK (0x7 << 1)
#define RSTMUX_OMODE8_DEV_RESET 0x2
#define RSTMUX_OMODE8_INT 0x3
#define RSTMUX_OMODE8_INT_AND_DEV_RESET 0x4
/* DEVSTAT register definition */
#define KS2_DEVSTAT_REFCLK_SHIFT 7
#define KS2_DEVSTAT_REFCLK_MASK (0x7 << 7)
/* GPMC */
#define KS2_GPMC_BASE 0x21818000
/* SYSCLK indexes */
#define SYSCLK_19MHz 0
#define SYSCLK_24MHz 1
#define SYSCLK_25MHz 2
#define SYSCLK_26MHz 3
#define MAX_SYSCLK 4
#ifndef __ASSEMBLY__
static inline u8 get_sysclk_index(void)
{
u32 dev_stat = __raw_readl(KS2_DEVSTAT);
return (dev_stat & KS2_DEVSTAT_REFCLK_MASK) >> KS2_DEVSTAT_REFCLK_SHIFT;
}
#endif
#endif /* __ASM_ARCH_HARDWARE_K2G_H */
@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2HK: SoC definitions
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_HARDWARE_K2HK_H
#define __ASM_ARCH_HARDWARE_K2HK_H
#define KS2_ARM_PLL_EN BIT(13)
/* PA SS Registers */
#define KS2_PASS_BASE 0x02000000
/* Power and Sleep Controller (PSC) Domains */
#define KS2_LPSC_MOD 0
#define KS2_LPSC_DUMMY1 1
#define KS2_LPSC_USB 2
#define KS2_LPSC_EMIF25_SPI 3
#define KS2_LPSC_TSIP 4
#define KS2_LPSC_DEBUGSS_TRC 5
#define KS2_LPSC_TETB_TRC 6
#define KS2_LPSC_PKTPROC 7
#define KS2_LPSC_PA KS2_LPSC_PKTPROC
#define KS2_LPSC_SGMII 8
#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII
#define KS2_LPSC_CRYPTO 9
#define KS2_LPSC_PCIE 10
#define KS2_LPSC_SRIO 11
#define KS2_LPSC_VUSR0 12
#define KS2_LPSC_CHIP_SRSS 13
#define KS2_LPSC_MSMC 14
#define KS2_LPSC_GEM_1 16
#define KS2_LPSC_GEM_2 17
#define KS2_LPSC_GEM_3 18
#define KS2_LPSC_GEM_4 19
#define KS2_LPSC_GEM_5 20
#define KS2_LPSC_GEM_6 21
#define KS2_LPSC_GEM_7 22
#define KS2_LPSC_EMIF4F_DDR3A 23
#define KS2_LPSC_EMIF4F_DDR3B 24
#define KS2_LPSC_TAC 25
#define KS2_LPSC_RAC 26
#define KS2_LPSC_RAC_1 27
#define KS2_LPSC_FFTC_A 28
#define KS2_LPSC_FFTC_B 29
#define KS2_LPSC_FFTC_C 30
#define KS2_LPSC_FFTC_D 31
#define KS2_LPSC_FFTC_E 32
#define KS2_LPSC_FFTC_F 33
#define KS2_LPSC_AI2 34
#define KS2_LPSC_TCP3D_0 35
#define KS2_LPSC_TCP3D_1 36
#define KS2_LPSC_TCP3D_2 37
#define KS2_LPSC_TCP3D_3 38
#define KS2_LPSC_VCP2X4_A 39
#define KS2_LPSC_CP2X4_B 40
#define KS2_LPSC_VCP2X4_C 41
#define KS2_LPSC_VCP2X4_D 42
#define KS2_LPSC_VCP2X4_E 43
#define KS2_LPSC_VCP2X4_F 44
#define KS2_LPSC_VCP2X4_G 45
#define KS2_LPSC_VCP2X4_H 46
#define KS2_LPSC_BCP 47
#define KS2_LPSC_DXB 48
#define KS2_LPSC_VUSR1 49
#define KS2_LPSC_XGE 50
#define KS2_LPSC_ARM_SREFLEX 51
/* DDR3B definitions */
#define KS2_DDR3B_EMIF_CTRL_BASE 0x21020000
#define KS2_DDR3B_EMIF_DATA_BASE 0x60000000
#define KS2_DDR3B_DDRPHYC 0x02328000
#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3 /* DDR3 ECC system irq number */
#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D /* DDR3 ECC int mapped to CIC2
channel 29 */
/* SGMII SerDes */
#define KS2_LANES_PER_SGMII_SERDES 4
/* Number of DSP cores */
#define KS2_NUM_DSPS 8
/* NETCP pktdma */
#define KS2_NETCP_PDMA_CTRL_BASE 0x02004000
#define KS2_NETCP_PDMA_TX_BASE 0x02004400
#define KS2_NETCP_PDMA_TX_CH_NUM 9
#define KS2_NETCP_PDMA_RX_BASE 0x02004800
#define KS2_NETCP_PDMA_RX_CH_NUM 26
#define KS2_NETCP_PDMA_SCHED_BASE 0x02004c00
#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x02005000
#define KS2_NETCP_PDMA_RX_FLOW_NUM 32
#define KS2_NETCP_PDMA_TX_SND_QUEUE 648
/* NETCP */
#define KS2_NETCP_BASE 0x02000000
#endif /* __ASM_ARCH_HARDWARE_H */
@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2L: SoC definitions
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_HARDWARE_K2L_H
#define __ASM_ARCH_HARDWARE_K2L_H
#define KS2_ARM_PLL_EN BIT(13)
/* PA SS Registers */
#define KS2_PASS_BASE 0x26000000
/* Power and Sleep Controller (PSC) Domains */
#define KS2_LPSC_MOD 0
#define KS2_LPSC_DFE_IQN_SYS 1
#define KS2_LPSC_USB 2
#define KS2_LPSC_EMIF25_SPI 3
#define KS2_LPSC_TSIP 4
#define KS2_LPSC_DEBUGSS_TRC 5
#define KS2_LPSC_TETB_TRC 6
#define KS2_LPSC_PKTPROC 7
#define KS2_LPSC_PA KS2_LPSC_PKTPROC
#define KS2_LPSC_SGMII 8
#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII
#define KS2_LPSC_CRYPTO 9
#define KS2_LPSC_PCIE0 10
#define KS2_LPSC_PCIE1 11
#define KS2_LPSC_JESD_MISC 12
#define KS2_LPSC_CHIP_SRSS 13
#define KS2_LPSC_MSMC 14
#define KS2_LPSC_GEM_1 16
#define KS2_LPSC_GEM_2 17
#define KS2_LPSC_GEM_3 18
#define KS2_LPSC_EMIF4F_DDR3 23
#define KS2_LPSC_TAC 25
#define KS2_LPSC_RAC 26
#define KS2_LPSC_DDUC4X_CFR2X_BB 27
#define KS2_LPSC_FFTC_A 28
#define KS2_LPSC_OSR 34
#define KS2_LPSC_TCP3D_0 35
#define KS2_LPSC_TCP3D_1 37
#define KS2_LPSC_VCP2X4_A 39
#define KS2_LPSC_VCP2X4_B 40
#define KS2_LPSC_VCP2X4_C 41
#define KS2_LPSC_VCP2X4_D 42
#define KS2_LPSC_BCP 47
#define KS2_LPSC_DPD4X 48
#define KS2_LPSC_FFTC_B 49
#define KS2_LPSC_IQN_AIL 50
/* Chip Interrupt Controller */
#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3
#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D
/* OSR */
#define KS2_OSR_DATA_BASE 0x70000000 /* OSR data base */
#define KS2_OSR_CFG_BASE 0x02348c00 /* OSR config base */
#define KS2_OSR_ECC_VEC 0x08 /* ECC Vector reg */
#define KS2_OSR_ECC_CTRL 0x14 /* ECC control reg */
/* OSR ECC Vector register */
#define KS2_OSR_ECC_VEC_TRIG_RD BIT(15) /* trigger a read op */
#define KS2_OSR_ECC_VEC_RD_DONE BIT(24) /* read complete */
#define KS2_OSR_ECC_VEC_RAM_ID_SH 0 /* RAM ID shift */
#define KS2_OSR_ECC_VEC_RD_ADDR_SH 16 /* read address shift */
/* OSR ECC control register */
#define KS2_OSR_ECC_CTRL_EN BIT(0) /* ECC enable bit */
#define KS2_OSR_ECC_CTRL_CHK BIT(1) /* ECC check bit */
#define KS2_OSR_ECC_CTRL_RMW BIT(2) /* ECC check bit */
/* Number of OSR RAM banks */
#define KS2_OSR_NUM_RAM_BANKS 4
/* OSR memory size */
#define KS2_OSR_SIZE 0x100000
/* SGMII SerDes */
#define KS2_SGMII_SERDES2_BASE 0x02320000
#define KS2_LANES_PER_SGMII_SERDES 2
/* Number of DSP cores */
#define KS2_NUM_DSPS 4
/* NETCP pktdma */
#define KS2_NETCP_PDMA_CTRL_BASE 0x26186000
#define KS2_NETCP_PDMA_TX_BASE 0x26187000
#define KS2_NETCP_PDMA_TX_CH_NUM 21
#define KS2_NETCP_PDMA_RX_BASE 0x26188000
#define KS2_NETCP_PDMA_RX_CH_NUM 91
#define KS2_NETCP_PDMA_SCHED_BASE 0x26186100
#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x26189000
#define KS2_NETCP_PDMA_RX_FLOW_NUM 96
#define KS2_NETCP_PDMA_TX_SND_QUEUE 896
/* NETCP */
#define KS2_NETCP_BASE 0x26000000
#ifndef __ASSEMBLY__
static inline int ddr3_get_size(void)
{
return 2;
}
#endif
#endif /* __ASM_ARCH_HARDWARE_K2L_H */
@@ -0,0 +1,397 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Keystone2: Common SoC definitions, structures etc.
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
#include <config.h>
#ifndef __ASSEMBLY__
#include <linux/sizes.h>
#include <asm/io.h>
#define REG(addr) (*(volatile unsigned int *)(addr))
#define REG_P(addr) ((volatile unsigned int *)(addr))
typedef volatile unsigned int dv_reg;
typedef volatile unsigned int *dv_reg_p;
#endif
#define KS2_DDRPHY_PIR_OFFSET 0x04
#define KS2_DDRPHY_PGCR0_OFFSET 0x08
#define KS2_DDRPHY_PGCR1_OFFSET 0x0C
#define KS2_DDRPHY_PGSR0_OFFSET 0x10
#define KS2_DDRPHY_PGSR1_OFFSET 0x14
#define KS2_DDRPHY_PLLCR_OFFSET 0x18
#define KS2_DDRPHY_PTR0_OFFSET 0x1C
#define KS2_DDRPHY_PTR1_OFFSET 0x20
#define KS2_DDRPHY_PTR2_OFFSET 0x24
#define KS2_DDRPHY_PTR3_OFFSET 0x28
#define KS2_DDRPHY_PTR4_OFFSET 0x2C
#define KS2_DDRPHY_DCR_OFFSET 0x44
#define KS2_DDRPHY_DTPR0_OFFSET 0x48
#define KS2_DDRPHY_DTPR1_OFFSET 0x4C
#define KS2_DDRPHY_DTPR2_OFFSET 0x50
#define KS2_DDRPHY_MR0_OFFSET 0x54
#define KS2_DDRPHY_MR1_OFFSET 0x58
#define KS2_DDRPHY_MR2_OFFSET 0x5C
#define KS2_DDRPHY_DTCR_OFFSET 0x68
#define KS2_DDRPHY_PGCR2_OFFSET 0x8C
#define KS2_DDRPHY_ZQ0CR1_OFFSET 0x184
#define KS2_DDRPHY_ZQ1CR1_OFFSET 0x194
#define KS2_DDRPHY_ZQ2CR1_OFFSET 0x1A4
#define KS2_DDRPHY_ZQ3CR1_OFFSET 0x1B4
#define KS2_DDRPHY_DATX8_2_OFFSET 0x240
#define KS2_DDRPHY_DATX8_3_OFFSET 0x280
#define KS2_DDRPHY_DATX8_4_OFFSET 0x2C0
#define KS2_DDRPHY_DATX8_5_OFFSET 0x300
#define KS2_DDRPHY_DATX8_6_OFFSET 0x340
#define KS2_DDRPHY_DATX8_7_OFFSET 0x380
#define KS2_DDRPHY_DATX8_8_OFFSET 0x3C0
#define IODDRM_MASK 0x00000180
#define ZCKSEL_MASK 0x01800000
#define CL_MASK 0x00000072
#define WR_MASK 0x00000E00
#define BL_MASK 0x00000003
#define RRMODE_MASK 0x00040000
#define UDIMM_MASK 0x20000000
#define BYTEMASK_MASK 0x0003FC00
#define MPRDQ_MASK 0x00000080
#define PDQ_MASK 0x00000070
#define NOSRA_MASK 0x08000000
#define ECC_MASK 0x00000001
#define DXEN_MASK 0x00000001
/* DDR3 definitions */
#define KS2_DDR3A_EMIF_CTRL_BASE 0x21010000
#define KS2_DDR3A_EMIF_DATA_BASE 0x80000000
#define KS2_DDR3A_DDRPHYC 0x02329000
#define EMIF1_BASE KS2_DDR3A_EMIF_CTRL_BASE
#define KS2_DDR3_MIDR_OFFSET 0x00
#define KS2_DDR3_STATUS_OFFSET 0x04
#define KS2_DDR3_SDCFG_OFFSET 0x08
#define KS2_DDR3_SDRFC_OFFSET 0x10
#define KS2_DDR3_SDTIM1_OFFSET 0x18
#define KS2_DDR3_SDTIM2_OFFSET 0x1C
#define KS2_DDR3_SDTIM3_OFFSET 0x20
#define KS2_DDR3_SDTIM4_OFFSET 0x28
#define KS2_DDR3_PMCTL_OFFSET 0x38
#define KS2_DDR3_ZQCFG_OFFSET 0xC8
#define KS2_DDR3_PLLCTRL_PHY_RESET 0x80000000
/* DDR3 ECC */
#define KS2_DDR3_ECC_INT_STATUS_OFFSET 0x0AC
#define KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET 0x0B4
#define KS2_DDR3_ECC_CTRL_OFFSET 0x110
#define KS2_DDR3_ECC_ADDR_RANGE1_OFFSET 0x114
#define KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET 0x130
#define KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET 0x13C
/* DDR3 ECC Interrupt Status register */
#define KS2_DDR3_1B_ECC_ERR_SYS BIT(5)
#define KS2_DDR3_2B_ECC_ERR_SYS BIT(4)
#define KS2_DDR3_WR_ECC_ERR_SYS BIT(3)
/* DDR3 ECC Control register */
#define KS2_DDR3_ECC_EN BIT(31)
#define KS2_DDR3_ECC_ADDR_RNG_PROT BIT(30)
#define KS2_DDR3_ECC_VERIFY_EN BIT(29)
#define KS2_DDR3_ECC_RMW_EN BIT(28)
#define KS2_DDR3_ECC_ADDR_RNG_1_EN BIT(0)
#define KS2_DDR3_ECC_ENABLE (KS2_DDR3_ECC_EN | \
KS2_DDR3_ECC_ADDR_RNG_PROT | \
KS2_DDR3_ECC_VERIFY_EN)
/* EDMA */
#define KS2_EDMA0_BASE 0x02700000
/* EDMA3 register offsets */
#define KS2_EDMA_QCHMAP0 0x0200
#define KS2_EDMA_IPR 0x1068
#define KS2_EDMA_ICR 0x1070
#define KS2_EDMA_QEECR 0x1088
#define KS2_EDMA_QEESR 0x108c
#define KS2_EDMA_PARAM_1(x) (0x4020 + (4 * x))
/* NETCP pktdma */
#ifdef CONFIG_SOC_K2G
#define KS2_NETCP_PDMA_RX_FREE_QUEUE 113
#define KS2_NETCP_PDMA_RX_RCV_QUEUE 114
#else
#define KS2_NETCP_PDMA_RX_FREE_QUEUE 4001
#define KS2_NETCP_PDMA_RX_RCV_QUEUE 4002
#endif
/* Chip Interrupt Controller */
#define KS2_CIC2_BASE 0x02608000
/* Chip Interrupt Controller register offsets */
#define KS2_CIC_CTRL 0x04
#define KS2_CIC_HOST_CTRL 0x0C
#define KS2_CIC_GLOBAL_ENABLE 0x10
#define KS2_CIC_SYS_ENABLE_IDX_SET 0x28
#define KS2_CIC_HOST_ENABLE_IDX_SET 0x34
#define KS2_CIC_CHAN_MAP(n) (0x0400 + (n << 2))
#define KS2_UART0_BASE 0x02530c00
#define KS2_UART1_BASE 0x02531000
/* Boot Config */
#define KS2_DEVICE_STATE_CTRL_BASE 0x02620000
#define KS2_JTAG_ID_REG (KS2_DEVICE_STATE_CTRL_BASE + 0x18)
#define KS2_DEVSTAT (KS2_DEVICE_STATE_CTRL_BASE + 0x20)
#define KS2_DEVCFG (KS2_DEVICE_STATE_CTRL_BASE + 0x14c)
#define KS2_ETHERNET_CFG (KS2_DEVICE_STATE_CTRL_BASE + 0xe20)
#define KS2_ETHERNET_RGMII 2
/* PSC */
#define KS2_PSC_BASE 0x02350000
#define KS2_LPSC_GEM_0 15
#define KS2_LPSC_TETRIS 52
#define KS2_TETRIS_PWR_DOMAIN 31
#define KS2_GEM_0_PWR_DOMAIN 8
/* Chip configuration unlock codes and registers */
#define KS2_KICK0 (KS2_DEVICE_STATE_CTRL_BASE + 0x38)
#define KS2_KICK1 (KS2_DEVICE_STATE_CTRL_BASE + 0x3c)
#define KS2_KICK0_MAGIC 0x83e70b13
#define KS2_KICK1_MAGIC 0x95a4f1e0
/* PLL control registers */
#define KS2_MAINPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x350)
#define KS2_MAINPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x354)
#define KS2_PASSPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x358)
#define KS2_PASSPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x35C)
#define KS2_DDR3APLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x360)
#define KS2_DDR3APLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x364)
#define KS2_DDR3BPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x368)
#define KS2_DDR3BPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x36C)
#define KS2_ARMPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x370)
#define KS2_ARMPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x374)
#define KS2_UARTPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x390)
#define KS2_UARTPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x394)
#define KS2_PLL_CNTRL_BASE 0x02310000
#define KS2_CLOCK_BASE KS2_PLL_CNTRL_BASE
#define KS2_RSTCTRL_RSTYPE (KS2_PLL_CNTRL_BASE + 0xe4)
#define KS2_RSTCTRL (KS2_PLL_CNTRL_BASE + 0xe8)
#define KS2_RSTCTRL_RSCFG (KS2_PLL_CNTRL_BASE + 0xec)
#define KS2_RSTCTRL_KEY 0x5a69
#define KS2_RSTCTRL_MASK 0xffff0000
#define KS2_RSTCTRL_SWRST 0xfffe0000
#define KS2_RSTYPE_PLL_SOFT BIT(13)
/* SPI */
#ifdef CONFIG_SOC_K2G
#define KS2_SPI0_BASE 0x21805400
#define KS2_SPI1_BASE 0x21805800
#define KS2_SPI2_BASE 0x21805c00
#define KS2_SPI3_BASE 0x21806000
#else
#define KS2_SPI0_BASE 0x21000400
#define KS2_SPI1_BASE 0x21000600
#define KS2_SPI2_BASE 0x21000800
#define KS2_SPI_BASE KS2_SPI0_BASE
#endif
/* AEMIF */
#define KS2_AEMIF_CNTRL_BASE 0x21000a00
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE KS2_AEMIF_CNTRL_BASE
/* Flag from ks2_debug options to check if DSPs need to stay ON */
#define DBG_LEAVE_DSPS_ON 0x1
/* MSMC control */
#define KS2_MSMC_CTRL_BASE 0x0bc00000
#define KS2_MSMC_DATA_BASE 0x0c000000
/* KS2 Generic Privilege ID Settings for MSMC2 */
#define KS2_MSMC_SEGMENT_C6X_0 0
#define KS2_MSMC_SEGMENT_C6X_1 1
#define KS2_MSMC_SEGMENT_C6X_2 2
#define KS2_MSMC_SEGMENT_C6X_3 3
#define KS2_MSMC_SEGMENT_C6X_4 4
#define KS2_MSMC_SEGMENT_C6X_5 5
#define KS2_MSMC_SEGMENT_C6X_6 6
#define KS2_MSMC_SEGMENT_C6X_7 7
#define KS2_MSMC_SEGMENT_DEBUG 12
/* KS2 HK/L/E MSMC PRIVIDs for MSMC2 */
#define K2HKLE_MSMC_SEGMENT_ARM 8
#define K2HKLE_MSMC_SEGMENT_NETCP 9
#define K2HKLE_MSMC_SEGMENT_QM_PDSP 10
#define K2HKLE_MSMC_SEGMENT_PCIE0 11
/* K2HK specific Privilege ID Settings */
#define K2HKE_MSMC_SEGMENT_HYPERLINK 14
/* K2L specific Privilege ID Settings */
#define K2L_MSMC_SEGMENT_PCIE1 14
/* K2E specific Privilege ID Settings */
#define K2E_MSMC_SEGMENT_PCIE1 13
#define K2E_MSMC_SEGMENT_TSIP 15
/* K2G specific Privilege ID Settings */
#define K2G_MSMC_SEGMENT_ARM 1
#define K2G_MSMC_SEGMENT_ICSS0 2
#define K2G_MSMC_SEGMENT_ICSS1 3
#define K2G_MSMC_SEGMENT_NSS 4
#define K2G_MSMC_SEGMENT_PCIE 5
#define K2G_MSMC_SEGMENT_USB 6
#define K2G_MSMC_SEGMENT_MLB 8
#define K2G_MSMC_SEGMENT_PMMC 9
#define K2G_MSMC_SEGMENT_DSS 10
#define K2G_MSMC_SEGMENT_MMC 11
/* MSMC segment size shift bits */
#define KS2_MSMC_SEG_SIZE_SHIFT 12
#define KS2_MSMC_MAP_SEG_NUM (2 << (30 - KS2_MSMC_SEG_SIZE_SHIFT))
#define KS2_MSMC_DST_SEG_BASE (CONFIG_SYS_LPAE_SDRAM_BASE >> \
KS2_MSMC_SEG_SIZE_SHIFT)
/* Device speed */
#define KS2_REV1_DEVSPEED (KS2_DEVICE_STATE_CTRL_BASE + 0xc98)
#define KS2_EFUSE_BOOTROM (KS2_DEVICE_STATE_CTRL_BASE + 0xc90)
#define KS2_MISC_CTRL (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c)
/* Queue manager */
#ifdef CONFIG_SOC_K2G
#define KS2_QM_BASE_ADDRESS 0x040C0000
#define KS2_QM_CONF_BASE 0x04040000
#define KS2_QM_DESC_SETUP_BASE 0x04080000
#define KS2_QM_STATUS_RAM_BASE 0x0 /* K2G doesn't have it */
#define KS2_QM_INTD_CONF_BASE 0x0
#define KS2_QM_PDSP1_CMD_BASE 0x0
#define KS2_QM_PDSP1_CTRL_BASE 0x0
#define KS2_QM_PDSP1_IRAM_BASE 0x0
#define KS2_QM_MANAGER_QUEUES_BASE 0x040c0000
#define KS2_QM_MANAGER_Q_PROXY_BASE 0x04040200
#define KS2_QM_QUEUE_STATUS_BASE 0x04100000
#define KS2_QM_LINK_RAM_BASE 0x04020000
#define KS2_QM_REGION_NUM 8
#define KS2_QM_QPOOL_NUM 112
#else
#define KS2_QM_BASE_ADDRESS 0x23a80000
#define KS2_QM_CONF_BASE 0x02a02000
#define KS2_QM_DESC_SETUP_BASE 0x02a03000
#define KS2_QM_STATUS_RAM_BASE 0x02a06000
#define KS2_QM_INTD_CONF_BASE 0x02a0c000
#define KS2_QM_PDSP1_CMD_BASE 0x02a20000
#define KS2_QM_PDSP1_CTRL_BASE 0x02a0f000
#define KS2_QM_PDSP1_IRAM_BASE 0x02a10000
#define KS2_QM_MANAGER_QUEUES_BASE 0x02a80000
#define KS2_QM_MANAGER_Q_PROXY_BASE 0x02ac0000
#define KS2_QM_QUEUE_STATUS_BASE 0x02a40000
#define KS2_QM_LINK_RAM_BASE 0x00100000
#define KS2_QM_REGION_NUM 64
#define KS2_QM_QPOOL_NUM 4000
#endif
/* USB */
#define KS2_USB_SS_BASE 0x02680000
#define KS2_USB_HOST_XHCI_BASE (KS2_USB_SS_BASE + 0x10000)
#define KS2_DEV_USB_PHY_BASE 0x02620738
#define KS2_USB_PHY_CFG_BASE 0x02630000
#define KS2_MAC_ID_BASE_ADDR (KS2_DEVICE_STATE_CTRL_BASE + 0x110)
/* SGMII SerDes */
#define KS2_SGMII_SERDES_BASE 0x0232a000
/* JTAG ID register */
#define JTAGID_VARIANT_SHIFT 28
#define JTAGID_VARIANT_MASK (0xf << 28)
#define JTAGID_PART_NUM_SHIFT 12
#define JTAGID_PART_NUM_MASK (0xffff << 12)
/* PART NUMBER definitions */
#define CPU_66AK2Hx 0xb981
#define CPU_66AK2Ex 0xb9a6
#define CPU_66AK2Lx 0xb9a7
#define CPU_66AK2Gx 0xbb06
/* Variant definitions */
#define CPU_66AK2G1x 0x08
/* DEVSPEED register */
#define DEVSPEED_DEVSPEED_SHIFT 16
#define DEVSPEED_DEVSPEED_MASK (0xfff << 16)
#define DEVSPEED_ARMSPEED_SHIFT 0
#define DEVSPEED_ARMSPEED_MASK 0xfff
#define DEVSPEED_NUMSPDS 12
#ifdef CONFIG_SOC_K2HK
#include <asm/arch/hardware-k2hk.h>
#endif
#ifdef CONFIG_SOC_K2E
#include <asm/arch/hardware-k2e.h>
#endif
#ifdef CONFIG_SOC_K2L
#include <asm/arch/hardware-k2l.h>
#endif
#ifdef CONFIG_SOC_K2G
#include <asm/arch/hardware-k2g.h>
#endif
#ifndef __ASSEMBLY__
static inline u16 get_part_number(void)
{
u32 jtag_id = __raw_readl(KS2_JTAG_ID_REG);
return (jtag_id & JTAGID_PART_NUM_MASK) >> JTAGID_PART_NUM_SHIFT;
}
static inline u8 cpu_is_k2hk(void)
{
return get_part_number() == CPU_66AK2Hx;
}
static inline u8 cpu_is_k2e(void)
{
return get_part_number() == CPU_66AK2Ex;
}
static inline u8 cpu_is_k2l(void)
{
return get_part_number() == CPU_66AK2Lx;
}
static inline u8 cpu_is_k2g(void)
{
return get_part_number() == CPU_66AK2Gx;
}
static inline u8 cpu_revision(void)
{
u32 jtag_id = __raw_readl(KS2_JTAG_ID_REG);
u8 rev = (jtag_id & JTAGID_VARIANT_MASK) >> JTAGID_VARIANT_SHIFT;
return rev;
}
int cpu_to_bus(u32 *ptr, u32 length);
void sdelay(unsigned long);
#endif
#endif /* __ASM_ARCH_HARDWARE_H */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* keystone: i2c driver definitions
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _I2C_DEFS_H_
#define _I2C_DEFS_H_
#define I2C0_BASE 0x02530000
#define I2C1_BASE 0x02530400
#define I2C2_BASE 0x02530800
#define I2C_BASE I2C0_BASE
#endif
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2G: MMC
*
* (C) Copyright 2015
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef K2G_MMC_HOST_DEF_H
#define K2G_MMC_HOST_DEF_H
#include <asm/omap_mmc.h>
/*
* OMAP HSMMC register definitions
*/
#define OMAP_HSMMC1_BASE 0x23000000
#define OMAP_HSMMC2_BASE 0x23100000
#endif /* K2G_MMC_HOST_DEF_H */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2HK: secure kernel command header file
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _MACH_MON_H_
#define _MACH_MON_H_
int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr);
int mon_power_on(int core_id, void *ep);
int mon_power_off(int core_id);
#endif
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* MSMC controller
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _MSMC_H_
#define _MSMC_H_
#include <asm/arch/hardware.h>
enum mpax_seg_size {
MPAX_SEG_4K = 0x0b,
MPAX_SEG_8K,
MPAX_SEG_16K,
MPAX_SEG_32K,
MPAX_SEG_64K,
MPAX_SEG_128K,
MPAX_SEG_256K,
MPAX_SEG_512K,
MPAX_SEG_1M,
MPAX_SEG_2M,
MPAX_SEG_4M,
MPAX_SEG_8M,
MPAX_SEG_16M,
MPAX_SEG_32M,
MPAX_SEG_64M,
MPAX_SEG_128M,
MPAX_SEG_256M,
MPAX_SEG_512M,
MPAX_SEG_1G,
MPAX_SEG_2G,
MPAX_SEG_4G
};
void msmc_share_all_segments(int priv_id);
void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax);
void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax);
void msmc_map_ses_segment(int priv_id, int ses_pair,
u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size);
#endif
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* K2G: Pinmux configuration
*
* (C) Copyright 2015
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef __ASM_ARCH_MUX_K2G_H
#define __ASM_ARCH_MUX_K2G_H
#include <common.h>
#include <asm/io.h>
#define K2G_PADCFG_REG (KS2_DEVICE_STATE_CTRL_BASE + 0x1000)
/*
* 20:19 - buffer class RW fixed
* 18 - rxactive (Input enabled for the pad ) 0 - Di; 1 - En;
* 17 - pulltypesel (0 - PULLDOWN; 1 - PULLUP);
* 16 - pulluden (0 - PULLUP/DOWN EN; 1 - DI);
* 3:0 - muxmode (available modes 0:5)
*/
#define PIN_IEN (1 << 18) /* pin input enabled */
#define PIN_PDIS (1 << 16) /* pull up/down disabled */
#define PIN_PTU (1 << 17) /* pull up */
#define PIN_PTD (0 << 17) /* pull down */
#define BUFFER_CLASS_B (0 << 19)
#define BUFFER_CLASS_C (1 << 19)
#define BUFFER_CLASS_D (2 << 19)
#define BUFFER_CLASS_E (3 << 19)
#define MODE(m) ((m) & 0x7)
#define MAX_PIN_N 260
#define MUX_CFG(value, index) \
__raw_writel(\
(value) | \
(__raw_readl(K2G_PADCFG_REG + (index << 2)) & \
(0x3 << 19)),\
(K2G_PADCFG_REG + (index << 2))\
);
struct pin_cfg {
int reg_inx;
u32 val;
};
static inline void configure_pin_mux(struct pin_cfg *pin_mux)
{
if (!pin_mux)
return;
while ((pin_mux->reg_inx >= 0) && (pin_mux->reg_inx < MAX_PIN_N)) {
MUX_CFG(pin_mux->val, pin_mux->reg_inx);
pin_mux++;
}
}
#endif /* __ASM_ARCH_MUX_K2G_H */
@@ -0,0 +1,106 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#ifndef _PSC_DEFS_H_
#define _PSC_DEFS_H_
#include <asm/arch/hardware.h>
/*
* FILE PURPOSE: Local Power Sleep Controller definitions
*
* FILE NAME: psc_defs.h
*
* DESCRIPTION: Provides local definitions for the power saver controller
*
*/
/* Register offsets */
#define PSC_REG_PTCMD 0x120
#define PSC_REG_PSTAT 0x128
#define PSC_REG_PDSTAT(x) (0x200 + (4 * (x)))
#define PSC_REG_PDCTL(x) (0x300 + (4 * (x)))
#define PSC_REG_MDCFG(x) (0x600 + (4 * (x)))
#define PSC_REG_MDSTAT(x) (0x800 + (4 * (x)))
#define PSC_REG_MDCTL(x) (0xa00 + (4 * (x)))
static inline u32 _boot_bit_mask(u32 x, u32 y)
{
u32 val = (1 << (x - y + 1)) - 1;
return val << y;
}
static inline u32 boot_read_bitfield(u32 z, u32 x, u32 y)
{
u32 val = z & _boot_bit_mask(x, y);
return val >> y;
}
static inline u32 boot_set_bitfield(u32 z, u32 f, u32 x, u32 y)
{
u32 mask = _boot_bit_mask(x, y);
return (z & ~mask) | ((f << y) & mask);
}
/* PDCTL */
#define PSC_REG_PDCTL_SET_NEXT(x, y) boot_set_bitfield((x), (y), 0, 0)
#define PSC_REG_PDCTL_SET_PDMODE(x, y) boot_set_bitfield((x), (y), 15, 12)
/* PDSTAT */
#define PSC_REG_PDSTAT_GET_STATE(x) boot_read_bitfield((x), 4, 0)
/* MDCFG */
#define PSC_REG_MDCFG_GET_PD(x) boot_read_bitfield((x), 20, 16)
#define PSC_REG_MDCFG_GET_RESET_ISO(x) boot_read_bitfield((x), 14, 14)
/* MDCTL */
#define PSC_REG_MDCTL_SET_NEXT(x, y) boot_set_bitfield((x), (y), 4, 0)
#define PSC_REG_MDCTL_SET_LRSTZ(x, y) boot_set_bitfield((x), (y), 8, 8)
#define PSC_REG_MDCTL_GET_LRSTZ(x) boot_read_bitfield((x), 8, 8)
#define PSC_REG_MDCTL_SET_RESET_ISO(x, y) boot_set_bitfield((x), (y), \
12, 12)
/* MDSTAT */
#define PSC_REG_MDSTAT_GET_STATUS(x) boot_read_bitfield((x), 5, 0)
#define PSC_REG_MDSTAT_GET_LRSTZ(x) boot_read_bitfield((x), 8, 8)
#define PSC_REG_MDSTAT_GET_LRSTDONE(x) boot_read_bitfield((x), 9, 9)
#define PSC_REG_MDSTAT_GET_MRSTZ(x) boot_read_bitfield((x), 10, 10)
#define PSC_REG_MDSTAT_GET_MRSTDONE(x) boot_read_bitfield((x), 11, 11)
/* PDCTL states */
#define PSC_REG_VAL_PDCTL_NEXT_ON 1
#define PSC_REG_VAL_PDCTL_NEXT_OFF 0
#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP 0
/* MDCTL states */
#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE 0
#define PSC_REG_VAL_MDCTL_NEXT_OFF 2
#define PSC_REG_VAL_MDCTL_NEXT_ON 3
/* MDSTAT states */
#define PSC_REG_VAL_MDSTAT_STATE_ON 3
#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG 0x24
#define PSC_REG_VAL_MDSTAT_STATE_OFF 2
#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1 0x20
#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2 0x21
#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3 0x22
/*
* Timeout limit on checking PTSTAT. This is the number of times the
* wait function will be called before giving up.
*/
#define PSC_PTSTAT_TIMEOUT_LIMIT 100000
u32 psc_get_domain_num(u32 mod_num);
int psc_enable_module(u32 mod_num);
int psc_disable_module(u32 mod_num);
int psc_disable_domain(u32 domain_num);
int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks);
int psc_module_release_from_reset(u32 mod_num);
#endif /* _PSC_DEFS_H_ */
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* USB 3.0 DRD Controller
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#define USB3_PHY_REF_SSP_EN BIT(29)
#define USB3_PHY_OTG_VBUSVLDECTSEL BIT(16)
/* KEYSTONE2 XHCI PHY register structure */
struct keystone_xhci_phy {
unsigned int phy_utmi; /* ctl0 */
unsigned int phy_pipe; /* ctl1 */
unsigned int phy_param_ctrl_1; /* ctl2 */
unsigned int phy_param_ctrl_2; /* ctl3 */
unsigned int phy_clock; /* ctl4 */
unsigned int phy_pll; /* ctl5 */
};
@@ -0,0 +1,260 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone2: Architecture initialization
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <cpu_func.h>
#include <ns16550.h>
#include <asm/io.h>
#include <asm/arch/msmc.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/psc_defs.h>
#define MAX_PCI_PORTS 2
enum pci_mode {
ENDPOINT,
LEGACY_ENDPOINT,
ROOTCOMPLEX,
};
#define DEVCFG_MODE_MASK (BIT(2) | BIT(1))
#define DEVCFG_MODE_SHIFT 1
void chip_configuration_unlock(void)
{
__raw_writel(KS2_KICK0_MAGIC, KS2_KICK0);
__raw_writel(KS2_KICK1_MAGIC, KS2_KICK1);
}
#ifdef CONFIG_SOC_K2L
void osr_init(void)
{
u32 i;
u32 j;
u32 val;
u32 base = KS2_OSR_CFG_BASE;
u32 ecc_ctrl[KS2_OSR_NUM_RAM_BANKS];
/* Enable the OSR clock domain */
psc_enable_module(KS2_LPSC_OSR);
/* Disable OSR ECC check for all the ram banks */
for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) {
val = i | KS2_OSR_ECC_VEC_TRIG_RD |
(KS2_OSR_ECC_CTRL << KS2_OSR_ECC_VEC_RD_ADDR_SH);
writel(val , base + KS2_OSR_ECC_VEC);
/**
* wait till read is done.
* Print should be added after earlyprintk support is added.
*/
for (j = 0; j < 10000; j++) {
val = readl(base + KS2_OSR_ECC_VEC);
if (val & KS2_OSR_ECC_VEC_RD_DONE)
break;
}
ecc_ctrl[i] = readl(base + KS2_OSR_ECC_CTRL) ^
KS2_OSR_ECC_CTRL_CHK;
writel(ecc_ctrl[i], KS2_MSMC_DATA_BASE + i * 4);
writel(ecc_ctrl[i], base + KS2_OSR_ECC_CTRL);
}
/* Reset OSR memory to all zeros */
for (i = 0; i < KS2_OSR_SIZE; i += 4)
writel(0, KS2_OSR_DATA_BASE + i);
/* Enable OSR ECC check for all the ram banks */
for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++)
writel(ecc_ctrl[i] |
KS2_OSR_ECC_CTRL_CHK, base + KS2_OSR_ECC_CTRL);
}
#endif
/* Function to set up PCIe mode */
static void config_pcie_mode(int pcie_port, enum pci_mode mode)
{
u32 val = __raw_readl(KS2_DEVCFG);
if (pcie_port >= MAX_PCI_PORTS)
return;
/**
* each pci port has two bits for mode and it starts at
* bit 1. So use port number to get the right bit position.
*/
pcie_port <<= 1;
val &= ~(DEVCFG_MODE_MASK << pcie_port);
val |= ((mode << DEVCFG_MODE_SHIFT) << pcie_port);
__raw_writel(val, KS2_DEVCFG);
}
static void msmc_k2hkle_common_setup(void)
{
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_0);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_ARM);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_NETCP);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_QM_PDSP);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_PCIE0);
msmc_share_all_segments(KS2_MSMC_SEGMENT_DEBUG);
}
static void msmc_k2hk_setup(void)
{
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_1);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_2);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_3);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_4);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_5);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_6);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_7);
msmc_share_all_segments(K2HKE_MSMC_SEGMENT_HYPERLINK);
}
static inline void msmc_k2l_setup(void)
{
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_1);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_2);
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_3);
msmc_share_all_segments(K2L_MSMC_SEGMENT_PCIE1);
}
static inline void msmc_k2e_setup(void)
{
msmc_share_all_segments(K2E_MSMC_SEGMENT_PCIE1);
msmc_share_all_segments(K2HKE_MSMC_SEGMENT_HYPERLINK);
msmc_share_all_segments(K2E_MSMC_SEGMENT_TSIP);
}
static void msmc_k2g_setup(void)
{
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_0);
msmc_share_all_segments(K2G_MSMC_SEGMENT_ARM);
msmc_share_all_segments(K2G_MSMC_SEGMENT_ICSS0);
msmc_share_all_segments(K2G_MSMC_SEGMENT_ICSS1);
msmc_share_all_segments(K2G_MSMC_SEGMENT_NSS);
msmc_share_all_segments(K2G_MSMC_SEGMENT_PCIE);
msmc_share_all_segments(K2G_MSMC_SEGMENT_USB);
msmc_share_all_segments(K2G_MSMC_SEGMENT_MLB);
msmc_share_all_segments(K2G_MSMC_SEGMENT_PMMC);
msmc_share_all_segments(K2G_MSMC_SEGMENT_DSS);
msmc_share_all_segments(K2G_MSMC_SEGMENT_MMC);
msmc_share_all_segments(KS2_MSMC_SEGMENT_DEBUG);
}
int arch_cpu_init(void)
{
chip_configuration_unlock();
icache_enable();
if (cpu_is_k2g()) {
msmc_k2g_setup();
} else {
msmc_k2hkle_common_setup();
if (cpu_is_k2e())
msmc_k2e_setup();
else if (cpu_is_k2l())
msmc_k2l_setup();
else
msmc_k2hk_setup();
}
/* Initialize the PCIe-0 to work as Root Complex */
config_pcie_mode(0, ROOTCOMPLEX);
#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L)
/* Initialize the PCIe-1 to work as Root Complex */
config_pcie_mode(1, ROOTCOMPLEX);
#endif
#ifdef CONFIG_SOC_K2L
osr_init();
#endif
/*
* just initialise the COM2 port so that TI specific
* UART register PWREMU_MGMT is initialized. Linux UART
* driver doesn't handle this.
*/
#ifndef CONFIG_DM_SERIAL
NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2),
CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
#endif
return 0;
}
void reset_cpu(ulong addr)
{
volatile u32 *rstctrl = (volatile u32 *)(KS2_RSTCTRL);
u32 tmp;
tmp = *rstctrl & KS2_RSTCTRL_MASK;
*rstctrl = tmp | KS2_RSTCTRL_KEY;
*rstctrl &= KS2_RSTCTRL_SWRST;
for (;;)
;
}
void enable_caches(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
#endif
}
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
u16 cpu = get_part_number();
u8 rev = cpu_revision();
puts("CPU: ");
switch (cpu) {
case CPU_66AK2Hx:
puts("66AK2Hx SR");
break;
case CPU_66AK2Lx:
puts("66AK2Lx SR");
break;
case CPU_66AK2Ex:
puts("66AK2Ex SR");
break;
case CPU_66AK2Gx:
puts("66AK2Gx");
#ifdef CONFIG_SOC_K2G
{
int speed = get_max_arm_speed(speeds);
if (speed == SPD1000)
puts("-100 ");
else if (speed == SPD600)
puts("-60 ");
else
puts("-xx ");
}
#endif
puts("SR");
break;
default:
puts("Unknown\n");
}
if (rev == 2)
puts("2.0\n");
else if (rev == 1)
puts("1.1\n");
else if (rev == 0)
puts("1.0\n");
else if (rev == 8)
puts("1.0\n");
return 0;
}
#endif
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone EVM : Board initialization
*
* (C) Copyright 2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/psc_defs.h>
#include <asm/arch/hardware.h>
/**
* cpu_to_bus - swap bytes of the 32-bit data if the device is BE
* @ptr - array of data
* @length - lenght of data array
*/
int cpu_to_bus(u32 *ptr, u32 length)
{
u32 i;
if (!(readl(KS2_DEVSTAT) & 0x1))
for (i = 0; i < length; i++, ptr++)
*ptr = cpu_to_be32(*ptr);
return 0;
}
static void turn_off_all_dsps(int num_dsps)
{
int i;
for (i = 0; i < num_dsps; i++) {
if (psc_disable_module(i + KS2_LPSC_GEM_0))
printf("Cannot disable module for #%d DSP", i);
if (psc_disable_domain(i + KS2_GEM_0_PWR_DOMAIN))
printf("Cannot disable domain for #%d DSP", i);
}
}
int misc_init_r(void)
{
char *env;
long ks2_debug = 0;
env = env_get("ks2_debug");
if (env)
ks2_debug = simple_strtol(env, NULL, 0);
if ((ks2_debug & DBG_LEAVE_DSPS_ON) == 0)
turn_off_all_dsps(KS2_NUM_DSPS);
return 0;
}
@@ -0,0 +1,140 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* K2x: Secure commands file
*
* Copyright (C) 2012-2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include <asm/unaligned.h>
#include <common.h>
#include <command.h>
#include <mach/mon.h>
#include <spl.h>
asm(".arch_extension sec\n\t");
int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr)
{
int result;
__asm__ __volatile__ (
"stmfd r13!, {lr}\n"
"mov r0, %1\n"
"mov r1, %2\n"
"mov r2, %3\n"
"mov r3, %4\n"
"blx r0\n"
"mov %0, r0\n"
"ldmfd r13!, {lr}\n"
: "=&r" (result)
: "r" (addr), "r" (dpsc), "r" (freq), "r" (bm_addr)
: "cc", "r0", "r1", "r2", "r3", "memory");
return result;
}
int mon_power_on(int core_id, void *ep)
{
int result;
asm volatile (
"stmfd r13!, {lr}\n"
"mov r1, %1\n"
"mov r2, %2\n"
"mov r0, #0\n"
"smc #0\n"
"mov %0, r0\n"
"ldmfd r13!, {lr}\n"
: "=&r" (result)
: "r" (core_id), "r" (ep)
: "cc", "r0", "r1", "r2", "memory");
return result;
}
int mon_power_off(int core_id)
{
int result;
asm volatile (
"stmfd r13!, {lr}\n"
"mov r1, %1\n"
"mov r0, #1\n"
"smc #1\n"
"mov %0, r0\n"
"ldmfd r13!, {lr}\n"
: "=&r" (result)
: "r" (core_id)
: "cc", "r0", "r1", "memory");
return result;
}
#ifdef CONFIG_TI_SECURE_DEVICE
#define KS2_HS_SEC_HEADER_LEN 0x60
#define KS2_HS_SEC_TAG_OFFSET 0x34
#define KS2_AUTH_CMD 130
/**
* k2_hs_bm_auth() - Invokes security functions using a
* proprietary TI interface. This binary and source for
* this is available in the secure development package or
* SECDEV. For details on how to access this please refer
* doc/README.ti-secure
*
* @cmd: Secure monitor command
* @arg1: Argument for command
*
* returns non-zero value on success, zero on error
*/
static int k2_hs_bm_auth(int cmd, void *arg1)
{
int result;
asm volatile (
"stmfd r13!, {r4-r12, lr}\n"
"mov r0, %1\n"
"mov r1, %2\n"
"smc #2\n"
"mov %0, r0\n"
"ldmfd r13!, {r4-r12, lr}\n"
: "=&r" (result)
: "r" (cmd), "r" (arg1)
: "cc", "r0", "r1", "memory");
return result;
}
void board_fit_image_post_process(void **p_image, size_t *p_size)
{
int result = 0;
void *image = *p_image;
if (strncmp(image + KS2_HS_SEC_TAG_OFFSET, "KEYS", 4)) {
printf("No signature found in image!\n");
hang();
}
result = k2_hs_bm_auth(KS2_AUTH_CMD, image);
if (result == 0) {
printf("Authentication failed!\n");
hang();
}
/*
* Overwrite the image headers after authentication
* and decryption. Update size to reflect removal
* of header and restore original file size.
*/
*p_size = get_unaligned_le32(image + (*p_size - 4));
memcpy(image, image + KS2_HS_SEC_HEADER_LEN, *p_size);
/*
* Output notification of successful authentication to re-assure the
* user that the secure code is being processed as expected. However
* suppress any such log output in case of building for SPL and booting
* via YMODEM. This is done to avoid disturbing the YMODEM serial
* protocol transactions.
*/
if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
spl_boot_device() == BOOT_DEVICE_UART))
printf("Authentication passed\n");
}
#endif
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* MSMC controller utilities
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <asm/arch/msmc.h>
struct mpax {
u32 mpaxl;
u32 mpaxh;
};
struct msms_regs {
u32 pid;
u32 _res_04;
u32 smcerrar;
u32 smcerrxr;
u32 smedcc;
u32 smcea;
u32 smsecc;
u32 smpfar;
u32 smpfxr;
u32 smpfr;
u32 smpfcr;
u32 _res_2c;
u32 sbndc[8];
u32 sbndm;
u32 sbnde;
u32 _res_58;
u32 cfglck;
u32 cfgulck;
u32 cfglckstat;
u32 sms_mpax_lck;
u32 sms_mpax_ulck;
u32 sms_mpax_lckstat;
u32 ses_mpax_lck;
u32 ses_mpax_ulck;
u32 ses_mpax_lckstat;
u32 smestat;
u32 smirstat;
u32 smirc;
u32 smiestat;
u32 smiec;
u32 _res_94_c0[12];
u32 smncerrar;
u32 smncerrxr;
u32 smncea;
u32 _res_d0_1fc[76];
struct mpax sms[16][8];
struct mpax ses[16][8];
};
void msmc_share_all_segments(int priv_id)
{
struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
int j;
for (j = 0; j < 8; j++) {
msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful;
msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful;
}
}
void msmc_map_ses_segment(int priv_id, int ses_pair,
u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size)
{
struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
msmc->ses[priv_id][ses_pair].mpaxh = src_pfn << 12 |
(size & 0x1f) | 0x80;
msmc->ses[priv_id][ses_pair].mpaxl = dst_pfn << 8 | 0x3f;
}
void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax)
{
struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
*mpax++ = msmc->ses[priv_id][ses_pair].mpaxl;
*mpax = msmc->ses[priv_id][ses_pair].mpaxh;
}
void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax)
{
struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
msmc->ses[priv_id][ses_pair].mpaxl = *mpax++;
msmc->ses[priv_id][ses_pair].mpaxh = *mpax;
}
@@ -0,0 +1,338 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Keystone: PSC configuration module
*
* (C) Copyright 2012-2014
* Texas Instruments Incorporated, <www.ti.com>
*/
#include <common.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/arch/psc_defs.h>
/**
* psc_delay() - delay for psc
*
* Return: 10
*/
int psc_delay(void)
{
udelay(10);
return 10;
}
/**
* psc_wait() - Wait for end of transitional state
* @domain_num: GPSC domain number
*
* Polls pstat for the selected domain and waits for transitions to be complete.
* Since this is boot loader code it is *ASSUMED* that interrupts are disabled
* and no other core is mucking around with the psc at the same time.
*
* Return: 0 when the domain is free. Returns -1 if a timeout occurred waiting
* for the completion.
*/
int psc_wait(u32 domain_num)
{
u32 retry;
u32 ptstat;
/*
* Do nothing if the power domain is in transition. This should never
* happen since the boot code is the only software accesses psc.
* It's still remotely possible that the hardware state machines
* initiate transitions.
* Don't trap if the domain (or a module in this domain) is
* stuck in transition.
*/
retry = 0;
do {
ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
ptstat = ptstat & (1 << domain_num);
} while ((ptstat != 0) && ((retry += psc_delay()) <
PSC_PTSTAT_TIMEOUT_LIMIT));
if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
return -1;
return 0;
}
/**
* psc_get_domain_num() - Get the domain number
* @mod_num: LPSC module number
*/
u32 psc_get_domain_num(u32 mod_num)
{
u32 domain_num;
/* Get the power domain associated with the module number */
domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
return domain_num;
}
/**
* psc_set_state() - powers up/down a module
* @mod_num: LPSC module number
* @state: 1 to enable, 0 to disable.
*
* Powers up/down the requested module and the associated power domain if
* required. No action is taken it the module is already powered up/down.
* This only controls modules. The domain in which the module resides will
* be left in the power on state. Multiple modules can exist in a power
* domain, so powering down the domain based on a single module is not done.
*
* Return: 0 on success, -1 if the module can't be powered up, or if there is a
* timeout waiting for the transition.
*/
int psc_set_state(u32 mod_num, u32 state)
{
u32 domain_num;
u32 pdctl;
u32 mdctl;
u32 ptcmd;
u32 reset_iso;
u32 v;
/*
* Get the power domain associated with the module number, and reset
* isolation functionality
*/
v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
domain_num = PSC_REG_MDCFG_GET_PD(v);
reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v);
/* Wait for the status of the domain/module to be non-transitional */
if (psc_wait(domain_num) != 0)
return -1;
/*
* Perform configuration even if the current status matches the
* existing state
*
* Set the next state of the power domain to on. It's OK if the domain
* is always on. This code will not ever power down a domain, so no
* change is made if the new state is power down.
*/
if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
PSC_REG_VAL_PDCTL_NEXT_ON);
__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
}
/* Set the next state for the module to enabled/disabled */
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Trigger the enable */
ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
ptcmd |= (u32)(1<<domain_num);
__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
/* Wait on the complete */
return psc_wait(domain_num);
}
/**
* psc_enable_module() - power up a module
* @mod_num: LPSC module number
*
* Powers up the requested module and the associated power domain
* if required. No action is taken it the module is already powered up.
*
* Return: 0 on success, -1 if the module can't be powered up, or
* if there is a timeout waiting for the transition.
*
*/
int psc_enable_module(u32 mod_num)
{
u32 mdctl;
/* Set the bit to apply reset */
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
return 0;
return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
}
/**
* psc_disable_module() - Power down a module
* @mod_num: LPSC module number
*
* Return: 0 on success, -1 on failure or timeout.
*/
int psc_disable_module(u32 mod_num)
{
u32 mdctl;
/* Set the bit to apply reset */
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
if ((mdctl & 0x3f) == 0)
return 0;
mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
}
/**
* psc_set_reset_iso() - Set the reset isolation bit in mdctl
* @mod_num: LPSC module number
*
* The reset isolation enable bit is set. The state of the module is not
* changed.
*
* Return: 0 if the module config showed that reset isolation is supported.
* Returns 1 otherwise. This is not an error, but setting the bit in mdctl
* has no effect.
*/
int psc_set_reset_iso(u32 mod_num)
{
u32 v;
u32 mdctl;
/* Set the reset isolation bit */
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
return 0;
return 1;
}
/**
* psc_disable_domain() - Disable a power domain
* @domain_num: GPSC domain number
*/
int psc_disable_domain(u32 domain_num)
{
u32 pdctl;
u32 ptcmd;
pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
ptcmd |= (u32)(1 << domain_num);
__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
return psc_wait(domain_num);
}
/**
* psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state
* @mod_num: LPSC module number
* @gate_clocks: Can the clocks be gated on this module?
*
* Enable the module, but do not release the module from local reset. This is
* necessary for many processor systems on keystone SoCs to allow for system
* initialization from a master processor prior to releasing the processor
* from reset.
*/
int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks)
{
u32 mdctl, ptcmd, mdstat;
u32 next_state;
int domain_num = psc_get_domain_num(mod_num);
int timeout = 100000;
/* Wait for any previous transitions to complete */
psc_wait(domain_num);
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Should be set 0 to assert Local reset */
if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) {
mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Wait for transition to take place */
psc_wait(domain_num);
}
/* Clear Module reset */
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
PSC_REG_VAL_MDCTL_NEXT_ON;
mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Trigger PD transition */
ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
ptcmd |= (u32)(1 << domain_num);
__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
psc_wait(domain_num);
mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
while (timeout) {
mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
break;
timeout--;
}
if (!timeout) {
printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
__func__, mdstat);
return -ETIMEDOUT;
}
return 0;
}
/**
* psc_module_release_from_reset() - Release the module from reset
* @mod_num: LPSC module number
*
* This is the follow through for the command 'psc_module_keep_in_reset_enabled'
* Allowing the module to be released from reset once all required inits are
* complete for the module. Typically, this allows the processor module to start
* execution.
*/
int psc_module_release_from_reset(u32 mod_num)
{
u32 mdctl, mdstat;
int domain_num = psc_get_domain_num(mod_num);
int timeout = 100000;
/* Wait for any previous transitions to complete */
psc_wait(domain_num);
mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Should be set to 1 to de-assert Local reset */
if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) {
mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1);
__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
/* Wait for transition to take place */
psc_wait(domain_num);
}
mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
while (timeout) {
mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
break;
timeout--;
}
if (!timeout) {
printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
__func__, mdstat);
return -ETIMEDOUT;
}
return 0;
}