sc-r5k.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
  4. * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
  5. */
  6. #include <linux/init.h>
  7. #include <linux/kernel.h>
  8. #include <linux/sched.h>
  9. #include <linux/mm.h>
  10. #include <asm/mipsregs.h>
  11. #include <asm/bcache.h>
  12. #include <asm/cacheops.h>
  13. #include <asm/page.h>
  14. #include <asm/mmu_context.h>
  15. #include <asm/r4kcache.h>
  16. /* Secondary cache size in bytes, if present. */
  17. static unsigned long scache_size;
  18. #define SC_LINE 32
  19. #define SC_PAGE (128*SC_LINE)
  20. static inline void blast_r5000_scache(void)
  21. {
  22. unsigned long start = INDEX_BASE;
  23. unsigned long end = start + scache_size;
  24. while(start < end) {
  25. cache_op(R5K_Page_Invalidate_S, start);
  26. start += SC_PAGE;
  27. }
  28. }
  29. static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
  30. {
  31. unsigned long end, a;
  32. /* Catch bad driver code */
  33. BUG_ON(size == 0);
  34. if (size >= scache_size) {
  35. blast_r5000_scache();
  36. return;
  37. }
  38. /* On the R5000 secondary cache we cannot
  39. * invalidate less than a page at a time.
  40. * The secondary cache is physically indexed, write-through.
  41. */
  42. a = addr & ~(SC_PAGE - 1);
  43. end = (addr + size - 1) & ~(SC_PAGE - 1);
  44. while (a <= end) {
  45. cache_op(R5K_Page_Invalidate_S, a);
  46. a += SC_PAGE;
  47. }
  48. }
  49. static void r5k_sc_enable(void)
  50. {
  51. unsigned long flags;
  52. local_irq_save(flags);
  53. set_c0_config(R5K_CONF_SE);
  54. blast_r5000_scache();
  55. local_irq_restore(flags);
  56. }
  57. static void r5k_sc_disable(void)
  58. {
  59. unsigned long flags;
  60. local_irq_save(flags);
  61. blast_r5000_scache();
  62. clear_c0_config(R5K_CONF_SE);
  63. local_irq_restore(flags);
  64. }
  65. static inline int __init r5k_sc_probe(void)
  66. {
  67. unsigned long config = read_c0_config();
  68. if (config & CONF_SC)
  69. return 0;
  70. scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
  71. printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n",
  72. scache_size >> 10);
  73. return 1;
  74. }
  75. static struct bcache_ops r5k_sc_ops = {
  76. .bc_enable = r5k_sc_enable,
  77. .bc_disable = r5k_sc_disable,
  78. .bc_wback_inv = r5k_dma_cache_inv_sc,
  79. .bc_inv = r5k_dma_cache_inv_sc
  80. };
  81. void r5k_sc_init(void)
  82. {
  83. if (r5k_sc_probe()) {
  84. r5k_sc_enable();
  85. bcops = &r5k_sc_ops;
  86. }
  87. }