cache.c 3.9 KB

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