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> 8350b50eeSStefan Roese #include <netdev.h> 94d991cb3SStefan Roese #include <ahci.h> 104d991cb3SStefan Roese #include <linux/mbus.h> 11350b50eeSStefan Roese #include <asm/io.h> 125730360eSStefan Roese #include <asm/pl310.h> 13350b50eeSStefan Roese #include <asm/arch/cpu.h> 14350b50eeSStefan Roese #include <asm/arch/soc.h> 157f1adcd7SStefan Roese #include <sdhci.h> 16350b50eeSStefan Roese 17350b50eeSStefan Roese #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) 18350b50eeSStefan Roese #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) 19350b50eeSStefan Roese 20350b50eeSStefan Roese static struct mbus_win windows[] = { 21350b50eeSStefan Roese /* SPI */ 228ed20d65SStefan Roese { MBUS_SPI_BASE, MBUS_SPI_SIZE, 238ed20d65SStefan Roese CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, 24350b50eeSStefan Roese 25350b50eeSStefan Roese /* NOR */ 268ed20d65SStefan Roese { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, 278ed20d65SStefan Roese CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM }, 28350b50eeSStefan Roese }; 29350b50eeSStefan Roese 3042cc034fSStefan Roese void lowlevel_init(void) 3142cc034fSStefan Roese { 3242cc034fSStefan Roese /* 3342cc034fSStefan Roese * Dummy implementation, we only need LOWLEVEL_INIT 3442cc034fSStefan Roese * on Armada to configure CP15 in start.S / cpu_init_cp15() 3542cc034fSStefan Roese */ 3642cc034fSStefan Roese } 3742cc034fSStefan Roese 38350b50eeSStefan Roese void reset_cpu(unsigned long ignored) 39350b50eeSStefan Roese { 40350b50eeSStefan Roese struct mvebu_system_registers *reg = 41350b50eeSStefan Roese (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE; 42350b50eeSStefan Roese 43350b50eeSStefan Roese writel(readl(®->rstoutn_mask) | 1, ®->rstoutn_mask); 44350b50eeSStefan Roese writel(readl(®->sys_soft_rst) | 1, ®->sys_soft_rst); 45350b50eeSStefan Roese while (1) 46350b50eeSStefan Roese ; 47350b50eeSStefan Roese } 48350b50eeSStefan Roese 499c6d3b7bSStefan Roese int mvebu_soc_family(void) 509c6d3b7bSStefan Roese { 519c6d3b7bSStefan Roese u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 529c6d3b7bSStefan Roese 53*bf0db8b8SStefan Roese if ((devid == SOC_MV78260_ID) || (devid == SOC_MV78460_ID)) 549c6d3b7bSStefan Roese return MVEBU_SOC_AXP; 559c6d3b7bSStefan Roese 569c6d3b7bSStefan Roese if (devid == SOC_88F6810_ID || devid == SOC_88F6820_ID || 579c6d3b7bSStefan Roese devid == SOC_88F6828_ID) 589c6d3b7bSStefan Roese return MVEBU_SOC_A38X; 599c6d3b7bSStefan Roese 609c6d3b7bSStefan Roese return MVEBU_SOC_UNKNOWN; 619c6d3b7bSStefan Roese } 629c6d3b7bSStefan Roese 63350b50eeSStefan Roese #if defined(CONFIG_DISPLAY_CPUINFO) 64350b50eeSStefan Roese int print_cpuinfo(void) 65350b50eeSStefan Roese { 66350b50eeSStefan Roese u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 67350b50eeSStefan Roese u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; 68350b50eeSStefan Roese 69350b50eeSStefan Roese puts("SoC: "); 70350b50eeSStefan Roese 71350b50eeSStefan Roese switch (devid) { 72*bf0db8b8SStefan Roese case SOC_MV78260_ID: 73*bf0db8b8SStefan Roese puts("MV78260-"); 74*bf0db8b8SStefan Roese break; 75350b50eeSStefan Roese case SOC_MV78460_ID: 76350b50eeSStefan Roese puts("MV78460-"); 77350b50eeSStefan Roese break; 789c6d3b7bSStefan Roese case SOC_88F6810_ID: 799c6d3b7bSStefan Roese puts("MV88F6810-"); 809c6d3b7bSStefan Roese break; 819c6d3b7bSStefan Roese case SOC_88F6820_ID: 829c6d3b7bSStefan Roese puts("MV88F6820-"); 839c6d3b7bSStefan Roese break; 849c6d3b7bSStefan Roese case SOC_88F6828_ID: 859c6d3b7bSStefan Roese puts("MV88F6828-"); 869c6d3b7bSStefan Roese break; 87350b50eeSStefan Roese default: 88350b50eeSStefan Roese puts("Unknown-"); 89350b50eeSStefan Roese break; 90350b50eeSStefan Roese } 91350b50eeSStefan Roese 929c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 93350b50eeSStefan Roese switch (revid) { 94350b50eeSStefan Roese case 1: 95350b50eeSStefan Roese puts("A0\n"); 96350b50eeSStefan Roese break; 97350b50eeSStefan Roese case 2: 98350b50eeSStefan Roese puts("B0\n"); 99350b50eeSStefan Roese break; 100350b50eeSStefan Roese default: 1019c6d3b7bSStefan Roese printf("?? (%x)\n", revid); 102350b50eeSStefan Roese break; 103350b50eeSStefan Roese } 1049c6d3b7bSStefan Roese } 1059c6d3b7bSStefan Roese 1069c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_A38X) { 1079c6d3b7bSStefan Roese switch (revid) { 1089c6d3b7bSStefan Roese case MV_88F68XX_Z1_ID: 1099c6d3b7bSStefan Roese puts("Z1\n"); 1109c6d3b7bSStefan Roese break; 1119c6d3b7bSStefan Roese case MV_88F68XX_A0_ID: 1129c6d3b7bSStefan Roese puts("A0\n"); 1139c6d3b7bSStefan Roese break; 1149c6d3b7bSStefan Roese default: 1159c6d3b7bSStefan Roese printf("?? (%x)\n", revid); 1169c6d3b7bSStefan Roese break; 1179c6d3b7bSStefan Roese } 1189c6d3b7bSStefan Roese } 119350b50eeSStefan Roese 120350b50eeSStefan Roese return 0; 121350b50eeSStefan Roese } 122350b50eeSStefan Roese #endif /* CONFIG_DISPLAY_CPUINFO */ 123350b50eeSStefan Roese 124350b50eeSStefan Roese /* 125350b50eeSStefan Roese * This function initialize Controller DRAM Fastpath windows. 126350b50eeSStefan Roese * It takes the CS size information from the 0x1500 scratch registers 127350b50eeSStefan Roese * and sets the correct windows sizes and base addresses accordingly. 128350b50eeSStefan Roese * 129350b50eeSStefan Roese * These values are set in the scratch registers by the Marvell 130350b50eeSStefan Roese * DDR3 training code, which is executed by the BootROM before the 131350b50eeSStefan Roese * main payload (U-Boot) is executed. This training code is currently 132350b50eeSStefan Roese * only available in the Marvell U-Boot version. It needs to be 133350b50eeSStefan Roese * ported to mainline U-Boot SPL at some point. 134350b50eeSStefan Roese */ 135350b50eeSStefan Roese static void update_sdram_window_sizes(void) 136350b50eeSStefan Roese { 137350b50eeSStefan Roese u64 base = 0; 138350b50eeSStefan Roese u32 size, temp; 139350b50eeSStefan Roese int i; 140350b50eeSStefan Roese 141350b50eeSStefan Roese for (i = 0; i < SDRAM_MAX_CS; i++) { 142350b50eeSStefan Roese size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK; 143350b50eeSStefan Roese if (size != 0) { 144350b50eeSStefan Roese size |= ~(SDRAM_ADDR_MASK); 145350b50eeSStefan Roese 146350b50eeSStefan Roese /* Set Base Address */ 147350b50eeSStefan Roese temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF); 148350b50eeSStefan Roese writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i)); 149350b50eeSStefan Roese 150350b50eeSStefan Roese /* 151350b50eeSStefan Roese * Check if out of max window size and resize 152350b50eeSStefan Roese * the window 153350b50eeSStefan Roese */ 154350b50eeSStefan Roese temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) & 155350b50eeSStefan Roese ~(SDRAM_ADDR_MASK)) | 1; 156350b50eeSStefan Roese temp |= (size & SDRAM_ADDR_MASK); 157350b50eeSStefan Roese writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)); 158350b50eeSStefan Roese 159350b50eeSStefan Roese base += ((u64)size + 1); 160350b50eeSStefan Roese } else { 161350b50eeSStefan Roese /* 162350b50eeSStefan Roese * Disable window if not used, otherwise this 163350b50eeSStefan Roese * leads to overlapping enabled windows with 164350b50eeSStefan Roese * pretty strange results 165350b50eeSStefan Roese */ 166350b50eeSStefan Roese clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1); 167350b50eeSStefan Roese } 168350b50eeSStefan Roese } 169350b50eeSStefan Roese } 170350b50eeSStefan Roese 1719f62b44eSStefan Roese void mmu_disable(void) 1729f62b44eSStefan Roese { 1739f62b44eSStefan Roese asm volatile( 1749f62b44eSStefan Roese "mrc p15, 0, r0, c1, c0, 0\n" 1759f62b44eSStefan Roese "bic r0, #1\n" 1769f62b44eSStefan Roese "mcr p15, 0, r0, c1, c0, 0\n"); 1779f62b44eSStefan Roese } 1789f62b44eSStefan Roese 179350b50eeSStefan Roese #ifdef CONFIG_ARCH_CPU_INIT 180e1b078e0SKevin Smith static void set_cbar(u32 addr) 181e1b078e0SKevin Smith { 182e1b078e0SKevin Smith asm("mcr p15, 4, %0, c15, c0" : : "r" (addr)); 183e1b078e0SKevin Smith } 184e1b078e0SKevin Smith 185dee40d26SStefan Roese #define MV_USB_PHY_BASE (MVEBU_AXP_USB_BASE + 0x800) 186dee40d26SStefan Roese #define MV_USB_PHY_PLL_REG(reg) (MV_USB_PHY_BASE | (((reg) & 0xF) << 2)) 187dee40d26SStefan Roese #define MV_USB_X3_BASE(addr) (MVEBU_AXP_USB_BASE | BIT(11) | \ 188dee40d26SStefan Roese (((addr) & 0xF) << 6)) 189dee40d26SStefan Roese #define MV_USB_X3_PHY_CHANNEL(dev, reg) (MV_USB_X3_BASE((dev) + 1) | \ 190dee40d26SStefan Roese (((reg) & 0xF) << 2)) 191dee40d26SStefan Roese 192dee40d26SStefan Roese static void setup_usb_phys(void) 193dee40d26SStefan Roese { 194dee40d26SStefan Roese int dev; 195dee40d26SStefan Roese 196dee40d26SStefan Roese /* 197dee40d26SStefan Roese * USB PLL init 198dee40d26SStefan Roese */ 199dee40d26SStefan Roese 200dee40d26SStefan Roese /* Setup PLL frequency */ 201dee40d26SStefan Roese /* USB REF frequency = 25 MHz */ 202dee40d26SStefan Roese clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605); 203dee40d26SStefan Roese 204dee40d26SStefan Roese /* Power up PLL and PHY channel */ 205ab8a4c6aSStefan Roese setbits_le32(MV_USB_PHY_PLL_REG(2), BIT(9)); 206dee40d26SStefan Roese 207dee40d26SStefan Roese /* Assert VCOCAL_START */ 208ab8a4c6aSStefan Roese setbits_le32(MV_USB_PHY_PLL_REG(1), BIT(21)); 209dee40d26SStefan Roese 210dee40d26SStefan Roese mdelay(1); 211dee40d26SStefan Roese 212dee40d26SStefan Roese /* 213dee40d26SStefan Roese * USB PHY init (change from defaults) specific for 40nm (78X30 78X60) 214dee40d26SStefan Roese */ 215dee40d26SStefan Roese 216dee40d26SStefan Roese for (dev = 0; dev < 3; dev++) { 217ab8a4c6aSStefan Roese setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), BIT(15)); 218dee40d26SStefan Roese 219dee40d26SStefan Roese /* Assert REG_RCAL_START in channel REG 1 */ 220ab8a4c6aSStefan Roese setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 221dee40d26SStefan Roese udelay(40); 222ab8a4c6aSStefan Roese clrbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 223dee40d26SStefan Roese } 224dee40d26SStefan Roese } 225e1b078e0SKevin Smith 226f4e6ec7dSStefan Roese /* 227f4e6ec7dSStefan Roese * This function is not called from the SPL U-Boot version 228f4e6ec7dSStefan Roese */ 229350b50eeSStefan Roese int arch_cpu_init(void) 230350b50eeSStefan Roese { 23142cc034fSStefan Roese struct pl310_regs *const pl310 = 23242cc034fSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 23342cc034fSStefan Roese 2349f62b44eSStefan Roese /* 2359f62b44eSStefan Roese * Only with disabled MMU its possible to switch the base 2369f62b44eSStefan Roese * register address on Armada 38x. Without this the SDRAM 2379f62b44eSStefan Roese * located at >= 0x4000.0000 is also not accessible, as its 2389f62b44eSStefan Roese * still locked to cache. 2399f62b44eSStefan Roese */ 2409f62b44eSStefan Roese mmu_disable(); 2419f62b44eSStefan Roese 242350b50eeSStefan Roese /* Linux expects the internal registers to be at 0xf1000000 */ 243350b50eeSStefan Roese writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); 244e1b078e0SKevin Smith set_cbar(SOC_REGS_PHY_BASE + 0xC000); 245350b50eeSStefan Roese 246cefd7642SStefan Roese /* 247cefd7642SStefan Roese * From this stage on, the SoC detection is working. As we have 248cefd7642SStefan Roese * configured the internal register base to the value used 249cefd7642SStefan Roese * in the macros / defines in the U-Boot header (soc.h). 250cefd7642SStefan Roese */ 251cefd7642SStefan Roese 252c86d53fdSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_A38X) { 253cefd7642SStefan Roese /* 254cefd7642SStefan Roese * To fully release / unlock this area from cache, we need 255cefd7642SStefan Roese * to flush all caches and disable the L2 cache. 256cefd7642SStefan Roese */ 257cefd7642SStefan Roese icache_disable(); 258cefd7642SStefan Roese dcache_disable(); 259cefd7642SStefan Roese clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 260c86d53fdSStefan Roese } 261cefd7642SStefan Roese 262350b50eeSStefan Roese /* 263350b50eeSStefan Roese * We need to call mvebu_mbus_probe() before calling 264350b50eeSStefan Roese * update_sdram_window_sizes() as it disables all previously 265350b50eeSStefan Roese * configured mbus windows and then configures them as 266350b50eeSStefan Roese * required for U-Boot. Calling update_sdram_window_sizes() 267350b50eeSStefan Roese * without this configuration will not work, as the internal 268350b50eeSStefan Roese * registers can't be accessed reliably because of potenial 269350b50eeSStefan Roese * double mapping. 270350b50eeSStefan Roese * After updating the SDRAM access windows we need to call 271350b50eeSStefan Roese * mvebu_mbus_probe() again, as this now correctly configures 272350b50eeSStefan Roese * the SDRAM areas that are later used by the MVEBU drivers 273350b50eeSStefan Roese * (e.g. USB, NETA). 274350b50eeSStefan Roese */ 275350b50eeSStefan Roese 276350b50eeSStefan Roese /* 277350b50eeSStefan Roese * First disable all windows 278350b50eeSStefan Roese */ 279350b50eeSStefan Roese mvebu_mbus_probe(NULL, 0); 280350b50eeSStefan Roese 2819c6d3b7bSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 282350b50eeSStefan Roese /* 283350b50eeSStefan Roese * Now the SDRAM access windows can be reconfigured using 284350b50eeSStefan Roese * the information in the SDRAM scratch pad registers 285350b50eeSStefan Roese */ 286350b50eeSStefan Roese update_sdram_window_sizes(); 2879c6d3b7bSStefan Roese } 288350b50eeSStefan Roese 289350b50eeSStefan Roese /* 290350b50eeSStefan Roese * Finally the mbus windows can be configured with the 291350b50eeSStefan Roese * updated SDRAM sizes 292350b50eeSStefan Roese */ 293350b50eeSStefan Roese mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); 294350b50eeSStefan Roese 2952a0b7dc3SStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 2962a0b7dc3SStefan Roese /* Enable GBE0, GBE1, LCD and NFC PUP */ 2972a0b7dc3SStefan Roese clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0, 2982a0b7dc3SStefan Roese GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN | 2992a0b7dc3SStefan Roese NAND_PUP_EN | SPI_PUP_EN); 300dee40d26SStefan Roese 301dee40d26SStefan Roese /* Configure USB PLL and PHYs on AXP */ 302dee40d26SStefan Roese setup_usb_phys(); 3032a0b7dc3SStefan Roese } 3042a0b7dc3SStefan Roese 3052a0b7dc3SStefan Roese /* Enable NAND and NAND arbiter */ 3062a0b7dc3SStefan Roese clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN); 3072a0b7dc3SStefan Roese 308501c098aSStefan Roese /* Disable MBUS error propagation */ 309501c098aSStefan Roese clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0); 310501c098aSStefan Roese 311350b50eeSStefan Roese return 0; 312350b50eeSStefan Roese } 313350b50eeSStefan Roese #endif /* CONFIG_ARCH_CPU_INIT */ 314350b50eeSStefan Roese 3152a0b7dc3SStefan Roese u32 mvebu_get_nand_clock(void) 3162a0b7dc3SStefan Roese { 3172a0b7dc3SStefan Roese return CONFIG_SYS_MVEBU_PLL_CLOCK / 3182a0b7dc3SStefan Roese ((readl(MVEBU_CORE_DIV_CLK_CTRL(1)) & 3192a0b7dc3SStefan Roese NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS); 3202a0b7dc3SStefan Roese } 3212a0b7dc3SStefan Roese 322350b50eeSStefan Roese /* 323350b50eeSStefan Roese * SOC specific misc init 324350b50eeSStefan Roese */ 325350b50eeSStefan Roese #if defined(CONFIG_ARCH_MISC_INIT) 326350b50eeSStefan Roese int arch_misc_init(void) 327350b50eeSStefan Roese { 328350b50eeSStefan Roese /* Nothing yet, perhaps we need something here later */ 329350b50eeSStefan Roese return 0; 330350b50eeSStefan Roese } 331350b50eeSStefan Roese #endif /* CONFIG_ARCH_MISC_INIT */ 332350b50eeSStefan Roese 3337f1adcd7SStefan Roese #ifdef CONFIG_MV_SDHCI 3347f1adcd7SStefan Roese int board_mmc_init(bd_t *bis) 3357f1adcd7SStefan Roese { 3367f1adcd7SStefan Roese mv_sdh_init(MVEBU_SDIO_BASE, 0, 0, 3377f1adcd7SStefan Roese SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD); 3387f1adcd7SStefan Roese 3397f1adcd7SStefan Roese return 0; 3407f1adcd7SStefan Roese } 3417f1adcd7SStefan Roese #endif 3427f1adcd7SStefan Roese 3434d991cb3SStefan Roese #ifdef CONFIG_SCSI_AHCI_PLAT 3444d991cb3SStefan Roese #define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 3454d991cb3SStefan Roese #define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 3464d991cb3SStefan Roese 3474d991cb3SStefan Roese #define AHCI_WINDOW_CTRL(win) (0x60 + ((win) << 4)) 3484d991cb3SStefan Roese #define AHCI_WINDOW_BASE(win) (0x64 + ((win) << 4)) 3494d991cb3SStefan Roese #define AHCI_WINDOW_SIZE(win) (0x68 + ((win) << 4)) 3504d991cb3SStefan Roese 3514d991cb3SStefan Roese static void ahci_mvebu_mbus_config(void __iomem *base) 3524d991cb3SStefan Roese { 3534d991cb3SStefan Roese const struct mbus_dram_target_info *dram; 3544d991cb3SStefan Roese int i; 3554d991cb3SStefan Roese 3564d991cb3SStefan Roese dram = mvebu_mbus_dram_info(); 3574d991cb3SStefan Roese 3584d991cb3SStefan Roese for (i = 0; i < 4; i++) { 3594d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_CTRL(i)); 3604d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_BASE(i)); 3614d991cb3SStefan Roese writel(0, base + AHCI_WINDOW_SIZE(i)); 3624d991cb3SStefan Roese } 3634d991cb3SStefan Roese 3644d991cb3SStefan Roese for (i = 0; i < dram->num_cs; i++) { 3654d991cb3SStefan Roese const struct mbus_dram_window *cs = dram->cs + i; 3664d991cb3SStefan Roese 3674d991cb3SStefan Roese writel((cs->mbus_attr << 8) | 3684d991cb3SStefan Roese (dram->mbus_dram_target_id << 4) | 1, 3694d991cb3SStefan Roese base + AHCI_WINDOW_CTRL(i)); 3704d991cb3SStefan Roese writel(cs->base >> 16, base + AHCI_WINDOW_BASE(i)); 3714d991cb3SStefan Roese writel(((cs->size - 1) & 0xffff0000), 3724d991cb3SStefan Roese base + AHCI_WINDOW_SIZE(i)); 3734d991cb3SStefan Roese } 3744d991cb3SStefan Roese } 3754d991cb3SStefan Roese 3764d991cb3SStefan Roese static void ahci_mvebu_regret_option(void __iomem *base) 3774d991cb3SStefan Roese { 3784d991cb3SStefan Roese /* 3794d991cb3SStefan Roese * Enable the regret bit to allow the SATA unit to regret a 3804d991cb3SStefan Roese * request that didn't receive an acknowlegde and avoid a 3814d991cb3SStefan Roese * deadlock 3824d991cb3SStefan Roese */ 3834d991cb3SStefan Roese writel(0x4, base + AHCI_VENDOR_SPECIFIC_0_ADDR); 3844d991cb3SStefan Roese writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA); 3854d991cb3SStefan Roese } 3864d991cb3SStefan Roese 3874d991cb3SStefan Roese void scsi_init(void) 3884d991cb3SStefan Roese { 3894d991cb3SStefan Roese printf("MVEBU SATA INIT\n"); 3904d991cb3SStefan Roese ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE); 3914d991cb3SStefan Roese ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE); 3924d991cb3SStefan Roese ahci_init((void __iomem *)MVEBU_SATA0_BASE); 3934d991cb3SStefan Roese } 3944d991cb3SStefan Roese #endif 3954d991cb3SStefan Roese 396350b50eeSStefan Roese void enable_caches(void) 397350b50eeSStefan Roese { 39860b75324SStefan Roese /* Avoid problem with e.g. neta ethernet driver */ 39960b75324SStefan Roese invalidate_dcache_all(); 40060b75324SStefan Roese 401350b50eeSStefan Roese /* Enable D-cache. I-cache is already enabled in start.S */ 402350b50eeSStefan Roese dcache_enable(); 403350b50eeSStefan Roese } 4043e5ce7ceSStefan Roese 4053e5ce7ceSStefan Roese void v7_outer_cache_enable(void) 4063e5ce7ceSStefan Roese { 407c86d53fdSStefan Roese if (mvebu_soc_family() == MVEBU_SOC_AXP) { 4083e5ce7ceSStefan Roese struct pl310_regs *const pl310 = 4093e5ce7ceSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 410c86d53fdSStefan Roese u32 u; 4113e5ce7ceSStefan Roese 4123e5ce7ceSStefan Roese /* The L2 cache is already disabled at this point */ 4133e5ce7ceSStefan Roese 4143e5ce7ceSStefan Roese /* 4153e5ce7ceSStefan Roese * For Aurora cache in no outer mode, enable via the CP15 4163e5ce7ceSStefan Roese * coprocessor broadcasting of cache commands to L2. 4173e5ce7ceSStefan Roese */ 4183e5ce7ceSStefan Roese asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u)); 4193e5ce7ceSStefan Roese u |= BIT(8); /* Set the FW bit */ 4203e5ce7ceSStefan Roese asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u)); 4213e5ce7ceSStefan Roese 4223e5ce7ceSStefan Roese isb(); 4233e5ce7ceSStefan Roese 4243e5ce7ceSStefan Roese /* Enable the L2 cache */ 4253e5ce7ceSStefan Roese setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 4263e5ce7ceSStefan Roese } 4273e5ce7ceSStefan Roese } 428f0e8173aSStefan Roese 429f0e8173aSStefan Roese void v7_outer_cache_disable(void) 430f0e8173aSStefan Roese { 431f0e8173aSStefan Roese struct pl310_regs *const pl310 = 432f0e8173aSStefan Roese (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 433f0e8173aSStefan Roese 434f0e8173aSStefan Roese clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 435f0e8173aSStefan Roese } 436