From 8dfc15f56c2b39fb5d542cf67857f5ad36575234 Mon Sep 17 00:00:00 2001 From: "Khoronzhuk, Ivan" Date: Wed, 9 Jul 2014 23:44:47 +0300 Subject: [PATCH] ARM: keystone: clock: move K2HK SoC dependent code in separate file This patch in general spit SoC type clock dependent code and general clock code. Before adding keystone II Edison k2e SoC which has slightly different dpll set, move k2hk dependent clock code to separate clock-k2hk.c file. Acked-by: Murali Karicheri Signed-off-by: Ivan Khoronzhuk --- arch/arm/cpu/armv7/keystone/Makefile | 1 + arch/arm/cpu/armv7/keystone/clock-k2hk.c | 113 +++++++++++++ arch/arm/cpu/armv7/keystone/clock.c | 148 +++--------------- .../include/asm/arch-keystone/clock-k2hk.h | 21 --- arch/arm/include/asm/arch-keystone/clock.h | 28 ++++ 5 files changed, 166 insertions(+), 145 deletions(-) create mode 100644 arch/arm/cpu/armv7/keystone/clock-k2hk.c diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile index 64e42a6e23..74c516013a 100644 --- a/arch/arm/cpu/armv7/keystone/Makefile +++ b/arch/arm/cpu/armv7/keystone/Makefile @@ -8,6 +8,7 @@ obj-y += init.o obj-y += psc.o obj-y += clock.o +obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o obj-y += cmd_clock.o obj-y += cmd_mon.o obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_nav.o diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c new file mode 100644 index 0000000000..96a9f72886 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c @@ -0,0 +1,113 @@ +/* + * 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}, +}; + +/** + * 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.c b/arch/arm/cpu/armv7/keystone/clock.c index f905fdcf0d..42b664b576 100644 --- a/arch/arm/cpu/armv7/keystone/clock.c +++ b/arch/arm/cpu/armv7/keystone/clock.c @@ -8,9 +8,6 @@ */ #include -#include -#include -#include #include #include @@ -24,106 +21,6 @@ static void wait_for_completion(const struct pll_init_data *data) } } -struct pll_regs { - u32 reg0, reg1; -}; - -static const struct pll_regs 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}, -}; - -/* Fout = Fref * NF(mult) / NR(prediv) / OD */ -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; -} - void init_pll(const struct pll_init_data *data) { u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj; @@ -139,7 +36,7 @@ void init_pll(const struct pll_init_data *data) tmp = pllctl_reg_read(data->pll, secctl); if (tmp & (PLLCTL_BYPASS)) { - setbits_le32(pll_regs[data->pll].reg1, + setbits_le32(keystone_pll_regs[data->pll].reg1, BIT(MAIN_ENSAT_OFFSET)); pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | @@ -159,21 +56,24 @@ void init_pll(const struct pll_init_data *data) pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK); - clrsetbits_le32(pll_regs[data->pll].reg0, PLLM_MULT_HI_SMASK, - (pllm << 6)); + 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(pll_regs[data->pll].reg0, PLL_BWADJ_LO_SMASK, + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLL_BWADJ_LO_SMASK, (tmp_ctl << PLL_BWADJ_LO_SHIFT)); - clrsetbits_le32(pll_regs[data->pll].reg1, PLL_BWADJ_HI_MASK, + 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(pll_regs[data->pll].reg0, PLL_DIV_MASK, plld); + 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, @@ -209,14 +109,14 @@ void init_pll(const struct pll_init_data *data) } else if (data->pll == TETRIS_PLL) { bwadj = pllm >> 1; /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ - setbits_le32(pll_regs[data->pll].reg0, PLLCTL_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(pll_regs[data->pll].reg1 , + setbits_le32(keystone_pll_regs[data->pll].reg1 , PLL_PLLRST | PLLCTL_ENSAT); /* @@ -229,13 +129,13 @@ void init_pll(const struct pll_init_data *data) (pllm << 6) | (plld & PLL_DIV_MASK) | (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS; - __raw_writel(tmp, pll_regs[data->pll].reg0); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(pll_regs[data->pll].reg1); + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); tmp &= ~(PLL_BWADJ_HI_MASK); tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); - __raw_writel(tmp, pll_regs[data->pll].reg1); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); /* * 5 Wait for at least 5 us based on the reference * clock (PLL reset time) @@ -243,26 +143,26 @@ void init_pll(const struct pll_init_data *data) sdelay(21000); /* Wait for a minimum of 7 us*/ /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */ - clrbits_le32(pll_regs[data->pll].reg1, PLL_PLLRST); + 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(pll_regs[data->pll].reg0, PLLCTL_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); } else { - setbits_le32(pll_regs[data->pll].reg1, PLLCTL_ENSAT); + 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(pll_regs[data->pll].reg0); + tmp = __raw_readl(keystone_pll_regs[data->pll].reg0); tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */ /* @@ -274,10 +174,10 @@ void init_pll(const struct pll_init_data *data) (pllm << PLL_MULT_SHIFT) | (plld & PLL_DIV_MASK) | (pllod << PLL_CLKOD_SHIFT); - __raw_writel(tmp, pll_regs[data->pll].reg0); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(pll_regs[data->pll].reg1); + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); tmp &= ~(PLL_BWADJ_HI_MASK); tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); @@ -285,20 +185,20 @@ void init_pll(const struct pll_init_data *data) if (data->pll == PASS_PLL) tmp |= PLLCTL_PAPLL; - __raw_writel(tmp, pll_regs[data->pll].reg1); + __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(pll_regs[data->pll].reg1, tmp); + setbits_le32(keystone_pll_regs[data->pll].reg1, tmp); /* Wait for a minimum of 7 us*/ sdelay(21000); /* Clear RESET bit */ - clrbits_le32(pll_regs[data->pll].reg1, tmp); + clrbits_le32(keystone_pll_regs[data->pll].reg1, tmp); sdelay(105000); /* clear BYPASS (Enable PLL Mode) */ - clrbits_le32(pll_regs[data->pll].reg0, PLLCTL_BYPASS); + clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); sdelay(21000); /* Wait for a minimum of 7 us*/ } diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h index ed1225c298..784a0be567 100644 --- a/arch/arm/include/asm/arch-keystone/clock-k2hk.h +++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h @@ -10,10 +10,6 @@ #ifndef __ASM_ARCH_CLOCK_K2HK_H #define __ASM_ARCH_CLOCK_K2HK_H -#include - -#ifndef __ASSEMBLY__ - enum ext_clk_e { sys_clk, alt_core_clk, @@ -66,15 +62,6 @@ enum pll_type_e { DDR3A_PLL, DDR3B_PLL, }; -#define MAIN_PLL CORE_PLL - -/* PLL configuration data */ -struct pll_init_data { - int pll; - int pll_m; /* PLL Multiplier */ - int pll_d; /* PLL divider */ - int pll_od; /* PLL output divider */ -}; #define CORE_PLL_799 {CORE_PLL, 13, 1, 2} #define CORE_PLL_983 {CORE_PLL, 16, 1, 2} @@ -98,12 +85,4 @@ struct pll_init_data { #define DDR3_PLL_800(x) {DDR3##x##_PLL, 16, 1, 2} #define DDR3_PLL_333(x) {DDR3##x##_PLL, 20, 1, 6} -void init_plls(int num_pll, struct pll_init_data *config); -void init_pll(const struct pll_init_data *data); -unsigned long clk_get_rate(unsigned int clk); -unsigned long clk_round_rate(unsigned int clk, unsigned long hz); -int clk_set_rate(unsigned int clk, unsigned long hz); - -#endif - #endif diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h index 324501b75a..c7da3520c4 100644 --- a/arch/arm/include/asm/arch-keystone/clock.h +++ b/arch/arm/include/asm/arch-keystone/clock.h @@ -10,8 +10,36 @@ #ifndef __ASM_ARCH_CLOCK_H #define __ASM_ARCH_CLOCK_H +#ifndef __ASSEMBLY__ + #ifdef CONFIG_SOC_K2HK #include #endif +#define MAIN_PLL CORE_PLL + +#include + +struct keystone_pll_regs { + u32 reg0; + u32 reg1; +}; + +/* PLL configuration data */ +struct pll_init_data { + int pll; + int pll_m; /* PLL Multiplier */ + int pll_d; /* PLL divider */ + int pll_od; /* PLL output divider */ +}; + +extern const struct keystone_pll_regs keystone_pll_regs[]; + +void init_plls(int num_pll, struct pll_init_data *config); +void init_pll(const struct pll_init_data *data); +unsigned long clk_get_rate(unsigned int clk); +unsigned long clk_round_rate(unsigned int clk, unsigned long hz); +int clk_set_rate(unsigned int clk, unsigned long hz); + +#endif #endif -- 2.25.1