summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/cpu/mpc8xxx/cpu.c
diff options
context:
space:
mode:
authorShaveta Leekha <shaveta@freescale.com>2015-01-19 12:46:54 +0530
committerYork Sun <yorksun@freescale.com>2015-03-04 10:15:29 -0800
commitb8bf0adc12f833f759cd69f88d83cd950c0b52cd (patch)
tree650093e53134b90ac07013128b41e9218ce02a14 /arch/powerpc/cpu/mpc8xxx/cpu.c
parent8176a874233eb5180701e2811b38c199369975b2 (diff)
downloadtalos-obmc-uboot-b8bf0adc12f833f759cd69f88d83cd950c0b52cd.tar.gz
talos-obmc-uboot-b8bf0adc12f833f759cd69f88d83cd950c0b52cd.zip
powerpc/mpc85xx: Add DSP side awareness for Freescale Heterogeneous SoCs
The code provides framework for heterogeneous multicore chips based on StarCore and Power Architecture which are chasis-2 compliant, like B4860 and B4420 It will make u-boot recognize all non-ppc cores and peripherals like SC3900/DSP CPUs, MAPLE, CPRI and print their configuration in u-boot logs. Example boot logs of B4860QDS: U-Boot 2015.01-00232-geef6e36-dirty (Jan 19 2015 - 11:58:45) CPU0: B4860E, Version: 2.2, (0x86880022) Core: e6500, Version: 2.0, (0x80400120) Clock Configuration: CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz, DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz, DSP CPU4:1200 MHz, DSP CPU5:1200 MHz, CCB:666.667 MHz, DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz CPRI:600 MHz MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz FMAN1: 666.667 MHz QMAN: 333.333 MHz Top level changes include: (1) Top level CONFIG to identify HETEROGENUOUS clusters (2) CONFIGS for SC3900/DSP components (3) Global structures like "cpu_type" and "MPC85xx_SYS_INFO" updated for dsp cores and other components (3) APIs to get DSP num cores and their Mask like: cpu_dsp_mask, cpu_num_dspcores etc same as that of PowerPC (5) Code to fetch and print SC cores and other heterogenous device's frequencies (6) README added for the same Signed-off-by: Shaveta Leekha <shaveta@freescale.com> Reviewed-by: York Sun <yorksun@freescale.com>
Diffstat (limited to 'arch/powerpc/cpu/mpc8xxx/cpu.c')
-rw-r--r--arch/powerpc/cpu/mpc8xxx/cpu.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c
index c92589fb9d..584f3b8d61 100644
--- a/arch/powerpc/cpu/mpc8xxx/cpu.c
+++ b/arch/powerpc/cpu/mpc8xxx/cpu.c
@@ -133,6 +133,53 @@ u32 compute_ppc_cpumask(void)
return mask;
}
+#ifdef CONFIG_HETROGENOUS_CLUSTERS
+u32 compute_dsp_cpumask(void)
+{
+ ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int i = CONFIG_DSP_CLUSTER_START, count = 0;
+ u32 cluster, type, dsp_mask = 0;
+
+ do {
+ int j;
+ cluster = in_be32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = init_type(cluster, j);
+ if (type) {
+ if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_SC)
+ dsp_mask |= 1 << count;
+ count++;
+ }
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
+
+ return dsp_mask;
+}
+
+int fsl_qoriq_dsp_core_to_cluster(unsigned int core)
+{
+ ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ int count = 0, i = CONFIG_DSP_CLUSTER_START;
+ u32 cluster;
+
+ do {
+ int j;
+ cluster = in_be32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ if (init_type(cluster, j)) {
+ if (count == core)
+ return i;
+ count++;
+ }
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
+
+ return -1; /* cannot identify the cluster */
+}
+#endif
+
int fsl_qoriq_core_to_cluster(unsigned int core)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@@ -198,8 +245,43 @@ __weak u32 cpu_mask(void)
return cpu->mask;
}
+#ifdef CONFIG_HETROGENOUS_CLUSTERS
+__weak u32 cpu_dsp_mask(void)
+{
+ ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR;
+ struct cpu_type *cpu = gd->arch.cpu;
+
+ /* better to query feature reporting register than just assume 1 */
+ if (cpu == &cpu_type_unknown)
+ return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >>
+ MPC8xxx_PICFRR_NCPU_SHIFT) + 1;
+
+ if (cpu->dsp_num_cores == 0)
+ return compute_dsp_cpumask();
+
+ return cpu->dsp_mask;
+}
+
/*
- * Return the number of cores on this SOC.
+ * Return the number of SC/DSP cores on this SOC.
+ */
+__weak int cpu_num_dspcores(void)
+{
+ struct cpu_type *cpu = gd->arch.cpu;
+
+ /*
+ * Report # of cores in terms of the cpu_mask if we haven't
+ * figured out how many there are yet
+ */
+ if (cpu->dsp_num_cores == 0)
+ return hweight32(cpu_dsp_mask());
+
+ return cpu->dsp_num_cores;
+}
+#endif
+
+/*
+ * Return the number of PPC cores on this SOC.
*/
__weak int cpu_numcores(void)
{
@@ -215,6 +297,7 @@ __weak int cpu_numcores(void)
return cpu->num_cores;
}
+
/*
* Check if the given core ID is valid
*
@@ -248,6 +331,12 @@ int fixup_cpu(void)
cpu->num_cores = cpu_numcores();
}
+#ifdef CONFIG_HETROGENOUS_CLUSTERS
+ if (cpu->dsp_num_cores == 0) {
+ cpu->dsp_mask = cpu_dsp_mask();
+ cpu->dsp_num_cores = cpu_num_dspcores();
+ }
+#endif
return 0;
}
OpenPOWER on IntegriCloud