cache.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
  4. * Copyright (C) 2009, Wind River Systems Inc
  5. * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
  6. */
  7. #include <common.h>
  8. #include <asm/cache.h>
  9. DECLARE_GLOBAL_DATA_PTR;
  10. static void __flush_dcache(unsigned long start, unsigned long end)
  11. {
  12. unsigned long addr;
  13. start &= ~(gd->arch.dcache_line_size - 1);
  14. end += (gd->arch.dcache_line_size - 1);
  15. end &= ~(gd->arch.dcache_line_size - 1);
  16. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  17. __asm__ __volatile__ (" flushda 0(%0)\n"
  18. : /* Outputs */
  19. : /* Inputs */ "r"(addr)
  20. /* : No clobber */);
  21. }
  22. }
  23. static void __flush_dcache_all(unsigned long start, unsigned long end)
  24. {
  25. unsigned long addr;
  26. start &= ~(gd->arch.dcache_line_size - 1);
  27. end += (gd->arch.dcache_line_size - 1);
  28. end &= ~(gd->arch.dcache_line_size - 1);
  29. if (end > start + gd->arch.dcache_size)
  30. end = start + gd->arch.dcache_size;
  31. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  32. __asm__ __volatile__ (" flushd 0(%0)\n"
  33. : /* Outputs */
  34. : /* Inputs */ "r"(addr)
  35. /* : No clobber */);
  36. }
  37. }
  38. static void __invalidate_dcache(unsigned long start, unsigned long end)
  39. {
  40. unsigned long addr;
  41. start &= ~(gd->arch.dcache_line_size - 1);
  42. end += (gd->arch.dcache_line_size - 1);
  43. end &= ~(gd->arch.dcache_line_size - 1);
  44. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  45. __asm__ __volatile__ (" initda 0(%0)\n"
  46. : /* Outputs */
  47. : /* Inputs */ "r"(addr)
  48. /* : No clobber */);
  49. }
  50. }
  51. static void __flush_icache(unsigned long start, unsigned long end)
  52. {
  53. unsigned long addr;
  54. start &= ~(gd->arch.icache_line_size - 1);
  55. end += (gd->arch.icache_line_size - 1);
  56. end &= ~(gd->arch.icache_line_size - 1);
  57. if (end > start + gd->arch.icache_size)
  58. end = start + gd->arch.icache_size;
  59. for (addr = start; addr < end; addr += gd->arch.icache_line_size) {
  60. __asm__ __volatile__ (" flushi %0\n"
  61. : /* Outputs */
  62. : /* Inputs */ "r"(addr)
  63. /* : No clobber */);
  64. }
  65. __asm__ __volatile(" flushp\n");
  66. }
  67. void flush_dcache_all(void)
  68. {
  69. __flush_dcache_all(0, gd->arch.dcache_size);
  70. __flush_icache(0, gd->arch.icache_size);
  71. }
  72. void flush_dcache_range(unsigned long start, unsigned long end)
  73. {
  74. if (gd->arch.has_initda)
  75. __flush_dcache(start, end);
  76. else
  77. __flush_dcache_all(start, end);
  78. }
  79. void flush_cache(unsigned long start, unsigned long size)
  80. {
  81. if (gd->arch.has_initda)
  82. __flush_dcache(start, start + size);
  83. else
  84. __flush_dcache_all(start, start + size);
  85. __flush_icache(start, start + size);
  86. }
  87. void invalidate_dcache_range(unsigned long start, unsigned long end)
  88. {
  89. if (gd->arch.has_initda)
  90. __invalidate_dcache(start, end);
  91. else
  92. __flush_dcache_all(start, end);
  93. }
  94. int dcache_status(void)
  95. {
  96. return 1;
  97. }
  98. void dcache_enable(void)
  99. {
  100. flush_dcache_all();
  101. }
  102. void dcache_disable(void)
  103. {
  104. flush_dcache_all();
  105. }