brcm63xx: fix spi flash setup on (at least) some reference boards
[openwrt.git] / target / linux / brcm63xx / patches-3.10 / 343-MIPS-BCM63XX-add-PCIe-support-for-BCM6318.patch
1 From 11a8ab8dac4ef5d0d70199843043927edce1d4db Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Sun, 15 Dec 2013 20:47:34 +0100
4 Subject: [PATCH 53/53] MIPS: BCM63XX: add PCIe support for BCM6318
5
6 ---
7  arch/mips/bcm63xx/clk.c                           |  25 ++++-
8  arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h   |   6 ++
9  arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h |  60 +++++++++++-
10  arch/mips/pci/ops-bcm63xx.c                       |  16 +++-
11  arch/mips/pci/pci-bcm63xx.c                       | 106 ++++++++++++++++++----
12  5 files changed, 184 insertions(+), 29 deletions(-)
13
14 --- a/arch/mips/bcm63xx/clk.c
15 +++ b/arch/mips/bcm63xx/clk.c
16 @@ -50,6 +50,18 @@ static void bcm_hwclock_set(u32 mask, in
17         bcm_perf_writel(reg, PERF_CKCTL_REG);
18  }
19  
20 +static void bcm_ub_hwclock_set(u32 mask, int enable)
21 +{
22 +       u32 reg;
23 +
24 +       reg = bcm_perf_readl(PERF_UB_CKCTL_REG);
25 +       if (enable)
26 +               reg |= mask;
27 +       else
28 +               reg &= ~mask;
29 +       bcm_perf_writel(reg, PERF_UB_CKCTL_REG);
30 +}
31 +
32  /*
33   * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
34   */
35 @@ -317,12 +329,17 @@ static struct clk clk_ipsec = {
36  
37  static void pcie_set(struct clk *clk, int enable)
38  {
39 -       if (BCMCPU_IS_6328())
40 +       if (BCMCPU_IS_6318()) {
41 +               bcm_hwclock_set(CKCTL_6318_PCIE_EN, enable);
42 +               bcm_hwclock_set(CKCTL_6318_PCIE25_EN, enable);
43 +               bcm_ub_hwclock_set(UB_CKCTL_6318_PCIE_EN, enable);
44 +       } else if (BCMCPU_IS_6328()) {
45                 bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
46 -       else if (BCMCPU_IS_6362())
47 +       } else if (BCMCPU_IS_6362()) {
48                 bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable);
49 -       else if (BCMCPU_IS_63268())
50 +       } else if (BCMCPU_IS_63268()) {
51                 bcm_hwclock_set(CKCTL_63268_PCIE_EN, enable);
52 +       }
53  }
54  
55  static struct clk clk_pcie = {
56 @@ -393,7 +410,7 @@ struct clk *clk_get(struct device *dev,
57         if ((BCMCPU_IS_6362() || BCMCPU_IS_6368() || BCMCPU_IS_63268()) &&
58             !strcmp(id, "ipsec"))
59                 return &clk_ipsec;
60 -       if ((BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) &&
61 +       if ((BCMCPU_IS_6318() || BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) &&
62             !strcmp(id, "pcie"))
63                 return &clk_pcie;
64         return ERR_PTR(-ENOENT);
65 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
66 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
67 @@ -40,6 +40,12 @@
68  #define BCM_CB_MEM_END_PA              (BCM_CB_MEM_BASE_PA +           \
69                                         BCM_CB_MEM_SIZE - 1)
70  
71 +#define BCM_PCIE_MEM_BASE_PA_6318      0x10200000
72 +#define BCM_PCIE_MEM_SIZE_6318         (1 * 1024 * 1024)
73 +#define BCM_PCIE_MEM_END_PA_6318       (BCM_PCIE_MEM_BASE_PA_6318 +    \
74 +                                       BCM_PCIE_MEM_SIZE_6318 - 1)
75 +
76 +
77  #define BCM_PCIE_MEM_BASE_PA_6328      0x10f00000
78  #define BCM_PCIE_MEM_SIZE_6328         (1 * 1024 * 1024)
79  #define BCM_PCIE_MEM_END_PA_6328       (BCM_PCIE_MEM_BASE_PA_6328 +    \
80 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
81 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
82 @@ -1662,6 +1662,17 @@
83   * _REG relative to RSET_PCIE
84   *************************************************************************/
85  
86 +#define PCIE_SPECIFIC_REG              0x188
87 +#define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT        0
88 +#define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
89 +#define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT        2
90 +#define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
91 +#define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT        4
92 +#define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
93 +#define SPECIFIC_ENDIAN_MODE_WORD_ALIGN        0
94 +#define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1
95 +#define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN        2
96 +
97  #define PCIE_CONFIG2_REG               0x408
98  #define CONFIG2_BAR1_SIZE_EN           1
99  #define CONFIG2_BAR1_SIZE_MASK         0xf
100 @@ -1707,7 +1718,54 @@
101  #define PCIE_RC_INT_C                  (1 << 2)
102  #define PCIE_RC_INT_D                  (1 << 3)
103  
104 -#define PCIE_DEVICE_OFFSET             0x8000
105 +#define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG        0x400c
106 +#define C2P_MEM_WIN_ENDIAN_MODE_MASK   0x3
107 +#define C2P_MEM_WIN_ENDIAN_NO_SWAP     0
108 +#define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1
109 +#define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2
110 +#define C2P_MEM_WIN_BASE_ADDR_SHIFT    20
111 +#define C2P_MEM_WIN_BASE_ADDR_MASK     (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT)
112 +
113 +#define PCIE_RC_BAR1_CONFIG_LO_REG     0x402c
114 +#define RC_BAR_CFG_LO_SIZE_256MB       0xd
115 +#define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20
116 +#define RC_BAR_CFG_LO_MATCH_ADDR_MASK  (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT)
117 +
118 +#define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070
119 +#define C2P_BASELIMIT_LIMIT_SHIFT      20
120 +#define C2P_BASELIMIT_LIMIT_MASK       (0xfff << C2P_BASELIMIT_LIMIT_SHIFT)
121 +#define C2P_BASELIMIT_BASE_SHIFT       4
122 +#define C2P_BASELIMIT_BASE_MASK                (0xfff << C2P_BASELIMIT_BASE_SHIFT)
123 +
124 +#define PCIE_UBUS_BAR1_CFG_REMAP_REG   0x4088
125 +#define BAR1_CFG_REMAP_OFFSET_SHIFT    20
126 +#define BAR1_CFG_REMAP_OFFSET_MASK     (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT)
127 +#define BAR1_CFG_REMAP_ACCESS_EN       1
128 +
129 +#define PCIE_HARD_DEBUG_REG            0x4204
130 +#define HARD_DEBUG_SERDES_IDDQ         (1 << 23)
131 +
132 +#define PCIE_CPU_INT1_MASK_CLEAR_REG   0x830c
133 +#define CPU_INT_PCIE_ERR_ATTN_CPU      (1 << 0)
134 +#define CPU_INT_PCIE_INTA              (1 << 1)
135 +#define CPU_INT_PCIE_INTB              (1 << 2)
136 +#define CPU_INT_PCIE_INTC              (1 << 3)
137 +#define CPU_INT_PCIE_INTD              (1 << 4)
138 +#define CPU_INT_PCIE_INTR              (1 << 5)
139 +#define CPU_INT_PCIE_NMI               (1 << 6)
140 +#define CPU_INT_PCIE_UBUS              (1 << 7)
141 +#define CPU_INT_IPI                    (1 << 8)
142 +
143 +#define PCIE_EXT_CFG_INDEX_REG         0x8400
144 +#define EXT_CFG_FUNC_NUM_SHIFT         12
145 +#define EXT_CFG_FUNC_NUM_MASK          (0x7 << EXT_CFG_FUNC_NUM_SHIFT)
146 +#define EXT_CFG_DEV_NUM_SHIFT          15
147 +#define EXT_CFG_DEV_NUM_MASK           (0xf << EXT_CFG_DEV_NUM_SHIFT)
148 +#define EXT_CFG_BUS_NUM_SHIFT          20
149 +#define EXT_CFG_BUS_NUM_MASK           (0xff << EXT_CFG_BUS_NUM_SHIFT)
150 +
151 +#define PCIE_DEVICE_OFFSET_6318                0x9000
152 +#define PCIE_DEVICE_OFFSET_6328                0x8000
153  
154  /*************************************************************************
155   * _REG relative to RSET_OTP
156 --- a/arch/mips/pci/ops-bcm63xx.c
157 +++ b/arch/mips/pci/ops-bcm63xx.c
158 @@ -489,8 +489,12 @@ static int bcm63xx_pcie_read(struct pci_
159         if (!bcm63xx_pcie_can_access(bus, devfn))
160                 return PCIBIOS_DEVICE_NOT_FOUND;
161  
162 -       if (bus->number == PCIE_BUS_DEVICE)
163 -               reg += PCIE_DEVICE_OFFSET;
164 +       if (bus->number == PCIE_BUS_DEVICE) {
165 +               if (BCMCPU_IS_6318())
166 +                       reg += PCIE_DEVICE_OFFSET_6318;
167 +               else
168 +                       reg += PCIE_DEVICE_OFFSET_6328;
169 +       }
170  
171         data = bcm_pcie_readl(reg);
172  
173 @@ -509,8 +513,12 @@ static int bcm63xx_pcie_write(struct pci
174         if (!bcm63xx_pcie_can_access(bus, devfn))
175                 return PCIBIOS_DEVICE_NOT_FOUND;
176  
177 -       if (bus->number == PCIE_BUS_DEVICE)
178 -               reg += PCIE_DEVICE_OFFSET;
179 +       if (bus->number == PCIE_BUS_DEVICE) {
180 +               if (BCMCPU_IS_6318())
181 +                       reg += PCIE_DEVICE_OFFSET_6318;
182 +               else
183 +                       reg += PCIE_DEVICE_OFFSET_6328;
184 +       }
185  
186  
187         data = bcm_pcie_readl(reg);
188 --- a/arch/mips/pci/pci-bcm63xx.c
189 +++ b/arch/mips/pci/pci-bcm63xx.c
190 @@ -118,7 +118,7 @@ static void bcm63xx_int_cfg_writel(u32 v
191  
192  void __iomem *pci_iospace_start;
193  
194 -static void __init bcm63xx_reset_pcie(void)
195 +static void __init bcm63xx_reset_pcie_gen1(void)
196  {
197         u32 val;
198         u32 reg;
199 @@ -152,20 +152,32 @@ static void __init bcm63xx_reset_pcie(vo
200         mdelay(200);
201  }
202  
203 -static struct clk *pcie_clk;
204 -
205 -static int __init bcm63xx_register_pcie(void)
206 +static void __init bcm63xx_reset_pcie_gen2(void)
207  {
208         u32 val;
209  
210 -       /* enable clock */
211 -       pcie_clk = clk_get(NULL, "pcie");
212 -       if (IS_ERR_OR_NULL(pcie_clk))
213 -               return -ENODEV;
214 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_HARD, 0);
215  
216 -       clk_prepare_enable(pcie_clk);
217 +       /* reset the PCIe core */
218 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1);
219 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1);
220 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 1);
221 +       mdelay(10);
222 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0);
223 +       mdelay(10);
224 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0);
225 +       mdelay(10);
226 +       val = bcm_pcie_readl(PCIE_HARD_DEBUG_REG);
227 +       val &= ~HARD_DEBUG_SERDES_IDDQ;
228 +       bcm_pcie_writel(val, PCIE_HARD_DEBUG_REG);
229 +       mdelay(10);
230 +       bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_CORE, 0);
231 +       mdelay(200);
232 +}
233  
234 -       bcm63xx_reset_pcie();
235 +static void __init bcm63xx_init_pcie_gen1(void)
236 +{
237 +       u32 val;
238  
239         /* configure the PCIe bridge */
240         val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG);
241 @@ -190,6 +202,65 @@ static int __init bcm63xx_register_pcie(
242         val |= OPT2_CFG_TYPE1_BD_SEL;
243         bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG);
244  
245 +       /* set bar0 to little endian */
246 +       val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT;
247 +       val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT;
248 +       val |= BASEMASK_REMAP_EN;
249 +       bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
250 +
251 +       val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT;
252 +       bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
253 +}
254 +
255 +static void __init bcm63xx_init_pcie_gen2(void)
256 +{
257 +       u32 val;
258 +
259 +       bcm_pcie_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB |
260 +                       CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD,
261 +                       PCIE_CPU_INT1_MASK_CLEAR_REG);
262 +
263 +       val = bcm_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK;
264 +       val |= (bcm_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT) <<
265 +              C2P_BASELIMIT_BASE_SHIFT;
266 +
267 +       bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG);
268 +
269 +       /* set bar0 to little endian */
270 +       val = bcm_pcie_readl(PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
271 +       val |= bcm_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK;
272 +       val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP;
273 +       bcm_pcie_writel(val, PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
274 +
275 +       bcm_pcie_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN, PCIE_SPECIFIC_REG);
276 +       bcm_pcie_writel(RC_BAR_CFG_LO_SIZE_256MB, PCIE_RC_BAR1_CONFIG_LO_REG);
277 +       bcm_pcie_writel(BAR1_CFG_REMAP_ACCESS_EN, PCIE_UBUS_BAR1_CFG_REMAP_REG);
278 +
279 +       bcm_pcie_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT,
280 +                       PCIE_EXT_CFG_INDEX_REG);
281 +}
282 +
283 +static struct clk *pcie_clk;
284 +
285 +static int __init bcm63xx_register_pcie(void)
286 +{
287 +       u32 val;
288 +
289 +       /* enable clock */
290 +       pcie_clk = clk_get(NULL, "pcie");
291 +       if (IS_ERR_OR_NULL(pcie_clk))
292 +               return -ENODEV;
293 +
294 +       clk_prepare_enable(pcie_clk);
295 +
296 +       if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_63268()) {
297 +               bcm63xx_reset_pcie_gen1();
298 +               bcm63xx_init_pcie_gen1();
299 +       } else {
300 +               bcm63xx_reset_pcie_gen2();
301 +               bcm63xx_init_pcie_gen2();
302 +       }
303 +
304         /* setup class code as bridge */
305         val = bcm_pcie_readl(PCIE_IDVAL3_REG);
306         val &= ~IDVAL3_CLASS_CODE_MASK;
307 @@ -201,15 +272,6 @@ static int __init bcm63xx_register_pcie(
308         val &= ~CONFIG2_BAR1_SIZE_MASK;
309         bcm_pcie_writel(val, PCIE_CONFIG2_REG);
310  
311 -       /* set bar0 to little endian */
312 -       val = (bcm_pcie_mem_resource.start >> 20) << BASEMASK_BASE_SHIFT;
313 -       val |= (bcm_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT;
314 -       val |= BASEMASK_REMAP_EN;
315 -       bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
316 -
317 -       val = (bcm_pcie_mem_resource.start >> 20) << REBASE_ADDR_BASE_SHIFT;
318 -       bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
319 -
320         register_pci_controller(&bcm63xx_pcie_controller);
321  
322         return 0;
323 @@ -341,7 +403,10 @@ static int __init bcm63xx_pci_init(void)
324         if (!bcm63xx_pci_enabled)
325                 return -ENODEV;
326  
327 -       if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
328 +       if (BCMCPU_IS_6318()) {
329 +               bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6318;
330 +               bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6318;
331 +       } if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
332                 bcm_pcie_mem_resource.start = BCM_PCIE_MEM_BASE_PA_6328;
333                 bcm_pcie_mem_resource.end = BCM_PCIE_MEM_END_PA_6328;
334         } else if (BCMCPU_IS_63268()) {
335 @@ -350,6 +415,7 @@ static int __init bcm63xx_pci_init(void)
336         }
337  
338         switch (bcm63xx_get_cpu_id()) {
339 +       case BCM6318_CPU_ID:
340         case BCM6328_CPU_ID:
341         case BCM6362_CPU_ID:
342         case BCM63268_CPU_ID: