1350b50eeSStefan Roese /* 29c6d3b7bSStefan Roese * Copyright (C) 2014-2015 Stefan Roese <sr@denx.de> 3350b50eeSStefan Roese * 4350b50eeSStefan Roese * SPDX-License-Identifier: GPL-2.0+ 5350b50eeSStefan Roese */ 6350b50eeSStefan Roese 7350b50eeSStefan Roese #include <common.h> 84d991cb3SStefan Roese #include <ahci.h> 94d991cb3SStefan Roese #include <linux/mbus.h> 10350b50eeSStefan Roese #include <asm/io.h> 115730360eSStefan Roese #include <asm/pl310.h> 12350b50eeSStefan Roese #include <asm/arch/cpu.h> 13350b50eeSStefan Roese #include <asm/arch/soc.h> 147f1adcd7SStefan Roese #include <sdhci.h> 15350b50eeSStefan Roese 16350b50eeSStefan Roese #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) 17350b50eeSStefan Roese #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) 18350b50eeSStefan Roese 19350b50eeSStefan Roese static struct mbus_win windows[] = { 20350b50eeSStefan Roese /* SPI */ 218ed20d65SStefan Roese { MBUS_SPI_BASE, MBUS_SPI_SIZE, 228ed20d65SStefan Roese CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, 23350b50eeSStefan Roese 24350b50eeSStefan Roese /* NOR */ 258ed20d65SStefan Roese { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, 268ed20d65SStefan Roese CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM }, 27350b50eeSStefan Roese }; 28350b50eeSStefan Roese 2942cc034fSStefan Roese void lowlevel_init(void) 3042cc034fSStefan Roese { 3142cc034fSStefan Roese /* 3242cc034fSStefan Roese * Dummy implementation, we only need LOWLEVEL_INIT 3342cc034fSStefan Roese * on Armada to configure CP15 in start.S / cpu_init_cp15() 3442cc034fSStefan Roese */ 3542cc034fSStefan Roese } 3642cc034fSStefan Roese 37350b50eeSStefan Roese void reset_cpu(unsigned long ignored) 38350b50eeSStefan Roese { 39350b50eeSStefan Roese struct mvebu_system_registers *reg = 40350b50eeSStefan Roese (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE; 41350b50eeSStefan Roese 42350b50eeSStefan Roese writel(readl(®->rstoutn_mask) | 1, ®->rstoutn_mask); 43350b50eeSStefan Roese writel(readl(®->sys_soft_rst) | 1, ®->sys_soft_rst); 44350b50eeSStefan Roese while (1) 45350b50eeSStefan Roese ; 46350b50eeSStefan Roese } 47350b50eeSStefan Roese 489c6d3b7bSStefan Roese int mvebu_soc_family(void) 499c6d3b7bSStefan Roese { 509c6d3b7bSStefan Roese u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 519c6d3b7bSStefan Roese 52bf0db8b8SStefan Roese if ((devid == SOC_MV78260_ID) || (devid == SOC_MV78460_ID)) 539c6d3b7bSStefan Roese return MVEBU_SOC_AXP; 549c6d3b7bSStefan Roese 559c6d3b7bSStefan Roese if (devid == SOC_88F6810_ID || devid == SOC_88F6820_ID || 569c6d3b7bSStefan Roese devid == SOC_88F6828_ID) 579c6d3b7bSStefan Roese return MVEBU_SOC_A38X; 589c6d3b7bSStefan Roese 599c6d3b7bSStefan Roese return MVEBU_SOC_UNKNOWN; 609c6d3b7bSStefan Roese } 619c6d3b7bSStefan Roese 62350b50eeSStefan Roese #if defined(CONFIG_DISPLAY_CPUINFO) 63*d718bf2cSStefan Roese 64*d718bf2cSStefan Roese #if defined(CONFIG_ARMADA_38X) 65*d718bf2cSStefan Roese /* SAR values for Armada 38x */ 66*d718bf2cSStefan Roese #define CONFIG_SAR_REG (MVEBU_REGISTER(0x18600)) 67*d718bf2cSStefan Roese #define SAR_CPU_FREQ_OFFS 10 68*d718bf2cSStefan Roese #define SAR_CPU_FREQ_MASK (0x1f << SAR_CPU_FREQ_OFFS) 69*d718bf2cSStefan Roese 70*d718bf2cSStefan Roese struct sar_freq_modes sar_freq_tab[] = { 71*d718bf2cSStefan Roese { 0x0, 0x0, 666, 333, 333 }, 72*d718bf2cSStefan Roese { 0x2, 0x0, 800, 400, 400 }, 73*d718bf2cSStefan Roese { 0x4, 0x0, 1066, 533, 533 }, 74*d718bf2cSStefan Roese { 0x6, 0x0, 1200, 600, 600 }, 75*d718bf2cSStefan Roese { 0x8, 0x0, 1332, 666, 666 }, 76*d718bf2cSStefan Roese { 0xc, 0x0, 1600, 800, 800 }, 77*d718bf2cSStefan Roese { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ 78*d718bf2cSStefan Roese }; 79*d718bf2cSStefan Roese #else 80*d718bf2cSStefan Roese /* SAR values for Armada XP */ 81*d718bf2cSStefan Roese #define CONFIG_SAR_REG (MVEBU_REGISTER(0x18230)) 82*d718bf2cSStefan Roese #define CONFIG_SAR2_REG (MVEBU_REGISTER(0x18234)) 83*d718bf2cSStefan Roese #define SAR_CPU_FREQ_OFFS 21 84*d718bf2cSStefan Roese #define SAR_CPU_FREQ_MASK (0x7 << SAR_CPU_FREQ_OFFS) 85*d718bf2cSStefan Roese #define SAR_FFC_FREQ_OFFS 24 86*d718bf2cSStefan Roese #define SAR_FFC_FREQ_MASK (0xf << SAR_FFC_FREQ_OFFS) 87*d718bf2cSStefan Roese #define SAR2_CPU_FREQ_OFFS 20 88*d718bf2cSStefan Roese #define SAR2_CPU_FREQ_MASK (0x1 << SAR2_CPU_FREQ_OFFS) 89*d718bf2cSStefan Roese 90*d718bf2cSStefan Roese struct sar_freq_modes sar_freq_tab[] = { 91*d718bf2cSStefan Roese { 0xa, 0x5, 800, 400, 400 }, 92*d718bf2cSStefan Roese { 0x1, 0x5, 1066, 533, 533 }, 93*d718bf2cSStefan Roese { 0x2, 0x5, 1200, 600, 600 }, 94*d718bf2cSStefan Roese { 0x2, 0x9, 1200, 600, 400 }, 95*d718bf2cSStefan Roese { 0x3, 0x5, 1333, 667, 667 }, 96*d718bf2cSStefan Roese { 0x4, 0x5, 1500, 750, 750 }, 97*d718bf2cSStefan Roese { 0x4, 0x9, 1500, 750, 500 }, 98*d718bf2cSStefan Roese { 0xb, 0x9, 1600, 800, 533 }, 99*d718bf2cSStefan Roese { 0xb, 0xa, 1600, 800, 640 }, 100*d718bf2cSStefan Roese { 0xb, 0x5, 1600, 800, 800 }, 101*d718bf2cSStefan Roese { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ 102*d718bf2cSStefan Roese }; 103*d718bf2cSStefan Roese #endif 104*d718bf2cSStefan Roese 105*d718bf2cSStefan Roese void get_sar_freq(struct sar_freq_modes *sar_freq) 106*d718bf2cSStefan Roese { 107*d718bf2cSStefan Roese u32 val; 108*d718bf2cSStefan Roese u32 freq; 109*d718bf2cSStefan Roese int i; 110*d718bf2cSStefan Roese 111*d718bf2cSStefan Roese val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */ 112*d718bf2cSStefan Roese freq = (val & SAR_CPU_FREQ_MASK) >> SAR_CPU_FREQ_OFFS; 113*d718bf2cSStefan Roese #if !defined(CONFIG_ARMADA_38X) 114*d718bf2cSStefan Roese /* 115*d718bf2cSStefan Roese * Shift CPU0 clock frequency select bit from SAR2 register 116*d718bf2cSStefan Roese * into correct position 117*d718bf2cSStefan Roese */ 118*d718bf2cSStefan Roese freq |= ((readl(CONFIG_SAR2_REG) & SAR2_CPU_FREQ_MASK) 119*d718bf2cSStefan Roese >> SAR2_CPU_FREQ_OFFS) << 3; 120*d718bf2cSStefan Roese #endif 121*d718bf2cSStefan Roese for (i = 0; sar_freq_tab[i].val != 0xff; i++) { 122*d718bf2cSStefan Roese if (sar_freq_tab[i].val == freq) { 123*d718bf2cSStefan Roese #if defined(CONFIG_ARMADA_38X) 124*d718bf2cSStefan Roese *sar_freq = sar_freq_tab[i]; 125*d718bf2cSStefan Roese return; 126*d718bf2cSStefan Roese #else 127*d718bf2cSStefan Roese int k; 128*d718bf2cSStefan Roese u8 ffc; 129*d718bf2cSStefan Roese 130*d718bf2cSStefan Roese ffc = (val & SAR_FFC_FREQ_MASK) >> 131*d718bf2cSStefan Roese SAR_FFC_FREQ_OFFS; 132*d718bf2cSStefan Roese for (k = i; sar_freq_tab[k].ffc != 0xff; k++) { 133*d718bf2cSStefan Roese if (sar_freq_tab[k].ffc == ffc) { 134*d718bf2cSStefan Roese *sar_freq = sar_freq_tab[k]; 135*d718bf2cSStefan Roese return; 136*d718bf2cSStefan Roese } 137*d718bf2cSStefan Roese } 138*d718bf2cSStefan Roese i = k; 139*d718bf2cSStefan Roese #endif 140*d718bf2cSStefan Roese } 141*d718bf2cSStefan Roese } 142*d718bf2cSStefan Roese 143*d718bf2cSStefan Roese /* SAR value not found, return 0 for frequencies */ 144*d718bf2cSStefan Roese *sar_freq = sar_freq_tab[i - 1]; 145*d718bf2cSStefan Roese } 146*d718bf2cSStefan Roese 147350b50eeSStefan Roese int print_cpuinfo(void) 148350b50eeSStefan Roese { 149350b50eeSStefan Roese u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 150350b50eeSStefan Roese u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; 151*d718bf2cSStefan Roese struct sar_freq_modes sar_freq; 152350b50eeSStefan Roese 153350b50eeSStefan Roese puts("SoC: "); 154350b50eeSStefan Roese 155350b50eeSStefan Roese switch (devid) { 156bf0db8b8SStefan Roese case SOC_MV78260_ID: 157bf0db8b8SStefan Roese puts("MV78260-"); 158bf0db8b8SStefan Roese break; 159350b50eeSStefan Roese case SOC_MV78460_ID: 160350b50eeSStefan Roese puts("MV78460-"); 161350b50eeSStefan Roese break; 1629c6d3b7bSStefan Roese case SOC_88F6810_ID: 1639c6d3b7bSStefan Roese puts("MV88F6810-"); 1649c6d3b7bSStefan Roese break; 1659c6d3b7bSStefan Roese case SOC_88F6820_ID: 1669c6d3b7bSStefan Roese puts("MV88F6820-"); 1679c6d3b7bSStefan Roese break; 1689c6d3b7bSStefan Roese case SOC_88F6828_ID: 1699c6d3b7bSStefan Roese puts("MV88F6828-"); 1709c6d3b7bSStefan Roese break; 171350b50eeSStefan Roese default: 172350b50eeSStefan Roese puts("Unknown-"); 173350b50eeSStefan Roese break; 174350b50eeSStefan Roese } 175350b50eeSStefan Roese 1769c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 177350b50eeSStefan Roese switch (revid) { 178350b50eeSStefan Roese case 1: 179*d718bf2cSStefan Roese puts("A0"); 180350b50eeSStefan Roese break; 181350b50eeSStefan Roese case 2: 182*d718bf2cSStefan Roese puts("B0"); 183350b50eeSStefan Roese break; 184350b50eeSStefan Roese default: 185*d718bf2cSStefan Roese printf("?? (%x)", revid); 186350b50eeSStefan Roese break; 187350b50eeSStefan Roese } 1889c6d3b7bSStefan Roese } 1899c6d3b7bSStefan Roese 1909c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_A38X) { 1919c6d3b7bSStefan Roese switch (revid) { 1929c6d3b7bSStefan Roese case MV_88F68XX_Z1_ID: 193*d718bf2cSStefan Roese puts("Z1"); 1949c6d3b7bSStefan Roese break; 1959c6d3b7bSStefan Roese case MV_88F68XX_A0_ID: 196*d718bf2cSStefan Roese puts("A0"); 1979c6d3b7bSStefan Roese break; 1989c6d3b7bSStefan Roese default: 199*d718bf2cSStefan Roese printf("?? (%x)", revid); 2009c6d3b7bSStefan Roese break; 2019c6d3b7bSStefan Roese } 2029c6d3b7bSStefan Roese } 203350b50eeSStefan Roese 204*d718bf2cSStefan Roese get_sar_freq(&sar_freq); 205*d718bf2cSStefan Roese printf(" at %d MHz\n", sar_freq.p_clk); 206*d718bf2cSStefan Roese 207350b50eeSStefan Roese return 0; 208350b50eeSStefan Roese } 209350b50eeSStefan Roese #endif /* CONFIG_DISPLAY_CPUINFO */ 210350b50eeSStefan Roese 211350b50eeSStefan Roese /* 212350b50eeSStefan Roese * This function initialize Controller DRAM Fastpath windows. 213350b50eeSStefan Roese * It takes the CS size information from the 0x1500 scratch registers 214350b50eeSStefan Roese * and sets the correct windows sizes and base addresses accordingly. 215350b50eeSStefan Roese * 216350b50eeSStefan Roese * These values are set in the scratch registers by the Marvell 217350b50eeSStefan Roese * DDR3 training code, which is executed by the BootROM before the 218350b50eeSStefan Roese * main payload (U-Boot) is executed. This training code is currently 219350b50eeSStefan Roese * only available in the Marvell U-Boot version. It needs to be 220350b50eeSStefan Roese * ported to mainline U-Boot SPL at some point. 221350b50eeSStefan Roese */ 222350b50eeSStefan Roese static void update_sdram_window_sizes(void) 223350b50eeSStefan Roese { 224350b50eeSStefan Roese u64 base = 0; 225350b50eeSStefan Roese u32 size, temp; 226350b50eeSStefan Roese int i; 227350b50eeSStefan Roese 228350b50eeSStefan Roese for (i = 0; i < SDRAM_MAX_CS; i++) { 229350b50eeSStefan Roese size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK; 230350b50eeSStefan Roese if (size != 0) { 231350b50eeSStefan Roese size |= ~(SDRAM_ADDR_MASK); 232350b50eeSStefan Roese 233350b50eeSStefan Roese /* Set Base Address */ 234350b50eeSStefan Roese temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF); 235350b50eeSStefan Roese writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i)); 236350b50eeSStefan Roese 237350b50eeSStefan Roese /* 238350b50eeSStefan Roese * Check if out of max window size and resize 239350b50eeSStefan Roese * the window 240350b50eeSStefan Roese */ 241350b50eeSStefan Roese temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) & 242350b50eeSStefan Roese ~(SDRAM_ADDR_MASK)) | 1; 243350b50eeSStefan Roese temp |= (size & SDRAM_ADDR_MASK); 244350b50eeSStefan Roese writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)); 245350b50eeSStefan Roese 246350b50eeSStefan Roese base += ((u64)size + 1); 247350b50eeSStefan Roese } else { 248350b50eeSStefan Roese /* 249350b50eeSStefan Roese * Disable window if not used, otherwise this 250350b50eeSStefan Roese * leads to overlapping enabled windows with 251350b50eeSStefan Roese * pretty strange results 252350b50eeSStefan Roese */ 253350b50eeSStefan Roese clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1); 254350b50eeSStefan Roese } 255350b50eeSStefan Roese } 256350b50eeSStefan Roese } 257350b50eeSStefan Roese 2589f62b44eSStefan Roese void mmu_disable(void) 2599f62b44eSStefan Roese { 2609f62b44eSStefan Roese asm volatile( 2619f62b44eSStefan Roese "mrc p15, 0, r0, c1, c0, 0\n" 2629f62b44eSStefan Roese "bic r0, #1\n" 2639f62b44eSStefan Roese "mcr p15, 0, r0, c1, c0, 0\n"); 2649f62b44eSStefan Roese } 2659f62b44eSStefan Roese 266350b50eeSStefan Roese #ifdef CONFIG_ARCH_CPU_INIT 267e1b078e0SKevin Smith static void set_cbar(u32 addr) 268e1b078e0SKevin Smith { 269e1b078e0SKevin Smith asm("mcr p15, 4, %0, c15, c0" : : "r" (addr)); 270e1b078e0SKevin Smith } 271e1b078e0SKevin Smith 272dee40d26SStefan Roese #define MV_USB_PHY_BASE (MVEBU_AXP_USB_BASE + 0x800) 273dee40d26SStefan Roese #define MV_USB_PHY_PLL_REG(reg) (MV_USB_PHY_BASE | (((reg) & 0xF) << 2)) 274dee40d26SStefan Roese #define MV_USB_X3_BASE(addr) (MVEBU_AXP_USB_BASE | BIT(11) | \ 275dee40d26SStefan Roese (((addr) & 0xF) << 6)) 276dee40d26SStefan Roese #define MV_USB_X3_PHY_CHANNEL(dev, reg) (MV_USB_X3_BASE((dev) + 1) | \ 277dee40d26SStefan Roese (((reg) & 0xF) << 2)) 278dee40d26SStefan Roese 279dee40d26SStefan Roese static void setup_usb_phys(void) 280dee40d26SStefan Roese { 281dee40d26SStefan Roese int dev; 282dee40d26SStefan Roese 283dee40d26SStefan Roese /* 284dee40d26SStefan Roese * USB PLL init 285dee40d26SStefan Roese */ 286dee40d26SStefan Roese 287dee40d26SStefan Roese /* Setup PLL frequency */ 288dee40d26SStefan Roese /* USB REF frequency = 25 MHz */ 289dee40d26SStefan Roese clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605); 290dee40d26SStefan Roese 291dee40d26SStefan Roese /* Power up PLL and PHY channel */ 292ab8a4c6aSStefan Roese setbits_le32(MV_USB_PHY_PLL_REG(2), BIT(9)); 293dee40d26SStefan Roese 294dee40d26SStefan Roese /* Assert VCOCAL_START */ 295ab8a4c6aSStefan Roese setbits_le32(MV_USB_PHY_PLL_REG(1), BIT(21)); 296dee40d26SStefan Roese 297dee40d26SStefan Roese mdelay(1); 298dee40d26SStefan Roese 299dee40d26SStefan Roese /* 300dee40d26SStefan Roese * USB PHY init (change from defaults) specific for 40nm (78X30 78X60) 301dee40d26SStefan Roese */ 302dee40d26SStefan Roese 303dee40d26SStefan Roese for (dev = 0; dev < 3; dev++) { 304ab8a4c6aSStefan Roese setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), BIT(15)); 305dee40d26SStefan Roese 306dee40d26SStefan Roese /* Assert REG_RCAL_START in channel REG 1 */ 307ab8a4c6aSStefan Roese setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 308dee40d26SStefan Roese udelay(40); 309ab8a4c6aSStefan Roese clrbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 310dee40d26SStefan Roese } 311dee40d26SStefan Roese } 312e1b078e0SKevin Smith 313f4e6ec7dSStefan Roese /* 314f4e6ec7dSStefan Roese * This function is not called from the SPL U-Boot version 315f4e6ec7dSStefan Roese */ 316350b50eeSStefan Roese int arch_cpu_init(void) 317350b50eeSStefan Roese { 31842cc034fSStefan Roese struct pl310_regs *const pl310 = 31942cc034fSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 32042cc034fSStefan Roese 3219f62b44eSStefan Roese /* 3229f62b44eSStefan Roese * Only with disabled MMU its possible to switch the base 3239f62b44eSStefan Roese * register address on Armada 38x. Without this the SDRAM 3249f62b44eSStefan Roese * located at >= 0x4000.0000 is also not accessible, as its 3259f62b44eSStefan Roese * still locked to cache. 3269f62b44eSStefan Roese */ 3279f62b44eSStefan Roese mmu_disable(); 3289f62b44eSStefan Roese 329350b50eeSStefan Roese /* Linux expects the internal registers to be at 0xf1000000 */ 330350b50eeSStefan Roese writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); 331e1b078e0SKevin Smith set_cbar(SOC_REGS_PHY_BASE + 0xC000); 332350b50eeSStefan Roese 333cefd7642SStefan Roese /* 334cefd7642SStefan Roese * From this stage on, the SoC detection is working. As we have 335cefd7642SStefan Roese * configured the internal register base to the value used 336cefd7642SStefan Roese * in the macros / defines in the U-Boot header (soc.h). 337cefd7642SStefan Roese */ 338cefd7642SStefan Roese 339c86d53fdSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_A38X) { 340cefd7642SStefan Roese /* 341cefd7642SStefan Roese * To fully release / unlock this area from cache, we need 342cefd7642SStefan Roese * to flush all caches and disable the L2 cache. 343cefd7642SStefan Roese */ 344cefd7642SStefan Roese icache_disable(); 345cefd7642SStefan Roese dcache_disable(); 346cefd7642SStefan Roese clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 347c86d53fdSStefan Roese } 348cefd7642SStefan Roese 349350b50eeSStefan Roese /* 350350b50eeSStefan Roese * We need to call mvebu_mbus_probe() before calling 351350b50eeSStefan Roese * update_sdram_window_sizes() as it disables all previously 352350b50eeSStefan Roese * configured mbus windows and then configures them as 353350b50eeSStefan Roese * required for U-Boot. Calling update_sdram_window_sizes() 354350b50eeSStefan Roese * without this configuration will not work, as the internal 355350b50eeSStefan Roese * registers can't be accessed reliably because of potenial 356350b50eeSStefan Roese * double mapping. 357350b50eeSStefan Roese * After updating the SDRAM access windows we need to call 358350b50eeSStefan Roese * mvebu_mbus_probe() again, as this now correctly configures 359350b50eeSStefan Roese * the SDRAM areas that are later used by the MVEBU drivers 360350b50eeSStefan Roese * (e.g. USB, NETA). 361350b50eeSStefan Roese */ 362350b50eeSStefan Roese 363350b50eeSStefan Roese /* 364350b50eeSStefan Roese * First disable all windows 365350b50eeSStefan Roese */ 366350b50eeSStefan Roese mvebu_mbus_probe(NULL, 0); 367350b50eeSStefan Roese 3689c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 369350b50eeSStefan Roese /* 370350b50eeSStefan Roese * Now the SDRAM access windows can be reconfigured using 371350b50eeSStefan Roese * the information in the SDRAM scratch pad registers 372350b50eeSStefan Roese */ 373350b50eeSStefan Roese update_sdram_window_sizes(); 3749c6d3b7bSStefan Roese } 375350b50eeSStefan Roese 376350b50eeSStefan Roese /* 377350b50eeSStefan Roese * Finally the mbus windows can be configured with the 378350b50eeSStefan Roese * updated SDRAM sizes 379350b50eeSStefan Roese */ 380350b50eeSStefan Roese mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); 381350b50eeSStefan Roese 3822a0b7dc3SStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 3832a0b7dc3SStefan Roese /* Enable GBE0, GBE1, LCD and NFC PUP */ 3842a0b7dc3SStefan Roese clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0, 3852a0b7dc3SStefan Roese GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN | 3862a0b7dc3SStefan Roese NAND_PUP_EN | SPI_PUP_EN); 387dee40d26SStefan Roese 388dee40d26SStefan Roese /* Configure USB PLL and PHYs on AXP */ 389dee40d26SStefan Roese setup_usb_phys(); 3902a0b7dc3SStefan Roese } 3912a0b7dc3SStefan Roese 3922a0b7dc3SStefan Roese /* Enable NAND and NAND arbiter */ 3932a0b7dc3SStefan Roese clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN); 3942a0b7dc3SStefan Roese 395501c098aSStefan Roese /* Disable MBUS error propagation */ 396501c098aSStefan Roese clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0); 397501c098aSStefan Roese 398350b50eeSStefan Roese return 0; 399350b50eeSStefan Roese } 400350b50eeSStefan Roese #endif /* CONFIG_ARCH_CPU_INIT */ 401350b50eeSStefan Roese 4022a0b7dc3SStefan Roese u32 mvebu_get_nand_clock(void) 4032a0b7dc3SStefan Roese { 4042a0b7dc3SStefan Roese return CONFIG_SYS_MVEBU_PLL_CLOCK / 4052a0b7dc3SStefan Roese ((readl(MVEBU_CORE_DIV_CLK_CTRL(1)) & 4062a0b7dc3SStefan Roese NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS); 4072a0b7dc3SStefan Roese } 4082a0b7dc3SStefan Roese 409350b50eeSStefan Roese /* 410350b50eeSStefan Roese * SOC specific misc init 411350b50eeSStefan Roese */ 412350b50eeSStefan Roese #if defined(CONFIG_ARCH_MISC_INIT) 413350b50eeSStefan Roese int arch_misc_init(void) 414350b50eeSStefan Roese { 415350b50eeSStefan Roese /* Nothing yet, perhaps we need something here later */ 416350b50eeSStefan Roese return 0; 417350b50eeSStefan Roese } 418350b50eeSStefan Roese #endif /* CONFIG_ARCH_MISC_INIT */ 419350b50eeSStefan Roese 4207f1adcd7SStefan Roese #ifdef CONFIG_MV_SDHCI 4217f1adcd7SStefan Roese int board_mmc_init(bd_t *bis) 4227f1adcd7SStefan Roese { 4237f1adcd7SStefan Roese mv_sdh_init(MVEBU_SDIO_BASE, 0, 0, 4247f1adcd7SStefan Roese SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD); 4257f1adcd7SStefan Roese 4267f1adcd7SStefan Roese return 0; 4277f1adcd7SStefan Roese } 4287f1adcd7SStefan Roese #endif 4297f1adcd7SStefan Roese 4304d991cb3SStefan Roese #ifdef CONFIG_SCSI_AHCI_PLAT 4314d991cb3SStefan Roese #define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 4324d991cb3SStefan Roese #define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 4334d991cb3SStefan Roese 4344d991cb3SStefan Roese #define AHCI_WINDOW_CTRL(win) (0x60 + ((win) << 4)) 4354d991cb3SStefan Roese #define AHCI_WINDOW_BASE(win) (0x64 + ((win) << 4)) 4364d991cb3SStefan Roese #define AHCI_WINDOW_SIZE(win) (0x68 + ((win) << 4)) 4374d991cb3SStefan Roese 4384d991cb3SStefan Roese static void ahci_mvebu_mbus_config(void __iomem *base) 4394d991cb3SStefan Roese { 4404d991cb3SStefan Roese const struct mbus_dram_target_info *dram; 4414d991cb3SStefan Roese int i; 4424d991cb3SStefan Roese 4434d991cb3SStefan Roese dram = mvebu_mbus_dram_info(); 4444d991cb3SStefan Roese 4454d991cb3SStefan Roese for (i = 0; i < 4; i++) { 4464d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_CTRL(i)); 4474d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_BASE(i)); 4484d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_SIZE(i)); 4494d991cb3SStefan Roese } 4504d991cb3SStefan Roese 4514d991cb3SStefan Roese for (i = 0; i < dram->num_cs; i++) { 4524d991cb3SStefan Roese const struct mbus_dram_window *cs = dram->cs + i; 4534d991cb3SStefan Roese 4544d991cb3SStefan Roese writel((cs->mbus_attr << 8) | 4554d991cb3SStefan Roese (dram->mbus_dram_target_id << 4) | 1, 4564d991cb3SStefan Roese base + AHCI_WINDOW_CTRL(i)); 4574d991cb3SStefan Roese writel(cs->base >> 16, base + AHCI_WINDOW_BASE(i)); 4584d991cb3SStefan Roese writel(((cs->size - 1) & 0xffff0000), 4594d991cb3SStefan Roese base + AHCI_WINDOW_SIZE(i)); 4604d991cb3SStefan Roese } 4614d991cb3SStefan Roese } 4624d991cb3SStefan Roese 4634d991cb3SStefan Roese static void ahci_mvebu_regret_option(void __iomem *base) 4644d991cb3SStefan Roese { 4654d991cb3SStefan Roese /* 4664d991cb3SStefan Roese * Enable the regret bit to allow the SATA unit to regret a 4674d991cb3SStefan Roese * request that didn't receive an acknowlegde and avoid a 4684d991cb3SStefan Roese * deadlock 4694d991cb3SStefan Roese */ 4704d991cb3SStefan Roese writel(0x4, base + AHCI_VENDOR_SPECIFIC_0_ADDR); 4714d991cb3SStefan Roese writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA); 4724d991cb3SStefan Roese } 4734d991cb3SStefan Roese 4744d991cb3SStefan Roese void scsi_init(void) 4754d991cb3SStefan Roese { 4764d991cb3SStefan Roese printf("MVEBU SATA INIT\n"); 4774d991cb3SStefan Roese ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE); 4784d991cb3SStefan Roese ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE); 4794d991cb3SStefan Roese ahci_init((void __iomem *)MVEBU_SATA0_BASE); 4804d991cb3SStefan Roese } 4814d991cb3SStefan Roese #endif 4824d991cb3SStefan Roese 483350b50eeSStefan Roese void enable_caches(void) 484350b50eeSStefan Roese { 48560b75324SStefan Roese /* Avoid problem with e.g. neta ethernet driver */ 48660b75324SStefan Roese invalidate_dcache_all(); 48760b75324SStefan Roese 488350b50eeSStefan Roese /* Enable D-cache. I-cache is already enabled in start.S */ 489350b50eeSStefan Roese dcache_enable(); 490350b50eeSStefan Roese } 4913e5ce7ceSStefan Roese 4923e5ce7ceSStefan Roese void v7_outer_cache_enable(void) 4933e5ce7ceSStefan Roese { 494c86d53fdSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 4953e5ce7ceSStefan Roese struct pl310_regs *const pl310 = 4963e5ce7ceSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 497c86d53fdSStefan Roese u32 u; 4983e5ce7ceSStefan Roese 4993e5ce7ceSStefan Roese /* The L2 cache is already disabled at this point */ 5003e5ce7ceSStefan Roese 5013e5ce7ceSStefan Roese /* 5023e5ce7ceSStefan Roese * For Aurora cache in no outer mode, enable via the CP15 5033e5ce7ceSStefan Roese * coprocessor broadcasting of cache commands to L2. 5043e5ce7ceSStefan Roese */ 5053e5ce7ceSStefan Roese asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u)); 5063e5ce7ceSStefan Roese u |= BIT(8); /* Set the FW bit */ 5073e5ce7ceSStefan Roese asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u)); 5083e5ce7ceSStefan Roese 5093e5ce7ceSStefan Roese isb(); 5103e5ce7ceSStefan Roese 5113e5ce7ceSStefan Roese /* Enable the L2 cache */ 5123e5ce7ceSStefan Roese setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 5133e5ce7ceSStefan Roese } 5143e5ce7ceSStefan Roese } 515f0e8173aSStefan Roese 516f0e8173aSStefan Roese void v7_outer_cache_disable(void) 517f0e8173aSStefan Roese { 518f0e8173aSStefan Roese struct pl310_regs *const pl310 = 519f0e8173aSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 520f0e8173aSStefan Roese 521f0e8173aSStefan Roese clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 522f0e8173aSStefan Roese } 523