cache.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * U-Boot - cache.c
  3. *
  4. * Copyright (c) 2005-2008 Analog Devices Inc.
  5. *
  6. * (C) Copyright 2000-2004
  7. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  8. *
  9. * Licensed under the GPL-2 or later.
  10. */
  11. #include <common.h>
  12. #include <asm/blackfin.h>
  13. #include <asm/mach-common/bits/mpu.h>
  14. void flush_cache(unsigned long addr, unsigned long size)
  15. {
  16. void *start_addr, *end_addr;
  17. int istatus, dstatus;
  18. /* no need to flush stuff in on chip memory (L1/L2/etc...) */
  19. if (addr >= 0xE0000000)
  20. return;
  21. start_addr = (void *)addr;
  22. end_addr = (void *)(addr + size);
  23. istatus = icache_status();
  24. dstatus = dcache_status();
  25. if (istatus) {
  26. if (dstatus)
  27. blackfin_icache_dcache_flush_range(start_addr, end_addr);
  28. else
  29. blackfin_icache_flush_range(start_addr, end_addr);
  30. } else if (dstatus)
  31. blackfin_dcache_flush_range(start_addr, end_addr);
  32. }
  33. #ifdef CONFIG_DCACHE_WB
  34. static void flushinv_all_dcache(void)
  35. {
  36. u32 way, bank, subbank, set;
  37. u32 status, addr;
  38. u32 dmem_ctl = bfin_read_DMEM_CONTROL();
  39. for (bank = 0; bank < 2; ++bank) {
  40. if (!(dmem_ctl & (1 << (DMC1_P - bank))))
  41. continue;
  42. for (way = 0; way < 2; ++way)
  43. for (subbank = 0; subbank < 4; ++subbank)
  44. for (set = 0; set < 64; ++set) {
  45. bfin_write_DTEST_COMMAND(
  46. way << 26 |
  47. bank << 23 |
  48. subbank << 16 |
  49. set << 5
  50. );
  51. CSYNC();
  52. status = bfin_read_DTEST_DATA0();
  53. /* only worry about valid/dirty entries */
  54. if ((status & 0x3) != 0x3)
  55. continue;
  56. /* construct the address using the tag */
  57. addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5);
  58. /* flush it */
  59. __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr));
  60. }
  61. }
  62. }
  63. #endif
  64. void icache_enable(void)
  65. {
  66. bfin_write_IMEM_CONTROL(IMC | ENICPLB);
  67. SSYNC();
  68. }
  69. void icache_disable(void)
  70. {
  71. bfin_write_IMEM_CONTROL(0);
  72. SSYNC();
  73. }
  74. int icache_status(void)
  75. {
  76. return bfin_read_IMEM_CONTROL() & IMC;
  77. }
  78. void dcache_enable(void)
  79. {
  80. bfin_write_DMEM_CONTROL(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
  81. SSYNC();
  82. }
  83. void dcache_disable(void)
  84. {
  85. #ifdef CONFIG_DCACHE_WB
  86. bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() & ~(ENDCPLB));
  87. flushinv_all_dcache();
  88. #endif
  89. bfin_write_DMEM_CONTROL(0);
  90. SSYNC();
  91. }
  92. int dcache_status(void)
  93. {
  94. return bfin_read_DMEM_CONTROL() & ACACHE_BCACHE;
  95. }
  96. void invalidate_dcache_range(unsigned long start, unsigned long stop)
  97. {
  98. blackfin_dcache_flush_invalidate_range((const void *)start, (const void *)stop);
  99. }
  100. void flush_dcache_range(unsigned long start, unsigned long stop)
  101. {
  102. blackfin_dcache_flush_range((const void *)start, (const void *)stop);
  103. }