powerpc/chassis2: Change core numbering scheme
authorYork Sun <yorksun@freescale.com>
Mon, 25 Mar 2013 07:40:07 +0000 (07:40 +0000)
committerAndy Fleming <afleming@freescale.com>
Fri, 24 May 2013 21:54:11 +0000 (16:54 -0500)
To align with chassis generation 2 spec, all cores are numbered in sequence.
The cores may reside across multiple clusters. Each cluster has zero to four
cores. The first available core is numbered as core 0. The second available
core is numbered as core 1 and so on.

Core clocks are generated by each clusters. To identify the cluster of each
core, topology registers are examined.

Cluster clock registers are reorganized to be easily indexed.

Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
arch/powerpc/cpu/mpc85xx/release.S
arch/powerpc/cpu/mpc85xx/speed.c
arch/powerpc/cpu/mpc8xxx/cpu.c
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/processor.h

index 467ea10..a4a21b0 100644 (file)
@@ -154,16 +154,12 @@ __secondary_start_page:
        ori     r3,r3,toreset(__spin_table_addr)@l
        lwz     r3,0(r3)
 
-       /*
-        * r10 has the base address for the entry.
-        * we cannot access it yet before setting up a new TLB
-        */
        mfspr   r0,SPRN_PIR
 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
 /*
  * PIR definition for Chassis 2
  * 0-17 Reserved (logic 0s)
- * 8-19 CHIP_ID,    2'b00      - SoC 1
+ * 18-19 CHIP_ID,    2'b00      - SoC 1
  *                  all others - reserved
  * 20-24 CLUSTER_ID 5'b00000   - CCM 1
  *                  all others - reserved
@@ -177,32 +173,33 @@ __secondary_start_page:
  *                       2'b11 - core 3
  * 29-31 THREAD_ID       3'b000 - thread 0
  *                       3'b001 - thread 1
+ *
+ * Power-on PIR increments threads by 0x01, cores within a cluster by 0x08
+ * and clusters by 0x20.
+ *
+ * We renumber PIR so that all threads in the system are consecutive.
  */
-       rlwinm  r4,r0,29,25,31
+
+       rlwinm  r8,r0,29,0x03   /* r8 = core within cluster */
+       srwi    r10,r0,5        /* r10 = cluster */
+
+       mulli   r5,r10,CONFIG_SYS_FSL_CORES_PER_CLUSTER
+       add     r5,r5,r8        /* for spin table index */
+       mulli   r4,r5,CONFIG_SYS_FSL_THREADS_PER_CORE   /* for PIR */
 #elif  defined(CONFIG_E500MC)
        rlwinm  r4,r0,27,27,31
+       mr      r5,r4
 #else
        mr      r4,r0
+       mr      r5,r4
 #endif
-       slwi    r8,r4,6 /* spin table is padded to 64 byte */
-       add     r10,r3,r8
 
-#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
-       mfspr   r0,SPRN_PIR
        /*
-        * core 0 thread 0: pir reset value 0x00, new pir 0
-        * core 0 thread 1: pir reset value 0x01, new pir 1
-        * core 1 thread 0: pir reset value 0x08, new pir 2
-        * core 1 thread 1: pir reset value 0x09, new pir 3
-        * core 2 thread 0: pir reset value 0x10, new pir 4
-        * core 2 thread 1: pir reset value 0x11, new pir 5
-        * etc.
-        *
-        * Only thread 0 of each core will be running, updating PIR doesn't
-        * need to deal with the thread bits.
+        * r10 has the base address for the entry.
+        * we cannot access it yet before setting up a new TLB
         */
-       rlwinm  r4,r0,30,24,30
-#endif
+       slwi    r8,r5,6 /* spin table is padded to 64 byte */
+       add     r10,r3,r8
 
        mtspr   SPRN_PIR,r4     /* write to PIR register */
 
index f00b1ab..a4d6e9c 100644 (file)
@@ -112,23 +112,20 @@ void get_sys_info (sys_info_t * sysInfo)
 #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
+        * The cluster assignment is fixed per SoC. PLL1, PLL2, PLL3 are
+        * cluster group A, feeding cores on cluster 1 and cluster 2.
+        * PLL4, PLL5, PLL6 are cluster group B, feeding cores on cluster 3
+        * and cluster 4 if existing.
         */
        for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
-               u32 c_pll_sel = (in_be32(&clk->clkc0csr + (cpu / 4) * 8) >> 27)
+               int cluster = fsl_qoriq_core_to_cluster(cpu);
+               u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 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;
-
+               cplx_pll += (cluster / 2) * 3;
                sysInfo->freqProcessor[cpu] =
                         freqCC_PLL[cplx_pll] / core_cplx_PLL_div[c_pll_sel];
        }
@@ -240,7 +237,8 @@ void get_sys_info (sys_info_t * sysInfo)
 #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 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
+                               & 0xf;
                u32 cplx_pll = core_cplx_PLL[c_pll_sel];
 
                sysInfo->freqProcessor[cpu] =
index 23e008e..bc26855 100644 (file)
@@ -103,35 +103,70 @@ static struct cpu_type cpu_type_list[] = {
 };
 
 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
