sc-r5k.c 2.2 KB

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