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>
diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c
index 7e69873..e24b857 100644
--- a/arch/powerpc/cpu/mpc85xx/speed.c
+++ b/arch/powerpc/cpu/mpc85xx/speed.c
@@ -34,6 +34,10 @@
 #ifdef CONFIG_FSL_CORENET
 	volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
 	unsigned int cpu;
+#ifdef CONFIG_HETROGENOUS_CLUSTERS
+	unsigned int dsp_cpu;
+	uint rcw_tmp1, rcw_tmp2;
+#endif
 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
 	int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
 #endif
@@ -157,6 +161,7 @@
 		else
 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
 	}
+
 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
 	/*
 	 * As per CHASSIS2 architeture total 12 clusters are posible and
@@ -181,6 +186,20 @@
 		sys_info->freq_processor[cpu] =
 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
 	}
+
+#ifdef CONFIG_HETROGENOUS_CLUSTERS
+	for_each_cpu(i, dsp_cpu, cpu_num_dspcores(), cpu_dsp_mask()) {
+		int dsp_cluster = fsl_qoriq_dsp_core_to_cluster(dsp_cpu);
+		u32 c_pll_sel = (in_be32
+				(&clk->clkcsr[dsp_cluster].clkcncsr) >> 27)
+				& 0xf;
+		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
+		cplx_pll += cc_group[dsp_cluster] - 1;
+		sys_info->freq_processor_dsp[dsp_cpu] =
+			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
+	}
+#endif
+
 #if defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420) || \
 	defined(CONFIG_PPC_T2080) || defined(CONFIG_PPC_T2081)
 #define FM1_CLK_SEL	0xe0000000
@@ -243,6 +262,127 @@
 	sys_info->freq_qman = sys_info->freq_systembus / CONFIG_QBMAN_CLK_DIV;
 #endif
 
+#if defined(CONFIG_SYS_MAPLE)
+#define CPRI_CLK_SEL		0x1C000000
+#define CPRI_CLK_SHIFT		26
+#define CPRI_ALT_CLK_SEL	0x00007000
+#define CPRI_ALT_CLK_SHIFT	12
+
+	rcw_tmp1 = in_be32(&gur->rcwsr[7]);	/* Reading RCW bits: 224-255*/
+	rcw_tmp2 = in_be32(&gur->rcwsr[15]);	/* Reading RCW bits: 480-511*/
+	/* For MAPLE and CPRI frequency */
+	switch ((rcw_tmp1 & CPRI_CLK_SEL) >> CPRI_CLK_SHIFT) {
+	case 1:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK];
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK];
+		break;
+	case 2:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
+		break;
+	case 3:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
+		break;
+	case 4:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
+		break;
+	case 5:
+		if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
+					>> CPRI_ALT_CLK_SHIFT) == 6) {
+			sys_info->freq_maple =
+				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
+			sys_info->freq_cpri =
+				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
+		}
+		if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
+					>> CPRI_ALT_CLK_SHIFT) == 7) {
+			sys_info->freq_maple =
+				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
+			sys_info->freq_cpri =
+				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
+		}
+		break;
+	case 6:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
+		break;
+	case 7:
+		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
+		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
+		break;
+	default:
+		printf("Error: Unknown MAPLE/CPRI clock select!\n");
+	}
+
+	/* For MAPLE ULB and eTVPE frequencies */
+#define ULB_CLK_SEL		0x00000038
+#define ULB_CLK_SHIFT		3
+#define ETVPE_CLK_SEL		0x00000007
+#define ETVPE_CLK_SHIFT		0
+
+	switch ((rcw_tmp2 & ULB_CLK_SEL) >> ULB_CLK_SHIFT) {
+	case 1:
+		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK];
+		break;
+	case 2:
+		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 2;
+		break;
+	case 3:
+		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 3;
+		break;
+	case 4:
+		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 4;
+		break;
+	case 5:
+		sys_info->freq_maple_ulb = sys_info->freq_systembus;
+		break;
+	case 6:
+		sys_info->freq_maple_ulb =
+			freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 2;
+		break;
+	case 7:
+		sys_info->freq_maple_ulb =
+			freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 3;
+		break;
+	default:
+		printf("Error: Unknown MAPLE ULB clock select!\n");
+	}
+
+	switch ((rcw_tmp2 & ETVPE_CLK_SEL) >> ETVPE_CLK_SHIFT) {
+	case 1:
+		sys_info->freq_maple_etvpe = freq_c_pll[CONFIG_SYS_ETVPE_CLK];
+		break;
+	case 2:
+		sys_info->freq_maple_etvpe =
+			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 2;
+		break;
+	case 3:
+		sys_info->freq_maple_etvpe =
+			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 3;
+		break;
+	case 4:
+		sys_info->freq_maple_etvpe =
+			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 4;
+		break;
+	case 5:
+		sys_info->freq_maple_etvpe = sys_info->freq_systembus;
+		break;
+	case 6:
+		sys_info->freq_maple_etvpe =
+			freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 2;
+		break;
+	case 7:
+		sys_info->freq_maple_etvpe =
+			freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 3;
+		break;
+	default:
+		printf("Error: Unknown MAPLE eTVPE clock select!\n");
+	}
+
+#endif
+
 #ifdef CONFIG_SYS_DPAA_FMAN
 #ifndef CONFIG_FM_PLAT_CLK_DIV
 	switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {