Commit fa18ed76589a684fc9ba14b68d7b917b1bea16cf

Authored by Wenbin Song
Committed by York Sun
1 parent 435cca1671

armv8/ls1043a: fixup GIC offset for ls1043a rev1

The LS1043A rev1.1 silicon supports two types of GIC offset: 4K
alignment and 64K alignment. The bit SCFG_GIC400_ALIGN[GIC_ADDR_BIT]
is used to choose which offset will be used.

The LS1043A rev1.0 silicon only supports the CIG offset with 4K
alignment.

If GIC_ADDR_BIT bit is set, 4K alignment is used, or else 64K alignment
is used. 64K alignment is the default setting.

Overriding the weak smp_kick_all_cpus, the new impletment is able to
detect GIC offset.

The default GIC offset in kernel device tree is using 4K alignment, it
need to be fixed if 64K alignment is detected.

Signed-off-by: Wenbin Song <wenbin.song@nxp.com>
Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com>
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>

Showing 6 changed files with 150 additions and 6 deletions Side-by-side Diff

arch/arm/cpu/armv8/fsl-layerscape/Kconfig
... ... @@ -90,6 +90,11 @@
90 90 This compatible is used to find pci controller node in Kernel DT
91 91 to complete fixup.
92 92  
  93 +config HAS_FEATURE_GIC64K_ALIGN
  94 + bool
  95 + default y if ARCH_LS1043A
  96 +
  97 +
93 98 menu "Layerscape PPA"
94 99 config FSL_LS_PPA
95 100 bool "FSL Layerscape PPA firmware support"
arch/arm/cpu/armv8/fsl-layerscape/fdt.c
... ... @@ -133,6 +133,67 @@
133 133 }
134 134 }
135 135  
  136 +#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
  137 +static void fdt_fixup_gic(void *blob)
  138 +{
  139 + int offset, err;
  140 + u64 reg[8];
  141 + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  142 + unsigned int val;
  143 + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  144 + int align_64k = 0;
  145 +
  146 + val = gur_in32(&gur->svr);
  147 +
  148 + if (SVR_SOC_VER(val) != SVR_LS1043A) {
  149 + align_64k = 1;
  150 + } else if (SVR_REV(val) != REV1_0) {
  151 + val = scfg_in32(&scfg->gic_align) & (0x01 << GIC_ADDR_BIT);
  152 + if (!val)
  153 + align_64k = 1;
  154 + }
  155 +
  156 + offset = fdt_subnode_offset(blob, 0, "interrupt-controller@1400000");
  157 + if (offset < 0) {
  158 + printf("WARNING: fdt_subnode_offset can't find node %s: %s\n",
  159 + "interrupt-controller@1400000", fdt_strerror(offset));
  160 + return;
  161 + }
  162 +
  163 + /* Fixup gic node align with 64K */
  164 + if (align_64k) {
  165 + reg[0] = cpu_to_fdt64(GICD_BASE_64K);
  166 + reg[1] = cpu_to_fdt64(GICD_SIZE_64K);
  167 + reg[2] = cpu_to_fdt64(GICC_BASE_64K);
  168 + reg[3] = cpu_to_fdt64(GICC_SIZE_64K);
  169 + reg[4] = cpu_to_fdt64(GICH_BASE_64K);
  170 + reg[5] = cpu_to_fdt64(GICH_SIZE_64K);
  171 + reg[6] = cpu_to_fdt64(GICV_BASE_64K);
  172 + reg[7] = cpu_to_fdt64(GICV_SIZE_64K);
  173 + } else {
  174 + /* Fixup gic node align with default */
  175 + reg[0] = cpu_to_fdt64(GICD_BASE);
  176 + reg[1] = cpu_to_fdt64(GICD_SIZE);
  177 + reg[2] = cpu_to_fdt64(GICC_BASE);
  178 + reg[3] = cpu_to_fdt64(GICC_SIZE);
  179 + reg[4] = cpu_to_fdt64(GICH_BASE);
  180 + reg[5] = cpu_to_fdt64(GICH_SIZE);
  181 + reg[6] = cpu_to_fdt64(GICV_BASE);
  182 + reg[7] = cpu_to_fdt64(GICV_SIZE);
  183 + }
  184 +
  185 + err = fdt_setprop(blob, offset, "reg", reg, sizeof(reg));
  186 + if (err < 0) {
  187 + printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
  188 + "reg", "interrupt-controller@1400000",
  189 + fdt_strerror(err));
  190 + return;
  191 + }
  192 +
  193 + return;
  194 +}
  195 +#endif
  196 +
136 197 void ft_cpu_setup(void *blob, bd_t *bd)
137 198 {
138 199 #ifdef CONFIG_FSL_LSCH2
... ... @@ -177,5 +238,8 @@
177 238 #endif
178 239 fsl_fdt_disable_usb(blob);
179 240  
  241 +#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
  242 + fdt_fixup_gic(blob);
  243 +#endif
180 244 }
arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
... ... @@ -10,15 +10,66 @@
10 10 #include <linux/linkage.h>
11 11 #include <asm/gic.h>
12 12 #include <asm/macro.h>
  13 +#include <asm/arch-fsl-layerscape/soc.h>
