cache-sh2.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * arch/sh/mm/cache-sh2.c
  3. *
  4. * Copyright (C) 2002 Paul Mundt
  5. * Copyright (C) 2008 Yoshinori Sato
  6. *
  7. * Released under the terms of the GNU GPL v2.0.
  8. */
  9. #include <linux/init.h>
  10. #include <linux/mm.h>
  11. #include <asm/cache.h>
  12. #include <asm/addrspace.h>
  13. #include <asm/processor.h>
  14. #include <asm/cacheflush.h>
  15. #include <asm/io.h>
  16. static void sh2__flush_wback_region(void *start, int size)
  17. {
  18. unsigned long v;
  19. unsigned long begin, end;
  20. begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  21. end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  22. & ~(L1_CACHE_BYTES-1);
  23. for (v = begin; v < end; v+=L1_CACHE_BYTES) {
  24. unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
  25. int way;
  26. for (way = 0; way < 4; way++) {
  27. unsigned long data = __raw_readl(addr | (way << 12));
  28. if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
  29. data &= ~SH_CACHE_UPDATED;
  30. __raw_writel(data, addr | (way << 12));
  31. }
  32. }
  33. }
  34. }
  35. static void sh2__flush_purge_region(void *start, int size)
  36. {
  37. unsigned long v;
  38. unsigned long begin, end;
  39. begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  40. end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  41. & ~(L1_CACHE_BYTES-1);
  42. for (v = begin; v < end; v+=L1_CACHE_BYTES)
  43. __raw_writel((v & CACHE_PHYSADDR_MASK),
  44. CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
  45. }
  46. static void sh2__flush_invalidate_region(void *start, int size)
  47. {
  48. #ifdef CONFIG_CACHE_WRITEBACK
  49. /*
  50. * SH-2 does not support individual line invalidation, only a
  51. * global invalidate.
  52. */
  53. unsigned long ccr;
  54. unsigned long flags;
  55. local_irq_save(flags);
  56. jump_to_uncached();
  57. ccr = __raw_readl(SH_CCR);
  58. ccr |= CCR_CACHE_INVALIDATE;
  59. __raw_writel(ccr, SH_CCR);
  60. back_to_cached();
  61. local_irq_restore(flags);
  62. #else
  63. unsigned long v;
  64. unsigned long begin, end;
  65. begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  66. end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  67. & ~(L1_CACHE_BYTES-1);
  68. for (v = begin; v < end; v+=L1_CACHE_BYTES)
  69. __raw_writel((v & CACHE_PHYSADDR_MASK),
  70. CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
  71. #endif
  72. }
  73. void __init sh2_cache_init(void)
  74. {
  75. __flush_wback_region = sh2__flush_wback_region;
  76. __flush_purge_region = sh2__flush_purge_region;
  77. __flush_invalidate_region = sh2__flush_invalidate_region;
  78. }