From: Masahiro Yamada Date: Fri, 20 Feb 2015 08:04:11 +0000 (+0900) Subject: ARM: keystone: move SoC sources to mach-keystone X-Git-Tag: v2015.04-rc3~43 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=39a723452f430a7ef89b0ffa934b2d4312890076;p=u-boot ARM: keystone: move SoC sources to mach-keystone Move arch/arm/cpu/armv7/keystone/* -> arch/arm/mach-keystone/* Signed-off-by: Masahiro Yamada Cc: Tom Rini --- diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9302b2a0b6..083823e8c4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -724,7 +724,7 @@ source "arch/arm/cpu/armv7/exynos/Kconfig" source "arch/arm/mach-highbank/Kconfig" -source "arch/arm/cpu/armv7/keystone/Kconfig" +source "arch/arm/mach-keystone/Kconfig" source "arch/arm/mach-kirkwood/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0699a4d472..678ac132aa 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -7,6 +7,7 @@ machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_DAVINCI) += davinci machine-$(CONFIG_ARCH_HIGHBANK) += highbank +machine-$(CONFIG_ARCH_KEYSTONE) += keystone # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 29ba6e2125..1a76982d6e 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -43,7 +43,6 @@ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ obj-$(CONFIG_ARCH_EXYNOS) += exynos/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/ obj-$(if $(filter mx5,$(SOC)),y) += mx5/ obj-$(CONFIG_MX6) += mx6/ diff --git a/arch/arm/cpu/armv7/keystone/Kconfig b/arch/arm/cpu/armv7/keystone/Kconfig deleted file mode 100644 index 134ae87fe1..0000000000 --- a/arch/arm/cpu/armv7/keystone/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -if ARCH_KEYSTONE - -choice - prompt "TI Keystone board select" - -config TARGET_K2HK_EVM - bool "TI Keystone 2 Kepler/Hawking EVM" - -config TARGET_K2E_EVM - bool "TI Keystone 2 Edison EVM" - -config TARGET_K2L_EVM - bool "TI Keystone 2 Lamar EVM" - -endchoice - -config SYS_SOC - default "keystone" - -source "board/ti/ks2_evm/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile deleted file mode 100644 index ed030db2c8..0000000000 --- a/arch/arm/cpu/armv7/keystone/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# (C) Copyright 2012-2014 -# Texas Instruments Incorporated, -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += init.o -obj-y += psc.o -obj-y += clock.o -obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o -obj-$(CONFIG_SOC_K2E) += clock-k2e.o -obj-$(CONFIG_SOC_K2L) += clock-k2l.o -obj-y += cmd_clock.o -obj-y += cmd_mon.o -obj-y += msmc.o -obj-y += ddr3.o cmd_ddr3.o -obj-y += keystone.o diff --git a/arch/arm/cpu/armv7/keystone/clock-k2e.c b/arch/arm/cpu/armv7/keystone/clock-k2e.c deleted file mode 100644 index 31f66613ef..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2e.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Keystone2: get clk rate for K2E - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -const struct keystone_pll_regs keystone_pll_regs[] = { - [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, - [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, - [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, -}; - -int dev_speeds[] = { - SPD800, - SPD850, - SPD1000, - SPD1250, - SPD1350, - SPD1400, - SPD1500, - SPD1400, - SPD1350, - SPD1250, - SPD1000, - SPD850, - SPD800 -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @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 == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c deleted file mode 100644 index 1591960795..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2hk.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Keystone2: get clk rate for K2HK - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -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}, -}; - -int dev_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD800, - SPD800, - SPD800, - SPD800, - SPD800, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -int arm_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD800, - SPD1400, - SPD1350, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @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 == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3A_PLL: - ret = external_clk[ddr3a_clk]; - reg = KS2_DDR3APLLCTL0; - break; - case DDR3B_PLL: - ret = external_clk[ddr3b_clk]; - reg = KS2_DDR3BPLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3a_pll_clk: return pll_freq_get(DDR3A_PLL); - case ddr3b_pll_clk: return pll_freq_get(DDR3B_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock-k2l.c b/arch/arm/cpu/armv7/keystone/clock-k2l.c deleted file mode 100644 index 1c5e4d54d8..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2l.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Keystone2: get clk rate for K2L - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -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}, - [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, -}; - -int dev_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD800, - SPD800, - SPD800, - SPD800, - SPD800, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -int arm_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD800, - SPD1400, - SPD1350, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @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 == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c deleted file mode 100644 index d13fbc1a4b..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Keystone2: pll initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define MAX_SPEEDS 13 - -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_GO) == 0) - break; - } -} - -void init_pll(const struct pll_init_data *data) -{ - u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj; - - pllm = data->pll_m - 1; - plld = (data->pll_d - 1) & PLL_DIV_MASK; - pllod = (data->pll_od - 1) & PLL_CLKOD_MASK; - - if (data->pll == MAIN_PLL) { - /* The requered delay before main PLL configuration */ - sdelay(210000); - - tmp = pllctl_reg_read(data->pll, secctl); - - if (tmp & (PLLCTL_BYPASS)) { - setbits_le32(keystone_pll_regs[data->pll].reg1, - BIT(MAIN_ENSAT_OFFSET)); - - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | - PLLCTL_PLLENSRC); - sdelay(340); - - pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS); - pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN); - sdelay(21000); - - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN); - } else { - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | - PLLCTL_PLLENSRC); - sdelay(340); - } - - pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK); - - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLLM_MULT_HI_SMASK, (pllm << 6)); - - /* Set the BWADJ (12 bit field) */ - tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */ - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLL_BWADJ_LO_SMASK, - (tmp_ctl << PLL_BWADJ_LO_SHIFT)); - clrsetbits_le32(keystone_pll_regs[data->pll].reg1, - PLL_BWADJ_HI_MASK, - (tmp_ctl >> 8)); - - /* - * Set the pll divider (6 bit field) * - * PLLD[5:0] is located in MAINPLLCTL0 - */ - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLL_DIV_MASK, plld); - - /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */ - pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK, - (pllod << PLL_CLKOD_SHIFT)); - wait_for_completion(data); - - pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1); - pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2); - pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3); - pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4); - pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5); - - pllctl_reg_setbits(data->pll, alnctl, 0x1f); - - /* - * Set GOSET bit in PLLCMD to initiate the GO operation - * to change the divide - */ - pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO); - sdelay(1500); /* wait for the phase adj */ - wait_for_completion(data); - - /* Reset PLL */ - pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST); - sdelay(21000); /* Wait for a minimum of 7 us*/ - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST); - sdelay(105000); /* Wait for PLL Lock time (min 50 us) */ - - pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS); - - tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN); - -#ifndef CONFIG_SOC_K2E - } else if (data->pll == TETRIS_PLL) { - bwadj = pllm >> 1; - /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ - setbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - /* - * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass) - * only applicable for Kepler - */ - clrbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); - /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */ - setbits_le32(keystone_pll_regs[data->pll].reg1 , - PLL_PLLRST | PLLCTL_ENSAT); - - /* - * 3 Program PLLM and PLLD in PLLCTL0 register - * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in - * PLLCTL1 register. BWADJ value must be set - * to ((PLLM + 1) >> 1) – 1) - */ - tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | - (pllm << 6) | - (plld & PLL_DIV_MASK) | - (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS; - __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); - - /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); - tmp &= ~(PLL_BWADJ_HI_MASK); - tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); - __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); - /* - * 5 Wait for at least 5 us based on the reference - * clock (PLL reset time) - */ - sdelay(21000); /* Wait for a minimum of 7 us*/ - - /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */ - clrbits_le32(keystone_pll_regs[data->pll].reg1, PLL_PLLRST); - /* - * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1) - * (PLL lock time) - */ - sdelay(105000); - /* 8 disable bypass */ - clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - /* - * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass) - * only applicable for Kepler - */ - setbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); -#endif - } else { - setbits_le32(keystone_pll_regs[data->pll].reg1, PLLCTL_ENSAT); - /* - * process keeps state of Bypass bit while programming - * all other DDR PLL settings - */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg0); - tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */ - - /* - * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0, - * bypass disabled - */ - bwadj = pllm >> 1; - tmp |= ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | - (pllm << PLL_MULT_SHIFT) | - (plld & PLL_DIV_MASK) | - (pllod << PLL_CLKOD_SHIFT); - __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); - - /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); - tmp &= ~(PLL_BWADJ_HI_MASK); - tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); - - __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); - - /* Reset bit: bit 14 for both DDR3 & PASS PLL */ - tmp = PLL_PLLRST; - /* Set RESET bit = 1 */ - setbits_le32(keystone_pll_regs[data->pll].reg1, tmp); - /* Wait for a minimum of 7 us*/ - sdelay(21000); - /* Clear RESET bit */ - clrbits_le32(keystone_pll_regs[data->pll].reg1, tmp); - sdelay(105000); - - /* clear BYPASS (Enable PLL Mode) */ - clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - sdelay(21000); /* Wait for a minimum of 7 us*/ - } - - /* - * This is required to provide a delay between multiple - * consequent PPL configurations - */ - sdelay(210000); -} - -void init_plls(int num_pll, struct pll_init_data *config) -{ - int i; - - for (i = 0; i < num_pll; i++) - init_pll(&config[i]); -} - -static int get_max_speed(u32 val, int *speeds) -{ - int j; - - if (!val) - return speeds[0]; - - for (j = 1; j < MAX_SPEEDS; j++) { - if (val == 1) - return speeds[j]; - val >>= 1; - } - - return SPD800; -} - -#ifdef CONFIG_SOC_K2HK -static u32 read_efuse_bootrom(void) -{ - return (cpu_revision() > 1) ? __raw_readl(KS2_EFUSE_BOOTROM) : - __raw_readl(KS2_REV1_DEVSPEED); -} -#else -static inline u32 read_efuse_bootrom(void) -{ - return __raw_readl(KS2_EFUSE_BOOTROM); -} -#endif - -inline int get_max_dev_speed(void) -{ - return get_max_speed(read_efuse_bootrom() & 0xffff, dev_speeds); -} - -#ifndef CONFIG_SOC_K2E -inline int get_max_arm_speed(void) -{ - return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds); -} -#endif - -void pass_pll_pa_clk_enable(void) -{ - u32 reg; - - reg = readl(keystone_pll_regs[PASS_PLL].reg1); - - reg |= PLLCTL_PAPLL; - writel(reg, keystone_pll_regs[PASS_PLL].reg1); - - /* wait till clock is enabled */ - sdelay(15000); -} diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c deleted file mode 100644 index af1b701e82..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_clock.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * keystone2: commands for clocks - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -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 "
\n" -); - -int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - unsigned int clk; - unsigned int freq; - - if (argc != 2) - goto getclk_cmd_usage; - - clk = simple_strtoul(argv[1], NULL, 10); - - freq = clk_get_rate(clk); - printf("clock index [%d] - frequency %u\n", clk, freq); - return 0; - -getclk_cmd_usage: - return cmd_usage(cmdtp); -} - -U_BOOT_CMD( - getclk, 2, 0, do_getclk_cmd, - "get clock rate", - "\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, - "", - " \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" -); diff --git a/arch/arm/cpu/armv7/keystone/cmd_ddr3.c b/arch/arm/cpu/armv7/keystone/cmd_ddr3.c deleted file mode 100644 index ea78ad8fd5..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_ddr3.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Keystone2: DDR3 test commands - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE - -#define DDR_REMAP_ADDR 0x80000000 -#define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17) - -#define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \ - CONFIG_STACKSIZE) >> 17) - 2) - -#define DDR_TEST_BURST_SIZE 1024 - -static int ddr_memory_test(u32 start_address, u32 end_address, int quick) -{ - u32 index_start, value, index; - - index_start = start_address; - - while (1) { - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) - __raw_writel(index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) { - value = __raw_readl(index); - if (value != index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readl(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - if (quick) - continue; - - /* Write a pattern for complementary values */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) - __raw_writel((u32)~index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) { - value = __raw_readl(index); - if (value != ~index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readl(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 2) - __raw_writew((u16)index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 2) { - value = __raw_readw(index); - if (value != (u16)index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readw(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 1) - __raw_writeb((u8)index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 1) { - value = __raw_readb(index); - if (value != (u8)index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readb(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - } - - puts("ddr memory test PASSED!\n"); - return 0; -} - -static int ddr_memory_compare(u32 address1, u32 address2, u32 size) -{ - u32 index, value, index2, value2; - - for (index = address1, index2 = address2; - index < address1 + size; - index += 4, index2 += 4) { - value = __raw_readl(index); - value2 = __raw_readl(index2); - - if (value != value2) { - printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n", - index, value, index2, value2); - - return -1; - } - } - - puts("ddr memory compare PASSED!\n"); - return 0; -} - -static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err) -{ - u32 value1, value2, value3; - - puts("Disabling DDR ECC ...\n"); - ddr3_disable_ecc(base); - - value1 = __raw_readl(address); - value2 = value1 ^ ecc_err; - __raw_writel(value2, address); - - value3 = __raw_readl(address); - printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n", - address, value1, value2, ecc_err, value3); - - __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16), - base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); - - puts("Enabling DDR ECC ...\n"); - ddr3_enable_ecc(base, 1); - - value1 = __raw_readl(address); - printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1); - - ddr3_check_ecc_int(base); - return 0; -} - -static int do_ddr_test(cmd_tbl_t *cmdtp, - int flag, int argc, char * const argv[]) -{ - u32 start_addr, end_addr, size, ecc_err; - - if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) { - if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) { - puts("ECC RMW isn't supported for this SOC\n"); - return 1; - } - - start_addr = simple_strtoul(argv[2], NULL, 16); - ecc_err = simple_strtoul(argv[3], NULL, 16); - - if ((start_addr < CONFIG_SYS_SDRAM_BASE) || - (start_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1))) { - puts("Invalid address!\n"); - return cmd_usage(cmdtp); - } - - ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE, - start_addr, ecc_err); - return 0; - } - - if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) || - ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0)))) - return cmd_usage(cmdtp); - - start_addr = simple_strtoul(argv[2], NULL, 16); - end_addr = simple_strtoul(argv[3], NULL, 16); - - if ((start_addr < CONFIG_SYS_SDRAM_BASE) || - (start_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1)) || - (end_addr < CONFIG_SYS_SDRAM_BASE) || - (end_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) { - puts("Invalid start or end address!\n"); - return cmd_usage(cmdtp); - } - - puts("Please wait ...\n"); - if (argc == 5) { - size = simple_strtoul(argv[4], NULL, 16); - ddr_memory_compare(start_addr, end_addr, size); - } else { - ddr_memory_test(start_addr, end_addr, 0); - } - - return 0; -} - -U_BOOT_CMD(ddr, 5, 1, do_ddr_test, - "DDR3 test", - "test - test DDR from start\n" - " address to end address\n" - "ddr compare -\n" - " compare DDR data of (size) bytes from start address to end\n" - " address\n" - "ddr ecc_err - generate bit errors\n" - " in DDR data at , the command will read a 32-bit data\n" - " from , and write (data ^ bit_err) back to \n" -); diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c deleted file mode 100644 index f9f58a37df..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_mon.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * K2HK: secure kernel command file - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -asm(".arch_extension sec\n\t"); - -static int mon_install(u32 addr, u32 dpsc, u32 freq) -{ - int result; - - __asm__ __volatile__ ( - "stmfd r13!, {lr}\n" - "mov r0, %1\n" - "mov r1, %2\n" - "mov r2, %3\n" - "blx r0\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (addr), "r" (dpsc), "r" (freq) - : "cc", "r0", "r1", "r2", "memory"); - return result; -} - -static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - u32 addr, dpsc_base = 0x1E80000, freq; - int rcode = 0; - - if (argc < 2) - return CMD_RET_USAGE; - - freq = clk_get_rate(sys_clk0_6_clk); - - addr = simple_strtoul(argv[1], NULL, 16); - - rcode = mon_install(addr, dpsc_base, freq); - printf("## installed monitor, freq [%d], status %d\n", - freq, rcode); - - return 0; -} - -U_BOOT_CMD(mon_install, 2, 0, do_mon_install, - "Install boot kernel at 'addr'", - "" -); - -static void core_spin(void) -{ - while (1) - ; /* forever */; -} - -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" - "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" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (core_id) - : "cc", "r0", "r1", "memory"); - return result; -} - -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 \n" - "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n" - "" -); diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c deleted file mode 100644 index dfb27b5ba2..0000000000 --- a/arch/arm/cpu/armv7/keystone/ddr3.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Keystone2: DDR3 initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -#include - -#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) - ; - - __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 */ - msmc_get_ses_mpax(8, 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 */ - msmc_map_ses_segment(8, 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 */ - msmc_set_ses_mpax(8, 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 = getenv("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 diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c deleted file mode 100644 index c96845c4e2..0000000000 --- a/arch/arm/cpu/armv7/keystone/init.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Keystone2: Architecture initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#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); -} - -int arch_cpu_init(void) -{ - chip_configuration_unlock(); - icache_enable(); - - msmc_share_all_segments(KS2_MSMC_SEGMENT_TETRIS); - msmc_share_all_segments(KS2_MSMC_SEGMENT_NETCP); - msmc_share_all_segments(KS2_MSMC_SEGMENT_QM_PDSP); - msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE0); - - /* Initialize the PCIe-0 to work as Root Complex */ - config_pcie_mode(0, ROOTCOMPLEX); -#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) - msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE1); - /* 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. - */ - NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2), - CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); - - 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) -{ -#ifndef CONFIG_SYS_DCACHE_OFF - /* Enable D-cache. I-cache is already enabled in start.S */ - dcache_enable(); -#endif -} diff --git a/arch/arm/cpu/armv7/keystone/keystone.c b/arch/arm/cpu/armv7/keystone/keystone.c deleted file mode 100644 index 11a9357db4..0000000000 --- a/arch/arm/cpu/armv7/keystone/keystone.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Keystone EVM : Board initialization - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -/** - * 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 int turn_off_myself(void) -{ - printf("Turning off ourselves\r\n"); - 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"); - - printf("What! Should not see that\n"); - 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 + 8)) - printf("Cannot disable domain for #%d DSP", i); - } -} - -int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - return turn_off_myself(); -} - -U_BOOT_CMD( - killme, 1, 0, do_killme_cmd, - "turn off main ARM core", - "turn off main ARM core. Should not live after that :(\n" -); - -int misc_init_r(void) -{ - char *env; - long ks2_debug = 0; - - env = getenv("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; -} diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c deleted file mode 100644 index 7899141d54..0000000000 --- a/arch/arm/cpu/armv7/keystone/msmc.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * MSMC controller utilities - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -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; -} diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c deleted file mode 100644 index 237e776e87..0000000000 --- a/arch/arm/cpu/armv7/keystone/psc.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Keystone: PSC configuration module - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -int psc_delay(void) -{ - udelay(10); - return 10; -} - -/* - * FUNCTION PURPOSE: Wait for end of transitional state - * - * DESCRIPTION: 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. - * - * Returns 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; -} - -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; -} - -/* - * FUNCTION PURPOSE: Power up/down a module - * - * DESCRIPTION: 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. - * - * Returns 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< +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += init.o +obj-y += psc.o +obj-y += clock.o +obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o +obj-$(CONFIG_SOC_K2E) += clock-k2e.o +obj-$(CONFIG_SOC_K2L) += clock-k2l.o +obj-y += cmd_clock.o +obj-y += cmd_mon.o +obj-y += msmc.o +obj-y += ddr3.o cmd_ddr3.o +obj-y += keystone.o diff --git a/arch/arm/mach-keystone/clock-k2e.c b/arch/arm/mach-keystone/clock-k2e.c new file mode 100644 index 0000000000..31f66613ef --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2e.c @@ -0,0 +1,117 @@ +/* + * Keystone2: get clk rate for K2E + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +const struct keystone_pll_regs keystone_pll_regs[] = { + [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, + [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, + [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, +}; + +int dev_speeds[] = { + SPD800, + SPD850, + SPD1000, + SPD1250, + SPD1350, + SPD1400, + SPD1500, + SPD1400, + SPD1350, + SPD1250, + SPD1000, + SPD850, + SPD800 +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @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 == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case DDR3_PLL: + ret = external_clk[ddr3_clk]; + reg = KS2_DDR3APLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock-k2hk.c b/arch/arm/mach-keystone/clock-k2hk.c new file mode 100644 index 0000000000..1591960795 --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2hk.c @@ -0,0 +1,145 @@ +/* + * Keystone2: get clk rate for K2HK + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +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}, +}; + +int dev_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD800, + SPD800, + SPD800, + SPD800, + SPD800, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +int arm_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD800, + SPD1400, + SPD1350, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @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 == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case TETRIS_PLL: + ret = external_clk[tetris_clk]; + reg = KS2_ARMPLLCTL0; + break; + case DDR3A_PLL: + ret = external_clk[ddr3a_clk]; + reg = KS2_DDR3APLLCTL0; + break; + case DDR3B_PLL: + ret = external_clk[ddr3b_clk]; + reg = KS2_DDR3BPLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); + case ddr3a_pll_clk: return pll_freq_get(DDR3A_PLL); + case ddr3b_pll_clk: return pll_freq_get(DDR3B_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock-k2l.c b/arch/arm/mach-keystone/clock-k2l.c new file mode 100644 index 0000000000..1c5e4d54d8 --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2l.c @@ -0,0 +1,138 @@ +/* + * Keystone2: get clk rate for K2L + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +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}, + [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, +}; + +int dev_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD800, + SPD800, + SPD800, + SPD800, + SPD800, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +int arm_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD800, + SPD1400, + SPD1350, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @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 == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case TETRIS_PLL: + ret = external_clk[tetris_clk]; + reg = KS2_ARMPLLCTL0; + break; + case DDR3_PLL: + ret = external_clk[ddr3_clk]; + reg = KS2_DDR3APLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); + case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock.c b/arch/arm/mach-keystone/clock.c new file mode 100644 index 0000000000..d13fbc1a4b --- /dev/null +++ b/arch/arm/mach-keystone/clock.c @@ -0,0 +1,272 @@ +/* + * Keystone2: pll initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define MAX_SPEEDS 13 + +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_GO) == 0) + break; + } +} + +void init_pll(const struct pll_init_data *data) +{ + u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj; + + pllm = data->pll_m - 1; + plld = (data->pll_d - 1) & PLL_DIV_MASK; + pllod = (data->pll_od - 1) & PLL_CLKOD_MASK; + + if (data->pll == MAIN_PLL) { + /* The requered delay before main PLL configuration */ + sdelay(210000); + + tmp = pllctl_reg_read(data->pll, secctl); + + if (tmp & (PLLCTL_BYPASS)) { + setbits_le32(keystone_pll_regs[data->pll].reg1, + BIT(MAIN_ENSAT_OFFSET)); + + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | + PLLCTL_PLLENSRC); + sdelay(340); + + pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS); + pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN); + sdelay(21000); + + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN); + } else { + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | + PLLCTL_PLLENSRC); + sdelay(340); + } + + pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK); + + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLLM_MULT_HI_SMASK, (pllm << 6)); + + /* Set the BWADJ (12 bit field) */ + tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */ + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLL_BWADJ_LO_SMASK, + (tmp_ctl << PLL_BWADJ_LO_SHIFT)); + clrsetbits_le32(keystone_pll_regs[data->pll].reg1, + PLL_BWADJ_HI_MASK, + (tmp_ctl >> 8)); + + /* + * Set the pll divider (6 bit field) * + * PLLD[5:0] is located in MAINPLLCTL0 + */ + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLL_DIV_MASK, plld); + + /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */ + pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK, + (pllod << PLL_CLKOD_SHIFT)); + wait_for_completion(data); + + pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1); + pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2); + pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3); + pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4); + pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5); + + pllctl_reg_setbits(data->pll, alnctl, 0x1f); + + /* + * Set GOSET bit in PLLCMD to initiate the GO operation + * to change the divide + */ + pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO); + sdelay(1500); /* wait for the phase adj */ + wait_for_completion(data); + + /* Reset PLL */ + pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST); + sdelay(21000); /* Wait for a minimum of 7 us*/ + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST); + sdelay(105000); /* Wait for PLL Lock time (min 50 us) */ + + pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS); + + tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN); + +#ifndef CONFIG_SOC_K2E + } else if (data->pll == TETRIS_PLL) { + bwadj = pllm >> 1; + /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ + setbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass) + * only applicable for Kepler + */ + clrbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); + /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */ + setbits_le32(keystone_pll_regs[data->pll].reg1 , + PLL_PLLRST | PLLCTL_ENSAT); + + /* + * 3 Program PLLM and PLLD in PLLCTL0 register + * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in + * PLLCTL1 register. BWADJ value must be set + * to ((PLLM + 1) >> 1) – 1) + */ + tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | + (pllm << 6) | + (plld & PLL_DIV_MASK) | + (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS; + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); + /* + * 5 Wait for at least 5 us based on the reference + * clock (PLL reset time) + */ + sdelay(21000); /* Wait for a minimum of 7 us*/ + + /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */ + clrbits_le32(keystone_pll_regs[data->pll].reg1, PLL_PLLRST); + /* + * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1) + * (PLL lock time) + */ + sdelay(105000); + /* 8 disable bypass */ + clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass) + * only applicable for Kepler + */ + setbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); +#endif + } else { + setbits_le32(keystone_pll_regs[data->pll].reg1, PLLCTL_ENSAT); + /* + * process keeps state of Bypass bit while programming + * all other DDR PLL settings + */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg0); + tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */ + + /* + * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0, + * bypass disabled + */ + bwadj = pllm >> 1; + tmp |= ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | + (pllm << PLL_MULT_SHIFT) | + (plld & PLL_DIV_MASK) | + (pllod << PLL_CLKOD_SHIFT); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); + + __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); + + /* Reset bit: bit 14 for both DDR3 & PASS PLL */ + tmp = PLL_PLLRST; + /* Set RESET bit = 1 */ + setbits_le32(keystone_pll_regs[data->pll].reg1, tmp); + /* Wait for a minimum of 7 us*/ + sdelay(21000); + /* Clear RESET bit */ + clrbits_le32(keystone_pll_regs[data->pll].reg1, tmp); + sdelay(105000); + + /* clear BYPASS (Enable PLL Mode) */ + clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + sdelay(21000); /* Wait for a minimum of 7 us*/ + } + + /* + * This is required to provide a delay between multiple + * consequent PPL configurations + */ + sdelay(210000); +} + +void init_plls(int num_pll, struct pll_init_data *config) +{ + int i; + + for (i = 0; i < num_pll; i++) + init_pll(&config[i]); +} + +static int get_max_speed(u32 val, int *speeds) +{ + int j; + + if (!val) + return speeds[0]; + + for (j = 1; j < MAX_SPEEDS; j++) { + if (val == 1) + return speeds[j]; + val >>= 1; + } + + return SPD800; +} + +#ifdef CONFIG_SOC_K2HK +static u32 read_efuse_bootrom(void) +{ + return (cpu_revision() > 1) ? __raw_readl(KS2_EFUSE_BOOTROM) : + __raw_readl(KS2_REV1_DEVSPEED); +} +#else +static inline u32 read_efuse_bootrom(void) +{ + return __raw_readl(KS2_EFUSE_BOOTROM); +} +#endif + +inline int get_max_dev_speed(void) +{ + return get_max_speed(read_efuse_bootrom() & 0xffff, dev_speeds); +} + +#ifndef CONFIG_SOC_K2E +inline int get_max_arm_speed(void) +{ + return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds); +} +#endif + +void pass_pll_pa_clk_enable(void) +{ + u32 reg; + + reg = readl(keystone_pll_regs[PASS_PLL].reg1); + + reg |= PLLCTL_PAPLL; + writel(reg, keystone_pll_regs[PASS_PLL].reg1); + + /* wait till clock is enabled */ + sdelay(15000); +} diff --git a/arch/arm/mach-keystone/cmd_clock.c b/arch/arm/mach-keystone/cmd_clock.c new file mode 100644 index 0000000000..af1b701e82 --- /dev/null +++ b/arch/arm/mach-keystone/cmd_clock.c @@ -0,0 +1,135 @@ +/* + * keystone2: commands for clocks + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +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 "
\n" +); + +int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int clk; + unsigned int freq; + + if (argc != 2) + goto getclk_cmd_usage; + + clk = simple_strtoul(argv[1], NULL, 10); + + freq = clk_get_rate(clk); + printf("clock index [%d] - frequency %u\n", clk, freq); + return 0; + +getclk_cmd_usage: + return cmd_usage(cmdtp); +} + +U_BOOT_CMD( + getclk, 2, 0, do_getclk_cmd, + "get clock rate", + "\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, + "", + " \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" +); diff --git a/arch/arm/mach-keystone/cmd_ddr3.c b/arch/arm/mach-keystone/cmd_ddr3.c new file mode 100644 index 0000000000..ea78ad8fd5 --- /dev/null +++ b/arch/arm/mach-keystone/cmd_ddr3.c @@ -0,0 +1,248 @@ +/* + * Keystone2: DDR3 test commands + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE + +#define DDR_REMAP_ADDR 0x80000000 +#define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17) + +#define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \ + CONFIG_STACKSIZE) >> 17) - 2) + +#define DDR_TEST_BURST_SIZE 1024 + +static int ddr_memory_test(u32 start_address, u32 end_address, int quick) +{ + u32 index_start, value, index; + + index_start = start_address; + + while (1) { + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) + __raw_writel(index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) { + value = __raw_readl(index); + if (value != index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readl(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + if (quick) + continue; + + /* Write a pattern for complementary values */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) + __raw_writel((u32)~index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) { + value = __raw_readl(index); + if (value != ~index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readl(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 2) + __raw_writew((u16)index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 2) { + value = __raw_readw(index); + if (value != (u16)index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readw(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 1) + __raw_writeb((u8)index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 1) { + value = __raw_readb(index); + if (value != (u8)index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readb(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + } + + puts("ddr memory test PASSED!\n"); + return 0; +} + +static int ddr_memory_compare(u32 address1, u32 address2, u32 size) +{ + u32 index, value, index2, value2; + + for (index = address1, index2 = address2; + index < address1 + size; + index += 4, index2 += 4) { + value = __raw_readl(index); + value2 = __raw_readl(index2); + + if (value != value2) { + printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n", + index, value, index2, value2); + + return -1; + } + } + + puts("ddr memory compare PASSED!\n"); + return 0; +} + +static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err) +{ + u32 value1, value2, value3; + + puts("Disabling DDR ECC ...\n"); + ddr3_disable_ecc(base); + + value1 = __raw_readl(address); + value2 = value1 ^ ecc_err; + __raw_writel(value2, address); + + value3 = __raw_readl(address); + printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n", + address, value1, value2, ecc_err, value3); + + __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16), + base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); + + puts("Enabling DDR ECC ...\n"); + ddr3_enable_ecc(base, 1); + + value1 = __raw_readl(address); + printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1); + + ddr3_check_ecc_int(base); + return 0; +} + +static int do_ddr_test(cmd_tbl_t *cmdtp, + int flag, int argc, char * const argv[]) +{ + u32 start_addr, end_addr, size, ecc_err; + + if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) { + if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) { + puts("ECC RMW isn't supported for this SOC\n"); + return 1; + } + + start_addr = simple_strtoul(argv[2], NULL, 16); + ecc_err = simple_strtoul(argv[3], NULL, 16); + + if ((start_addr < CONFIG_SYS_SDRAM_BASE) || + (start_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1))) { + puts("Invalid address!\n"); + return cmd_usage(cmdtp); + } + + ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE, + start_addr, ecc_err); + return 0; + } + + if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) || + ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0)))) + return cmd_usage(cmdtp); + + start_addr = simple_strtoul(argv[2], NULL, 16); + end_addr = simple_strtoul(argv[3], NULL, 16); + + if ((start_addr < CONFIG_SYS_SDRAM_BASE) || + (start_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1)) || + (end_addr < CONFIG_SYS_SDRAM_BASE) || + (end_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) { + puts("Invalid start or end address!\n"); + return cmd_usage(cmdtp); + } + + puts("Please wait ...\n"); + if (argc == 5) { + size = simple_strtoul(argv[4], NULL, 16); + ddr_memory_compare(start_addr, end_addr, size); + } else { + ddr_memory_test(start_addr, end_addr, 0); + } + + return 0; +} + +U_BOOT_CMD(ddr, 5, 1, do_ddr_test, + "DDR3 test", + "test - test DDR from start\n" + " address to end address\n" + "ddr compare -\n" + " compare DDR data of (size) bytes from start address to end\n" + " address\n" + "ddr ecc_err - generate bit errors\n" + " in DDR data at , the command will read a 32-bit data\n" + " from , and write (data ^ bit_err) back to \n" +); diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c new file mode 100644 index 0000000000..f9f58a37df --- /dev/null +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -0,0 +1,131 @@ +/* + * K2HK: secure kernel command file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +asm(".arch_extension sec\n\t"); + +static int mon_install(u32 addr, u32 dpsc, u32 freq) +{ + int result; + + __asm__ __volatile__ ( + "stmfd r13!, {lr}\n" + "mov r0, %1\n" + "mov r1, %2\n" + "mov r2, %3\n" + "blx r0\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (addr), "r" (dpsc), "r" (freq) + : "cc", "r0", "r1", "r2", "memory"); + return result; +} + +static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 addr, dpsc_base = 0x1E80000, freq; + int rcode = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + freq = clk_get_rate(sys_clk0_6_clk); + + addr = simple_strtoul(argv[1], NULL, 16); + + rcode = mon_install(addr, dpsc_base, freq); + printf("## installed monitor, freq [%d], status %d\n", + freq, rcode); + + return 0; +} + +U_BOOT_CMD(mon_install, 2, 0, do_mon_install, + "Install boot kernel at 'addr'", + "" +); + +static void core_spin(void) +{ + while (1) + ; /* forever */; +} + +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" + "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" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (core_id) + : "cc", "r0", "r1", "memory"); + return result; +} + +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 \n" + "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n" + "" +); diff --git a/arch/arm/mach-keystone/ddr3.c b/arch/arm/mach-keystone/ddr3.c new file mode 100644 index 0000000000..dfb27b5ba2 --- /dev/null +++ b/arch/arm/mach-keystone/ddr3.c @@ -0,0 +1,404 @@ +/* + * Keystone2: DDR3 initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#include + +#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) + ; + + __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 */ + msmc_get_ses_mpax(8, 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 */ + msmc_map_ses_segment(8, 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 */ + msmc_set_ses_mpax(8, 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 = getenv("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 diff --git a/arch/arm/mach-keystone/init.c b/arch/arm/mach-keystone/init.c new file mode 100644 index 0000000000..c96845c4e2 --- /dev/null +++ b/arch/arm/mach-keystone/init.c @@ -0,0 +1,151 @@ +/* + * Keystone2: Architecture initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#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); +} + +int arch_cpu_init(void) +{ + chip_configuration_unlock(); + icache_enable(); + + msmc_share_all_segments(KS2_MSMC_SEGMENT_TETRIS); + msmc_share_all_segments(KS2_MSMC_SEGMENT_NETCP); + msmc_share_all_segments(KS2_MSMC_SEGMENT_QM_PDSP); + msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE0); + + /* Initialize the PCIe-0 to work as Root Complex */ + config_pcie_mode(0, ROOTCOMPLEX); +#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) + msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE1); + /* 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. + */ + NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2), + CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); + + 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) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +#endif +} diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c new file mode 100644 index 0000000000..11a9357db4 --- /dev/null +++ b/arch/arm/mach-keystone/keystone.c @@ -0,0 +1,87 @@ +/* + * Keystone EVM : Board initialization + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +/** + * 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 int turn_off_myself(void) +{ + printf("Turning off ourselves\r\n"); + 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"); + + printf("What! Should not see that\n"); + 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 + 8)) + printf("Cannot disable domain for #%d DSP", i); + } +} + +int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return turn_off_myself(); +} + +U_BOOT_CMD( + killme, 1, 0, do_killme_cmd, + "turn off main ARM core", + "turn off main ARM core. Should not live after that :(\n" +); + +int misc_init_r(void) +{ + char *env; + long ks2_debug = 0; + + env = getenv("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; +} diff --git a/arch/arm/mach-keystone/msmc.c b/arch/arm/mach-keystone/msmc.c new file mode 100644 index 0000000000..7899141d54 --- /dev/null +++ b/arch/arm/mach-keystone/msmc.c @@ -0,0 +1,94 @@ +/* + * MSMC controller utilities + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +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; +} diff --git a/arch/arm/mach-keystone/psc.c b/arch/arm/mach-keystone/psc.c new file mode 100644 index 0000000000..237e776e87 --- /dev/null +++ b/arch/arm/mach-keystone/psc.c @@ -0,0 +1,227 @@ +/* + * Keystone: PSC configuration module + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int psc_delay(void) +{ + udelay(10); + return 10; +} + +/* + * FUNCTION PURPOSE: Wait for end of transitional state + * + * DESCRIPTION: 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. + * + * Returns 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; +} + +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; +} + +/* + * FUNCTION PURPOSE: Power up/down a module + * + * DESCRIPTION: 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. + * + * Returns 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<