cache.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <asm/armv7.h>
  7. #include <asm/pl310.h>
  8. #include <asm/io.h>
  9. #include <asm/mach-imx/sys_proto.h>
  10. static void enable_ca7_smp(void)
  11. {
  12. u32 val;
  13. /* Read MIDR */
  14. asm volatile ("mrc p15, 0, %0, c0, c0, 0\n\t" : "=r"(val));
  15. val = (val >> 4);
  16. val &= 0xf;
  17. /* Only set the SMP for Cortex A7 */
  18. if (val == 0x7) {
  19. /* Read auxiliary control register */
  20. asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" : "=r"(val));
  21. if (val & (1 << 6))
  22. return;
  23. /* Enable SMP */
  24. val |= (1 << 6);
  25. /* Write auxiliary control register */
  26. asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(val));
  27. DSB;
  28. ISB;
  29. }
  30. }
  31. #ifndef CONFIG_SYS_DCACHE_OFF
  32. void enable_caches(void)
  33. {
  34. #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
  35. enum dcache_option option = DCACHE_WRITETHROUGH;
  36. #else
  37. enum dcache_option option = DCACHE_WRITEBACK;
  38. #endif
  39. /* Avoid random hang when download by usb */
  40. invalidate_dcache_all();
  41. /* Set ACTLR.SMP bit for Cortex-A7 */
  42. enable_ca7_smp();
  43. /* Enable D-cache. I-cache is already enabled in start.S */
  44. dcache_enable();
  45. /* Enable caching on OCRAM and ROM */
  46. mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
  47. ROMCP_ARB_END_ADDR,
  48. option);
  49. mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
  50. IRAM_SIZE,
  51. option);
  52. }
  53. #else
  54. void enable_caches(void)
  55. {
  56. /*
  57. * Set ACTLR.SMP bit for Cortex-A7, even if the caches are
  58. * disabled by u-boot
  59. */
  60. enable_ca7_smp();
  61. puts("WARNING: Caches not enabled\n");
  62. }
  63. #endif
  64. #ifndef CONFIG_SYS_L2CACHE_OFF
  65. #ifdef CONFIG_SYS_L2_PL310
  66. #define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
  67. void v7_outer_cache_enable(void)
  68. {
  69. struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
  70. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  71. unsigned int val;
  72. /*
  73. * Must disable the L2 before changing the latency parameters
  74. * and auxiliary control register.
  75. */
  76. clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  77. /*
  78. * Set bit 22 in the auxiliary control register. If this bit
  79. * is cleared, PL310 treats Normal Shared Non-cacheable
  80. * accesses as Cacheable no-allocate.
  81. */
  82. setbits_le32(&pl310->pl310_aux_ctrl, L310_SHARED_ATT_OVERRIDE_ENABLE);
  83. if (is_mx6sl() || is_mx6sll()) {
  84. val = readl(&iomux->gpr[11]);
  85. if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
  86. /* L2 cache configured as OCRAM, reset it */
  87. val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
  88. writel(val, &iomux->gpr[11]);
  89. }
  90. }
  91. writel(0x132, &pl310->pl310_tag_latency_ctrl);
  92. writel(0x132, &pl310->pl310_data_latency_ctrl);
  93. val = readl(&pl310->pl310_prefetch_ctrl);
  94. /* Turn on the L2 I/D prefetch */
  95. val |= 0x30000000;
  96. /*
  97. * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
  98. * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
  99. * But according to ARM PL310 errata: 752271
  100. * ID: 752271: Double linefill feature can cause data corruption
  101. * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
  102. * Workaround: The only workaround to this erratum is to disable the
  103. * double linefill feature. This is the default behavior.
  104. */
  105. #ifndef CONFIG_MX6Q
  106. val |= 0x40800000;
  107. #endif
  108. writel(val, &pl310->pl310_prefetch_ctrl);
  109. val = readl(&pl310->pl310_power_ctrl);
  110. val |= L2X0_DYNAMIC_CLK_GATING_EN;
  111. val |= L2X0_STNDBY_MODE_EN;
  112. writel(val, &pl310->pl310_power_ctrl);
  113. setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  114. }
  115. void v7_outer_cache_disable(void)
  116. {
  117. struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
  118. clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  119. }
  120. #endif /* !CONFIG_SYS_L2_PL310 */
  121. #endif /* !CONFIG_SYS_L2CACHE_OFF */