13 14 #ifdef CONFIG_MP
14 15 #include <asm/arch/mp.h>
15 16 #endif
16 17 #ifdef CONFIG_FSL_LSCH3
17 18 #include <asm/arch-fsl-layerscape/immap_lsch3.h>
18   -#include <asm/arch-fsl-layerscape/soc.h>
19 19 #endif
20 20 #include <asm/u-boot.h>
21 21  
  22 +/* Get GIC offset
  23 +* For LS1043a rev1.0, GIC base address align with 4k.
  24 +* For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
  25 +* is set, GIC base address align with 4K, or else align
  26 +* with 64k.
  27 +* output:
  28 +* x0: the base address of GICD
  29 +* x1: the base address of GICC
  30 +*/
  31 +ENTRY(get_gic_offset)
  32 + ldr x0, =GICD_BASE
  33 +#ifdef CONFIG_GICV2
  34 + ldr x1, =GICC_BASE
  35 +#endif
  36 +#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
  37 + ldr x2, =DCFG_CCSR_SVR
  38 + ldr w2, [x2]
  39 + rev w2, w2
  40 + mov w3, w2
  41 + ands w3, w3, #SVR_WO_E << 8
  42 + mov w4, #SVR_LS1043A << 8
  43 + cmp w3, w4
  44 + b.ne 1f
  45 + ands w2, w2, #0xff
  46 + cmp w2, #REV1_0
  47 + b.eq 1f
  48 + ldr x2, =SCFG_GIC400_ALIGN
  49 + ldr w2, [x2]
  50 + rev w2, w2
  51 + tbnz w2, #GIC_ADDR_BIT, 1f
  52 + ldr x0, =GICD_BASE_64K
  53 +#ifdef CONFIG_GICV2
  54 + ldr x1, =GICC_BASE_64K
  55 +#endif
  56 +1:
  57 +#endif
  58 + ret
  59 +ENDPROC(get_gic_offset)
  60 +
  61 +ENTRY(smp_kick_all_cpus)
  62 + /* Kick secondary cpus up by SGI 0 interrupt */
  63 +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
  64 + mov x29, lr /* Save LR */
  65 + bl get_gic_offset
  66 + bl gic_kick_secondary_cpus
  67 + mov lr, x29 /* Restore LR */
  68 +#endif
  69 + ret
  70 +ENDPROC(smp_kick_all_cpus)
  71 +
  72 +
22 73 ENTRY(lowlevel_init)
23 74 mov x29, lr /* Save LR */
24 75  
25 76  
... ... @@ -130,15 +181,14 @@
130 181 /* Initialize GIC Secure Bank Status */
131 182 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
132 183 branch_if_slave x0, 1f
133   - ldr x0, =GICD_BASE
  184 + bl get_gic_offset
134 185 bl gic_init_secure
135 186 1:
136 187 #ifdef CONFIG_GICV3
137 188 ldr x0, =GICR_BASE
138 189 bl gic_init_secure_percpu
139 190 #elif defined(CONFIG_GICV2)
140   - ldr x0, =GICD_BASE
141   - ldr x1, =GICC_BASE
  191 + bl get_gic_offset
142 192 bl gic_init_secure_percpu
143 193 #endif
144 194 #endif
... ... @@ -413,7 +463,8 @@
413 463 #if defined(CONFIG_GICV3)
414 464 gic_wait_for_interrupt_m x0
415 465 #elif defined(CONFIG_GICV2)
416   - ldr x0, =GICC_BASE
  466 + bl get_gic_offset
  467 + mov x0, x1
417 468 gic_wait_for_interrupt_m x0, w1
418 469 #endif
419 470  
arch/arm/include/asm/arch-fsl-layerscape/config.h
... ... @@ -163,6 +163,28 @@
163 163 /* Generic Interrupt Controller Definitions */
164 164 #define GICD_BASE 0x01401000
165 165 #define GICC_BASE 0x01402000
  166 +#define GICH_BASE 0x01404000
  167 +#define GICV_BASE 0x01406000
  168 +#define GICD_SIZE 0x1000
  169 +#define GICC_SIZE 0x2000
  170 +#define GICH_SIZE 0x2000
  171 +#define GICV_SIZE 0x2000
  172 +#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
  173 +#define GICD_BASE_64K 0x01410000
  174 +#define GICC_BASE_64K 0x01420000
  175 +#define GICH_BASE_64K 0x01440000
  176 +#define GICV_BASE_64K 0x01460000
  177 +#define GICD_SIZE_64K 0x10000
  178 +#define GICC_SIZE_64K 0x20000
  179 +#define GICH_SIZE_64K 0x20000
  180 +#define GICV_SIZE_64K 0x20000
  181 +#endif
  182 +
  183 +#define DCFG_CCSR_SVR 0x1ee00a4
  184 +#define REV1_0 0x10
  185 +#define REV1_1 0x11
  186 +#define GIC_ADDR_BIT 31
  187 +#define SCFG_GIC400_ALIGN 0x1570188
166 188  
167 189 #define CONFIG_SYS_FSL_MAX_NUM_OF_SEC 1
168 190  
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
... ... @@ -361,7 +361,8 @@
361 361 u32 qspi_cfg;
362 362 u8 res_160[0x180-0x160];
363 363 u32 dmamcr;
364   - u8 res_184[0x18c-0x184];
  364 + u8 res_184[0x188-0x184];
  365 + u32 gic_align;
365 366 u32 debug_icid;
366 367 u8 res_190[0x1a4-0x190];
367 368 u32 snpcnfgcr;
arch/arm/include/asm/arch-fsl-layerscape/soc.h
... ... @@ -59,6 +59,7 @@
59 59  
60 60 #define SVR_MAJ(svr) (((svr) >> 4) & 0xf)
61 61 #define SVR_MIN(svr) (((svr) >> 0) & 0xf)
  62 +#define SVR_REV(svr) (((svr) >> 0) & 0xff)
62 63 #define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E)
63 64 #define IS_E_PROCESSOR(svr) (!((svr >> 8) & 0x1))
64 65 #define IS_SVR_REV(svr, maj, min) \