probe.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * arch/sh/kernel/cpu/sh3/probe.c
  3. *
  4. * CPU Subtype Probing for SH-3.
  5. *
  6. * Copyright (C) 1999, 2000 Niibe Yutaka
  7. * Copyright (C) 2002 Paul Mundt
  8. *
  9. * This file is subject to the terms and conditions of the GNU General Public
  10. * License. See the file "COPYING" in the main directory of this archive
  11. * for more details.
  12. */
  13. #include <linux/init.h>
  14. #include <asm/processor.h>
  15. #include <asm/cache.h>
  16. #include <asm/io.h>
  17. int __init detect_cpu_and_cache_system(void)
  18. {
  19. unsigned long addr0, addr1, data0, data1, data2, data3;
  20. jump_to_P2();
  21. /*
  22. * Check if the entry shadows or not.
  23. * When shadowed, it's 128-entry system.
  24. * Otherwise, it's 256-entry system.
  25. */
  26. addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
  27. addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
  28. /* First, write back & invalidate */
  29. data0 = ctrl_inl(addr0);
  30. ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
  31. data1 = ctrl_inl(addr1);
  32. ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
  33. /* Next, check if there's shadow or not */
  34. data0 = ctrl_inl(addr0);
  35. data0 ^= SH_CACHE_VALID;
  36. ctrl_outl(data0, addr0);
  37. data1 = ctrl_inl(addr1);
  38. data2 = data1 ^ SH_CACHE_VALID;
  39. ctrl_outl(data2, addr1);
  40. data3 = ctrl_inl(addr0);
  41. /* Lastly, invaliate them. */
  42. ctrl_outl(data0&~SH_CACHE_VALID, addr0);
  43. ctrl_outl(data2&~SH_CACHE_VALID, addr1);
  44. back_to_P1();
  45. cpu_data->dcache.ways = 4;
  46. cpu_data->dcache.entry_shift = 4;
  47. cpu_data->dcache.linesz = L1_CACHE_BYTES;
  48. cpu_data->dcache.flags = 0;
  49. /*
  50. * 7709A/7729 has 16K cache (256-entry), while 7702 has only
  51. * 2K(direct) 7702 is not supported (yet)
  52. */
  53. if (data0 == data1 && data2 == data3) { /* Shadow */
  54. cpu_data->dcache.way_incr = (1 << 11);
  55. cpu_data->dcache.entry_mask = 0x7f0;
  56. cpu_data->dcache.sets = 128;
  57. cpu_data->type = CPU_SH7708;
  58. cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC;
  59. } else { /* 7709A or 7729 */
  60. cpu_data->dcache.way_incr = (1 << 12);
  61. cpu_data->dcache.entry_mask = 0xff0;
  62. cpu_data->dcache.sets = 256;
  63. cpu_data->type = CPU_SH7729;
  64. #if defined(CONFIG_CPU_SUBTYPE_SH7705)
  65. cpu_data->type = CPU_SH7705;
  66. #if defined(CONFIG_SH7705_CACHE_32KB)
  67. cpu_data->dcache.way_incr = (1 << 13);
  68. cpu_data->dcache.entry_mask = 0x1ff0;
  69. cpu_data->dcache.sets = 512;
  70. ctrl_outl(CCR_CACHE_32KB, CCR3);
  71. #else
  72. ctrl_outl(CCR_CACHE_16KB, CCR3);
  73. #endif
  74. #endif
  75. }
  76. /*
  77. * SH-3 doesn't have separate caches
  78. */
  79. cpu_data->dcache.flags |= SH_CACHE_COMBINED;
  80. cpu_data->icache = cpu_data->dcache;
  81. return 0;
  82. }