arm: mvebu: Add basic support for the Marvell Armada 375 SoC
[oweals/u-boot.git] / arch / arm / mach-mvebu / cpu.c
1 /*
2  * Copyright (C) 2014-2016 Stefan Roese <sr@denx.de>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <ahci.h>
9 #include <linux/mbus.h>
10 #include <asm/io.h>
11 #include <asm/pl310.h>
12 #include <asm/arch/cpu.h>
13 #include <asm/arch/soc.h>
14 #include <sdhci.h>
15
16 #define DDR_BASE_CS_OFF(n)      (0x0000 + ((n) << 3))
17 #define DDR_SIZE_CS_OFF(n)      (0x0004 + ((n) << 3))
18
19 static struct mbus_win windows[] = {
20         /* SPI */
21         { MBUS_SPI_BASE, MBUS_SPI_SIZE,
22           CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH },
23
24         /* NOR */
25         { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,
26           CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM },
27 };
28
29 void lowlevel_init(void)
30 {
31         /*
32          * Dummy implementation, we only need LOWLEVEL_INIT
33          * on Armada to configure CP15 in start.S / cpu_init_cp15()
34          */
35 }
36
37 void reset_cpu(unsigned long ignored)
38 {
39         struct mvebu_system_registers *reg =
40                 (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE;
41
42         writel(readl(&reg->rstoutn_mask) | 1, &reg->rstoutn_mask);
43         writel(readl(&reg->sys_soft_rst) | 1, &reg->sys_soft_rst);
44         while (1)
45                 ;
46 }
47
48 int mvebu_soc_family(void)
49 {
50         u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff;
51
52         switch (devid) {
53         case SOC_MV78230_ID:
54         case SOC_MV78260_ID:
55         case SOC_MV78460_ID:
56                 return MVEBU_SOC_AXP;
57
58         case SOC_88F6720_ID:
59                 return MVEBU_SOC_A375;
60
61         case SOC_88F6810_ID:
62         case SOC_88F6820_ID:
63         case SOC_88F6828_ID:
64                 return MVEBU_SOC_A38X;
65         }
66
67         return MVEBU_SOC_UNKNOWN;
68 }
69
70 #if defined(CONFIG_DISPLAY_CPUINFO)
71
72 #if defined(CONFIG_ARMADA_375)
73 /* SAR frequency values for Armada 375 */
74 static const struct sar_freq_modes sar_freq_tab[] = {
75         {  0,  0x0,  266,  133,  266 },
76         {  1,  0x0,  333,  167,  167 },
77         {  2,  0x0,  333,  167,  222 },
78         {  3,  0x0,  333,  167,  333 },
79         {  4,  0x0,  400,  200,  200 },
80         {  5,  0x0,  400,  200,  267 },
81         {  6,  0x0,  400,  200,  400 },
82         {  7,  0x0,  500,  250,  250 },
83         {  8,  0x0,  500,  250,  334 },
84         {  9,  0x0,  500,  250,  500 },
85         { 10,  0x0,  533,  267,  267 },
86         { 11,  0x0,  533,  267,  356 },
87         { 12,  0x0,  533,  267,  533 },
88         { 13,  0x0,  600,  300,  300 },
89         { 14,  0x0,  600,  300,  400 },
90         { 15,  0x0,  600,  300,  600 },
91         { 16,  0x0,  666,  333,  333 },
92         { 17,  0x0,  666,  333,  444 },
93         { 18,  0x0,  666,  333,  666 },
94         { 19,  0x0,  800,  400,  267 },
95         { 20,  0x0,  800,  400,  400 },
96         { 21,  0x0,  800,  400,  534 },
97         { 22,  0x0,  900,  450,  300 },
98         { 23,  0x0,  900,  450,  450 },
99         { 24,  0x0,  900,  450,  600 },
100         { 25,  0x0, 1000,  500,  500 },
101         { 26,  0x0, 1000,  500,  667 },
102         { 27,  0x0, 1000,  333,  500 },
103         { 28,  0x0,  400,  400,  400 },
104         { 29,  0x0, 1100,  550,  550 },
105         { 0xff, 0xff,    0,   0,   0 }  /* 0xff marks end of array */
106 };
107 #elif defined(CONFIG_ARMADA_38X)
108 /* SAR frequency values for Armada 38x */
109 static const struct sar_freq_modes sar_freq_tab[] = {
110         {  0x0,  0x0,  666, 333, 333 },
111         {  0x2,  0x0,  800, 400, 400 },
112         {  0x4,  0x0, 1066, 533, 533 },
113         {  0x6,  0x0, 1200, 600, 600 },
114         {  0x8,  0x0, 1332, 666, 666 },
115         {  0xc,  0x0, 1600, 800, 800 },
116         { 0xff, 0xff,    0,   0,   0 }  /* 0xff marks end of array */
117 };
118 #else
119 /* SAR frequency values for Armada XP */
120 static const struct sar_freq_modes sar_freq_tab[] = {
121         {  0xa,  0x5,  800, 400, 400 },
122         {  0x1,  0x5, 1066, 533, 533 },
123         {  0x2,  0x5, 1200, 600, 600 },
124         {  0x2,  0x9, 1200, 600, 400 },
125         {  0x3,  0x5, 1333, 667, 667 },
126         {  0x4,  0x5, 1500, 750, 750 },
127         {  0x4,  0x9, 1500, 750, 500 },
128         {  0xb,  0x9, 1600, 800, 533 },
129         {  0xb,  0xa, 1600, 800, 640 },
130         {  0xb,  0x5, 1600, 800, 800 },
131         { 0xff, 0xff,    0,   0,   0 }  /* 0xff marks end of array */
132 };
133 #endif
134
135 void get_sar_freq(struct sar_freq_modes *sar_freq)
136 {
137         u32 val;
138         u32 freq;
139         int i;
140
141 #if defined(CONFIG_ARMADA_375)
142         val = readl(CONFIG_SAR2_REG);   /* SAR - Sample At Reset */
143 #else
144         val = readl(CONFIG_SAR_REG);    /* SAR - Sample At Reset */
145 #endif
146         freq = (val & SAR_CPU_FREQ_MASK) >> SAR_CPU_FREQ_OFFS;
147 #if defined(SAR2_CPU_FREQ_MASK)
148         /*
149          * Shift CPU0 clock frequency select bit from SAR2 register
150          * into correct position
151          */
152         freq |= ((readl(CONFIG_SAR2_REG) & SAR2_CPU_FREQ_MASK)
153                  >> SAR2_CPU_FREQ_OFFS) << 3;
154 #endif
155         for (i = 0; sar_freq_tab[i].val != 0xff; i++) {
156                 if (sar_freq_tab[i].val == freq) {
157 #if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X)
158                         *sar_freq = sar_freq_tab[i];
159                         return;
160 #else
161                         int k;
162                         u8 ffc;
163
164                         ffc = (val & SAR_FFC_FREQ_MASK) >>
165                                 SAR_FFC_FREQ_OFFS;
166                         for (k = i; sar_freq_tab[k].ffc != 0xff; k++) {
167                                 if (sar_freq_tab[k].ffc == ffc) {
168                                         *sar_freq = sar_freq_tab[k];
169                                         return;
170                                 }
171                         }
172                         i = k;
173 #endif
174                 }
175         }
176
177         /* SAR value not found, return 0 for frequencies */
178         *sar_freq = sar_freq_tab[i - 1];
179 }
180
181 int print_cpuinfo(void)
182 {
183         u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff;
184         u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff;
185         struct sar_freq_modes sar_freq;
186
187         puts("SoC:   ");
188
189         switch (devid) {
190         case SOC_MV78230_ID:
191                 puts("MV78230-");
192                 break;
193         case SOC_MV78260_ID:
194                 puts("MV78260-");
195                 break;
196         case SOC_MV78460_ID:
197                 puts("MV78460-");
198                 break;
199         case SOC_88F6720_ID:
200                 puts("MV88F6720-");
201                 break;
202         case SOC_88F6810_ID:
203                 puts("MV88F6810-");
204                 break;
205         case SOC_88F6820_ID:
206                 puts("MV88F6820-");
207                 break;
208         case SOC_88F6828_ID:
209                 puts("MV88F6828-");
210                 break;
211         default:
212                 puts("Unknown-");
213                 break;
214         }
215
216         if (mvebu_soc_family() == MVEBU_SOC_AXP) {
217                 switch (revid) {
218                 case 1:
219                         puts("A0");
220                         break;
221                 case 2:
222                         puts("B0");
223                         break;
224                 default:
225                         printf("?? (%x)", revid);
226                         break;
227                 }
228         }
229
230         if (mvebu_soc_family() == MVEBU_SOC_A375) {
231                 switch (revid) {
232                 case MV_88F67XX_A0_ID:
233                         puts("A0");
234                         break;
235                 default:
236                         printf("?? (%x)", revid);
237                         break;
238                 }
239         }
240
241         if (mvebu_soc_family() == MVEBU_SOC_A38X) {
242                 switch (revid) {
243                 case MV_88F68XX_Z1_ID:
244                         puts("Z1");
245                         break;
246                 case MV_88F68XX_A0_ID:
247                         puts("A0");
248                         break;
249                 default:
250                         printf("?? (%x)", revid);
251                         break;
252                 }
253         }
254
255         get_sar_freq(&sar_freq);
256         printf(" at %d MHz\n", sar_freq.p_clk);
257
258         return 0;
259 }
260 #endif /* CONFIG_DISPLAY_CPUINFO */
261
262 /*
263  * This function initialize Controller DRAM Fastpath windows.
264  * It takes the CS size information from the 0x1500 scratch registers
265  * and sets the correct windows sizes and base addresses accordingly.
266  *
267  * These values are set in the scratch registers by the Marvell
268  * DDR3 training code, which is executed by the BootROM before the
269  * main payload (U-Boot) is executed. This training code is currently
270  * only available in the Marvell U-Boot version. It needs to be
271  * ported to mainline U-Boot SPL at some point.
272  */
273 static void update_sdram_window_sizes(void)
274 {
275         u64 base = 0;
276         u32 size, temp;
277         int i;
278
279         for (i = 0; i < SDRAM_MAX_CS; i++) {
280                 size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK;
281                 if (size != 0) {
282                         size |= ~(SDRAM_ADDR_MASK);
283
284                         /* Set Base Address */
285                         temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF);
286                         writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i));
287
288                         /*
289                          * Check if out of max window size and resize
290                          * the window
291                          */
292                         temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) &
293                                 ~(SDRAM_ADDR_MASK)) | 1;
294                         temp |= (size & SDRAM_ADDR_MASK);
295                         writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i));
296
297                         base += ((u64)size + 1);
298                 } else {
299                         /*
300                          * Disable window if not used, otherwise this
301                          * leads to overlapping enabled windows with
302                          * pretty strange results
303                          */
304                         clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1);
305                 }
306         }
307 }
308
309 void mmu_disable(void)
310 {
311         asm volatile(
312                 "mrc p15, 0, r0, c1, c0, 0\n"
313                 "bic r0, #1\n"
314                 "mcr p15, 0, r0, c1, c0, 0\n");
315 }
316
317 #ifdef CONFIG_ARCH_CPU_INIT
318 static void set_cbar(u32 addr)
319 {
320         asm("mcr p15, 4, %0, c15, c0" : : "r" (addr));
321 }
322
323 #define MV_USB_PHY_BASE                 (MVEBU_AXP_USB_BASE + 0x800)
324 #define MV_USB_PHY_PLL_REG(reg)         (MV_USB_PHY_BASE | (((reg) & 0xF) << 2))
325 #define MV_USB_X3_BASE(addr)            (MVEBU_AXP_USB_BASE | BIT(11) | \
326                                          (((addr) & 0xF) << 6))
327 #define MV_USB_X3_PHY_CHANNEL(dev, reg) (MV_USB_X3_BASE((dev) + 1) |    \
328                                          (((reg) & 0xF) << 2))
329
330 static void setup_usb_phys(void)
331 {
332         int dev;
333
334         /*
335          * USB PLL init
336          */
337
338         /* Setup PLL frequency */
339         /* USB REF frequency = 25 MHz */
340         clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605);
341
342         /* Power up PLL and PHY channel */
343         setbits_le32(MV_USB_PHY_PLL_REG(2), BIT(9));
344
345         /* Assert VCOCAL_START */
346         setbits_le32(MV_USB_PHY_PLL_REG(1), BIT(21));
347
348         mdelay(1);
349
350         /*
351          * USB PHY init (change from defaults) specific for 40nm (78X30 78X60)
352          */
353
354         for (dev = 0; dev < 3; dev++) {
355                 setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), BIT(15));
356
357                 /* Assert REG_RCAL_START in channel REG 1 */
358                 setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12));
359                 udelay(40);
360                 clrbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12));
361         }
362 }
363
364 /*
365  * This function is not called from the SPL U-Boot version
366  */
367 int arch_cpu_init(void)
368 {
369         struct pl310_regs *const pl310 =
370                 (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
371
372         /*
373          * Only with disabled MMU its possible to switch the base
374          * register address on Armada 38x. Without this the SDRAM
375          * located at >= 0x4000.0000 is also not accessible, as its
376          * still locked to cache.
377          */
378         mmu_disable();
379
380         /* Linux expects the internal registers to be at 0xf1000000 */
381         writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
382         set_cbar(SOC_REGS_PHY_BASE + 0xC000);
383
384         /*
385          * From this stage on, the SoC detection is working. As we have
386          * configured the internal register base to the value used
387          * in the macros / defines in the U-Boot header (soc.h).
388          */
389
390         if (mvebu_soc_family() == MVEBU_SOC_A38X) {
391                 /*
392                  * To fully release / unlock this area from cache, we need
393                  * to flush all caches and disable the L2 cache.
394                  */
395                 icache_disable();
396                 dcache_disable();
397                 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
398         }
399
400         /*
401          * We need to call mvebu_mbus_probe() before calling
402          * update_sdram_window_sizes() as it disables all previously
403          * configured mbus windows and then configures them as
404          * required for U-Boot. Calling update_sdram_window_sizes()
405          * without this configuration will not work, as the internal
406          * registers can't be accessed reliably because of potenial
407          * double mapping.
408          * After updating the SDRAM access windows we need to call
409          * mvebu_mbus_probe() again, as this now correctly configures
410          * the SDRAM areas that are later used by the MVEBU drivers
411          * (e.g. USB, NETA).
412          */
413
414         /*
415          * First disable all windows
416          */
417         mvebu_mbus_probe(NULL, 0);
418
419         if (mvebu_soc_family() == MVEBU_SOC_AXP) {
420                 /*
421                  * Now the SDRAM access windows can be reconfigured using
422                  * the information in the SDRAM scratch pad registers
423                  */
424                 update_sdram_window_sizes();
425         }
426
427         /*
428          * Finally the mbus windows can be configured with the
429          * updated SDRAM sizes
430          */
431         mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
432
433         if (mvebu_soc_family() == MVEBU_SOC_AXP) {
434                 /* Enable GBE0, GBE1, LCD and NFC PUP */
435                 clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0,
436                                 GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN |
437                                 NAND_PUP_EN | SPI_PUP_EN);
438
439                 /* Configure USB PLL and PHYs on AXP */
440                 setup_usb_phys();
441         }
442
443         /* Enable NAND and NAND arbiter */
444         clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN);
445
446         /* Disable MBUS error propagation */
447         clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0);
448
449         return 0;
450 }
451 #endif /* CONFIG_ARCH_CPU_INIT */
452
453 u32 mvebu_get_nand_clock(void)
454 {
455         return CONFIG_SYS_MVEBU_PLL_CLOCK /
456                 ((readl(MVEBU_CORE_DIV_CLK_CTRL(1)) &
457                   NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS);
458 }
459
460 /*
461  * SOC specific misc init
462  */
463 #if defined(CONFIG_ARCH_MISC_INIT)
464 int arch_misc_init(void)
465 {
466         /* Nothing yet, perhaps we need something here later */
467         return 0;
468 }
469 #endif /* CONFIG_ARCH_MISC_INIT */
470
471 #ifdef CONFIG_MV_SDHCI
472 int board_mmc_init(bd_t *bis)
473 {
474         mv_sdh_init(MVEBU_SDIO_BASE, 0, 0,
475                     SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD);
476
477         return 0;
478 }
479 #endif
480
481 #ifdef CONFIG_SCSI_AHCI_PLAT
482 #define AHCI_VENDOR_SPECIFIC_0_ADDR     0xa0
483 #define AHCI_VENDOR_SPECIFIC_0_DATA     0xa4
484
485 #define AHCI_WINDOW_CTRL(win)           (0x60 + ((win) << 4))
486 #define AHCI_WINDOW_BASE(win)           (0x64 + ((win) << 4))
487 #define AHCI_WINDOW_SIZE(win)           (0x68 + ((win) << 4))
488
489 static void ahci_mvebu_mbus_config(void __iomem *base)
490 {
491         const struct mbus_dram_target_info *dram;
492         int i;
493
494         dram = mvebu_mbus_dram_info();
495
496         for (i = 0; i < 4; i++) {
497                 writel(0, base + AHCI_WINDOW_CTRL(i));
498                 writel(0, base + AHCI_WINDOW_BASE(i));
499                 writel(0, base + AHCI_WINDOW_SIZE(i));
500         }
501
502         for (i = 0; i < dram->num_cs; i++) {
503                 const struct mbus_dram_window *cs = dram->cs + i;
504
505                 writel((cs->mbus_attr << 8) |
506                        (dram->mbus_dram_target_id << 4) | 1,
507                        base + AHCI_WINDOW_CTRL(i));
508                 writel(cs->base >> 16, base + AHCI_WINDOW_BASE(i));
509                 writel(((cs->size - 1) & 0xffff0000),
510                        base + AHCI_WINDOW_SIZE(i));
511         }
512 }
513
514 static void ahci_mvebu_regret_option(void __iomem *base)
515 {
516         /*
517          * Enable the regret bit to allow the SATA unit to regret a
518          * request that didn't receive an acknowlegde and avoid a
519          * deadlock
520          */
521         writel(0x4, base + AHCI_VENDOR_SPECIFIC_0_ADDR);
522         writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA);
523 }
524
525 void scsi_init(void)
526 {
527         printf("MVEBU SATA INIT\n");
528         ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE);
529         ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE);
530         ahci_init((void __iomem *)MVEBU_SATA0_BASE);
531 }
532 #endif
533
534 void enable_caches(void)
535 {
536         /* Avoid problem with e.g. neta ethernet driver */
537         invalidate_dcache_all();
538
539         /* Enable D-cache. I-cache is already enabled in start.S */
540         dcache_enable();
541 }
542
543 void v7_outer_cache_enable(void)
544 {
545         if (mvebu_soc_family() == MVEBU_SOC_AXP) {
546                 struct pl310_regs *const pl310 =
547                         (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
548                 u32 u;
549
550                 /* The L2 cache is already disabled at this point */
551
552                 /*
553                  * For Aurora cache in no outer mode, enable via the CP15
554                  * coprocessor broadcasting of cache commands to L2.
555                  */
556                 asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
557                 u |= BIT(8);            /* Set the FW bit */
558                 asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
559
560                 isb();
561
562                 /* Enable the L2 cache */
563                 setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
564         }
565 }
566
567 void v7_outer_cache_disable(void)
568 {
569         struct pl310_regs *const pl310 =
570                 (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
571
572         clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
573 }