diff options
author | York Sun <yorksun@freescale.com> | 2012-10-08 07:44:11 +0000 |
---|---|---|
committer | Andy Fleming <afleming@freescale.com> | 2012-10-22 14:31:16 -0500 |
commit | 9a653a9810160351ba1930ec55eae37c1a492b78 (patch) | |
tree | 74be1c446c2cdd731408bad59c553300371fab4d /arch/powerpc/cpu/mpc85xx | |
parent | 2f1712b275af3ed960b92cd1ed9b99d23c4919a5 (diff) | |
download | u-boot-imx-9a653a9810160351ba1930ec55eae37c1a492b78.zip u-boot-imx-9a653a9810160351ba1930ec55eae37c1a492b78.tar.gz u-boot-imx-9a653a9810160351ba1930ec55eae37c1a492b78.tar.bz2 |
powerpc/mpc85xx: Fix core cluster PLL calculation for Chassis generation 2
Corenet based SoCs have different core clocks starting from Chassis
generation 2. Cores are organized into clusters. Each cluster has up to
4 cores sharing same clock, which can be chosen from one of three PLLs in
the cluster group with one of the devisors /1, /2 or /4. Two clusters are
put together as a cluster group. These two clusters share the PLLs but may
have different divisor. For example, core 0~3 are in cluster 1. Core 4~7
are in cluster 2. Core 8~11 are in cluster 3 and so on. Cluster 1 and 2
are cluster group A. Cluster 3 and 4 are in cluster group B. Cluster group
A has PLL1, PLL2, PLL3. Cluster group B has PLL4, PLL5. Core 0~3 may have
PLL1/2, core 4~7 may have PLL2/2. Core 8~11 may have PLL4/1.
PME and FMan blocks can take different PLLs, configured by RCW.
Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx')
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/speed.c | 138 |
1 files changed, 128 insertions, 10 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 6c2bc34..f07a28b 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -76,8 +76,8 @@ void get_sys_info (sys_info_t * sysInfo) [13] = 2, /* CC4 PPL / 2 */ [14] = 4, /* CC4 PPL / 4 */ }; - uint lcrr_div, i, freqCC_PLL[4], rcw_tmp; - uint ratio[4]; + uint i, freqCC_PLL[6], rcw_tmp; + uint ratio[6]; unsigned long sysclk = CONFIG_SYS_CLK_FREQ; uint mem_pll_rat; @@ -97,21 +97,139 @@ void get_sys_info (sys_info_t * sysInfo) ratio[1] = (in_be32(&clk->pllc2gsr) >> 1) & 0x3f; ratio[2] = (in_be32(&clk->pllc3gsr) >> 1) & 0x3f; ratio[3] = (in_be32(&clk->pllc4gsr) >> 1) & 0x3f; - for (i = 0; i < 4; i++) { + ratio[4] = (in_be32(&clk->pllc5gsr) >> 1) & 0x3f; + ratio[5] = (in_be32(&clk->pllc6gsr) >> 1) & 0x3f; + for (i = 0; i < 6; i++) { if (ratio[i] > 4) freqCC_PLL[i] = sysclk * ratio[i]; else freqCC_PLL[i] = sysInfo->freqSystemBus * ratio[i]; } - rcw_tmp = in_be32(&gur->rcwsr[3]); +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 + /* + * Each cluster has up to 4 cores, sharing the same PLL selection. + * The cluster assignment is fixed per SoC. There is no way identify the + * assignment so far, presuming the "first configuration" which is to + * fill the lower cluster group first before moving up to next group. + * PLL1, PLL2, PLL3 are cluster group A, feeding core 0~3 on cluster 1 + * and core 4~7 on cluster 2 + * PLL4, PLL5, PLL6 are cluster group B, feeding core 8~11 on cluster 3 + * and core 12~15 on cluster 4 if existing + */ for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { - u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; + u32 c_pll_sel = (in_be32(&clk->clkc0csr + (cpu / 4) * 8) >> 27) + & 0xf; u32 cplx_pll = core_cplx_PLL[c_pll_sel]; + if (cplx_pll > 3) + printf("Unsupported architecture configuration" + " in function %s\n", __func__); + cplx_pll += (cpu / 8) * 3; sysInfo->freqProcessor[cpu] = freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; } +#define PME_CLK_SEL 0xe0000000 +#define PME_CLK_SHIFT 29 +#define FM1_CLK_SEL 0x1c000000 +#define FM1_CLK_SHIFT 26 + rcw_tmp = in_be32(&gur->rcwsr[7]); + +#ifdef CONFIG_SYS_DPAA_PME + switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) { + case 1: + sysInfo->freqPME = freqCC_PLL[0]; + break; + case 2: + sysInfo->freqPME = freqCC_PLL[0] / 2; + break; + case 3: + sysInfo->freqPME = freqCC_PLL[0] / 3; + break; + case 4: + sysInfo->freqPME = freqCC_PLL[0] / 4; + break; + case 6: + sysInfo->freqPME = freqCC_PLL[1] / 2; + break; + case 7: + sysInfo->freqPME = freqCC_PLL[1] / 3; + break; + default: + printf("Error: Unknown PME clock select!\n"); + case 0: + sysInfo->freqPME = sysInfo->freqSystemBus / 2; + break; + + } +#endif +#ifdef CONFIG_SYS_DPAA_FMAN + switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) { + case 1: + sysInfo->freqFMan[0] = freqCC_PLL[3]; + break; + case 2: + sysInfo->freqFMan[0] = freqCC_PLL[3] / 2; + break; + case 3: + sysInfo->freqFMan[0] = freqCC_PLL[3] / 3; + break; + case 4: + sysInfo->freqFMan[0] = freqCC_PLL[3] / 4; + break; + case 6: + sysInfo->freqFMan[0] = freqCC_PLL[4] / 2; + break; + case 7: + sysInfo->freqFMan[0] = freqCC_PLL[4] / 3; + break; + default: + printf("Error: Unknown FMan1 clock select!\n"); + case 0: + sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2; + break; + } +#if (CONFIG_SYS_NUM_FMAN) == 2 +#define FM2_CLK_SEL 0x00000038 +#define FM2_CLK_SHIFT 3 + rcw_tmp = in_be32(&gur->rcwsr[15]); + switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) { + case 1: + sysInfo->freqFMan[1] = freqCC_PLL[4]; + break; + case 2: + sysInfo->freqFMan[1] = freqCC_PLL[4] / 2; + break; + case 3: + sysInfo->freqFMan[1] = freqCC_PLL[4] / 3; + break; + case 4: + sysInfo->freqFMan[1] = freqCC_PLL[4] / 4; + break; + case 6: + sysInfo->freqFMan[1] = freqCC_PLL[3] / 2; + break; + case 7: + sysInfo->freqFMan[1] = freqCC_PLL[3] / 3; + break; + default: + printf("Error: Unknown FMan2 clock select!\n"); + case 0: + sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2; + break; + } +#endif /* CONFIG_SYS_NUM_FMAN == 2 */ +#endif /* CONFIG_SYS_DPAA_FMAN */ + +#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + + for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { + u32 c_pll_sel = (in_be32(&clk->clkc0csr + cpu*8) >> 27) & 0xf; + u32 cplx_pll = core_cplx_PLL[c_pll_sel]; + + sysInfo->freqProcessor[cpu] = + freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel]; + } #define PME_CLK_SEL 0x80000000 #define FM1_CLK_SEL 0x40000000 #define FM2_CLK_SEL 0x20000000 @@ -159,11 +277,10 @@ void get_sys_info (sys_info_t * sysInfo) #endif #endif -#else - uint plat_ratio,e500_ratio,half_freqSystemBus; -#if defined(CONFIG_FSL_LBC) - uint lcrr_div; -#endif +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +#else /* CONFIG_FSL_CORENET */ + uint plat_ratio, e500_ratio, half_freqSystemBus; int i; #ifdef CONFIG_QE __maybe_unused u32 qe_ratio; @@ -210,6 +327,7 @@ void get_sys_info (sys_info_t * sysInfo) #endif /* CONFIG_FSL_CORENET */ #if defined(CONFIG_FSL_LBC) + uint lcrr_div; #if defined(CONFIG_SYS_LBC_LCRR) /* We will program LCRR to this value later */ lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; |