+static inline u32 init_type(u32 cluster, int init_id)
+{
+       ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK;
+       u32 type = in_be32(&gur->tp_ityp[idx]);
+
+       if (type & TP_ITYP_AV)
+               return type;
+
+       return 0;
+}
+
 u32 compute_ppc_cpumask(void)
 {
-       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
        int i = 0, count = 0;
-       u32 cluster, mask = 0;
+       u32 cluster, type, mask = 0;
 
        do {
                int j;
-               cluster = in_be32(&gur->tp_cluster[i++].lower);
-               for (j = 0; j < 4; j++) {
-                       u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK;
-                       u32 type = in_be32(&gur->tp_ityp[idx]);
-
-                       if (type & TP_ITYP_AV) {
+               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_PPC)
                                        mask |= 1 << count;
+                               count++;
                        }
-                       count++;
                }
+               i++;
        } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
 
        return mask;
 }
+
+int fsl_qoriq_core_to_cluster(unsigned int core)
+{
+       ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       int i = 0, count = 0;
+       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 */
+}
+
 #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
 /*
  * Before chassis genenration 2, the cpumask should be hard-coded.
  * In case of cpu type unknown or cpumask unset, use 1 as fail save.
  */
 #define compute_ppc_cpumask()  1
+#define fsl_qoriq_core_to_cluster(x) x
 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
 
 static struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0);
index 08e1238..dd68335 100644 (file)
 #define CONFIG_SYS_PPC64               /* 64-bit core */
 #define CONFIG_FSL_CORENET             /* Freescale CoreNet platform */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS2  /* Freescale Chassis generation 2 */
+#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
 #define CONFIG_SYS_FSL_QMAN_V3         /* QMAN version 3 */
 #ifdef CONFIG_PPC_T4240
 #define CONFIG_MAX_CPUS                        12
 #define CONFIG_SYS_PPC64               /* 64-bit core */
 #define CONFIG_FSL_CORENET             /* Freescale CoreNet platform */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS2  /* Freescale Chassis generation 2 */
+#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
 #define CONFIG_SYS_FSL_QMAN_V3         /* QMAN version 3 */
 #define CONFIG_MAX_CPUS                        2
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     4
 #define CONFIG_SYS_PPC64               /* 64-bit core */
 #define CONFIG_FSL_CORENET             /* Freescale CoreNet platform */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS2  /* Freescale Chassis generation 2 */
+#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
 #define CONFIG_SYS_FSL_QMAN_V3         /* QMAN version 3 */
 #define CONFIG_MAX_CPUS                        4
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     4
 #define CONFIG_E5500
 #define CONFIG_FSL_CORENET             /* Freescale CoreNet platform */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS2  /* Freescale Chassis generation 2 */
+#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1
 #define CONFIG_SYS_FSL_QMAN_V3         /* QMAN version 3 */
 #define CONFIG_MAX_CPUS                        4
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     5
 #error "CONFIG_SYS_CCSRBAR_DEFAULT is not defined for this platform."
 #endif
 
+#ifdef CONFIG_E6500
+#define CONFIG_SYS_FSL_THREADS_PER_CORE 2
+#else
+#define CONFIG_SYS_FSL_THREADS_PER_CORE 1
+#endif
+
 #endif /* _ASM_MPC85xx_CONFIG_H_ */
index 46f2e1c..4052037 100644 (file)
@@ -1996,6 +1996,7 @@ typedef struct ccsr_gur {
 
 #define TP_CLUSTER_EOC         0x80000000      /* end of clusters */
 #define TP_CLUSTER_INIT_MASK   0x0000003f      /* initiator mask */
+#define TP_INIT_PER_CLUSTER    4
 
 #define FSL_CORENET_DCSR_SZ_MASK       0x00000003
 #define FSL_CORENET_DCSR_SZ_4M         0x0
@@ -2008,22 +2009,13 @@ typedef struct ccsr_gur {
 #define rmuliodnr rio1maintliodnr
 
 typedef struct ccsr_clk {
-       u32     clkc0csr;       /* 0x000 Core 0 Clock control/status */
-       u8      res1[0x1c];
-       u32     clkc1csr;       /* 0x020 Core 1 Clock control/status */
-       u8      res2[0x1c];
-       u32     clkc2csr;       /* 0x040 Core 2 Clock control/status */
-       u8      res3[0x1c];
-       u32     clkc3csr;       /* 0x060 Core 3 Clock control/status */
-       u8      res4[0x1c];
-       u32     clkc4csr;       /* 0x080 Core 4 Clock control/status */
-       u8      res5[0x1c];
-       u32     clkc5csr;       /* 0x0a0 Core 5 Clock control/status */
-       u8      res6[0x1c];
-       u32     clkc6csr;       /* 0x0c0 Core 6 Clock control/status */
-       u8      res7[0x1c];
-       u32     clkc7csr;       /* 0x0e0 Core 7 Clock control/status */
-       u8      res8[0x71c];
+       struct {
+               u32 clkcncsr;   /* core cluster n clock control status */
+               u8  res_004[0x0c];
+               u32 clkcgnhwacsr;/* clock generator n hardware accelerator */
+               u8  res_014[0x0c];
+       } clkcsr[8];
+       u8      res_100[0x700]; /* 0x100 */
        u32     pllc1gsr;       /* 0x800 Cluster PLL 1 General Status */
        u8      res10[0x1c];
        u32     pllc2gsr;       /* 0x820 Cluster PLL 2 General Status */
index 5799386..56b22d8 100644 (file)
@@ -1200,6 +1200,8 @@ struct cpu_type {
 struct cpu_type *identify_cpu(u32 ver);
 int fixup_cpu(void);
 
+int fsl_qoriq_core_to_cluster(unsigned int core);
+
 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
 #define CPU_TYPE_ENTRY(n, v, nc) \
        { .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), \