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