cache-sh2.c 2.2 KB

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