cs5536_ide.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * the IDE Virtual Support Module of AMD CS5536
  3. *
  4. * Copyright (C) 2007 Lemote, Inc.
  5. * Author : jlliu, liujl@lemote.com
  6. *
  7. * Copyright (C) 2009 Lemote, Inc.
  8. * Author: Wu Zhangjin, wuzhangjin@gmail.com
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. */
  15. #include <cs5536/cs5536.h>
  16. #include <cs5536/cs5536_pci.h>
  17. void pci_ide_write_reg(int reg, u32 value)
  18. {
  19. u32 hi = 0, lo = value;
  20. switch (reg) {
  21. case PCI_COMMAND:
  22. _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
  23. if (value & PCI_COMMAND_MASTER)
  24. lo |= (0x03 << 4);
  25. else
  26. lo &= ~(0x03 << 4);
  27. _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
  28. break;
  29. case PCI_STATUS:
  30. if (value & PCI_STATUS_PARITY) {
  31. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  32. if (lo & SB_PARE_ERR_FLAG) {
  33. lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
  34. _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
  35. }
  36. }
  37. break;
  38. case PCI_CACHE_LINE_SIZE:
  39. value &= 0x0000ff00;
  40. _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
  41. hi &= 0xffffff00;
  42. hi |= (value >> 8);
  43. _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
  44. break;
  45. case PCI_BAR4_REG:
  46. if (value == PCI_BAR_RANGE_MASK) {
  47. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  48. lo |= SOFT_BAR_IDE_FLAG;
  49. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  50. } else if (value & 0x01) {
  51. _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  52. lo = (value & 0xfffffff0) | 0x1;
  53. _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
  54. value &= 0xfffffffc;
  55. hi = 0x60000000 | ((value & 0x000ff000) >> 12);
  56. lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
  57. _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
  58. }
  59. break;
  60. case PCI_IDE_CFG_REG:
  61. if (value == CS5536_IDE_FLASH_SIGNATURE) {
  62. _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
  63. lo |= 0x01;
  64. _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
  65. } else {
  66. _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
  67. lo = value;
  68. _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
  69. }
  70. break;
  71. case PCI_IDE_DTC_REG:
  72. _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
  73. lo = value;
  74. _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
  75. break;
  76. case PCI_IDE_CAST_REG:
  77. _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
  78. lo = value;
  79. _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
  80. break;
  81. case PCI_IDE_ETC_REG:
  82. _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
  83. lo = value;
  84. _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
  85. break;
  86. case PCI_IDE_PM_REG:
  87. _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
  88. lo = value;
  89. _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
  90. break;
  91. default:
  92. break;
  93. }
  94. }
  95. u32 pci_ide_read_reg(int reg)
  96. {
  97. u32 conf_data = 0;
  98. u32 hi, lo;
  99. switch (reg) {
  100. case PCI_VENDOR_ID:
  101. conf_data =
  102. CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
  103. break;
  104. case PCI_COMMAND:
  105. _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  106. if (lo & 0xfffffff0)
  107. conf_data |= PCI_COMMAND_IO;
  108. _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
  109. if ((lo & 0x30) == 0x30)
  110. conf_data |= PCI_COMMAND_MASTER;
  111. break;
  112. case PCI_STATUS:
  113. conf_data |= PCI_STATUS_66MHZ;
  114. conf_data |= PCI_STATUS_FAST_BACK;
  115. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  116. if (lo & SB_PARE_ERR_FLAG)
  117. conf_data |= PCI_STATUS_PARITY;
  118. conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  119. break;
  120. case PCI_CLASS_REVISION:
  121. _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
  122. conf_data = lo & 0x000000ff;
  123. conf_data |= (CS5536_IDE_CLASS_CODE << 8);
  124. break;
  125. case PCI_CACHE_LINE_SIZE:
  126. _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
  127. hi &= 0x000000f8;
  128. conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
  129. break;
  130. case PCI_BAR4_REG:
  131. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  132. if (lo & SOFT_BAR_IDE_FLAG) {
  133. conf_data = CS5536_IDE_RANGE |
  134. PCI_BASE_ADDRESS_SPACE_IO;
  135. lo &= ~SOFT_BAR_IDE_FLAG;
  136. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  137. } else {
  138. _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  139. conf_data = lo & 0xfffffff0;
  140. conf_data |= 0x01;
  141. conf_data &= ~0x02;
  142. }
  143. break;
  144. case PCI_CARDBUS_CIS:
  145. conf_data = PCI_CARDBUS_CIS_POINTER;
  146. break;
  147. case PCI_SUBSYSTEM_VENDOR_ID:
  148. conf_data =
  149. CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
  150. break;
  151. case PCI_ROM_ADDRESS:
  152. conf_data = PCI_EXPANSION_ROM_BAR;
  153. break;
  154. case PCI_CAPABILITY_LIST:
  155. conf_data = PCI_CAPLIST_POINTER;
  156. break;
  157. case PCI_INTERRUPT_LINE:
  158. conf_data =
  159. CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
  160. break;
  161. case PCI_IDE_CFG_REG:
  162. _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
  163. conf_data = lo;
  164. break;
  165. case PCI_IDE_DTC_REG:
  166. _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
  167. conf_data = lo;
  168. break;
  169. case PCI_IDE_CAST_REG:
  170. _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
  171. conf_data = lo;
  172. break;
  173. case PCI_IDE_ETC_REG:
  174. _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
  175. conf_data = lo;
  176. break;
  177. case PCI_IDE_PM_REG:
  178. _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
  179. conf_data = lo;
  180. break;
  181. default:
  182. break;
  183. }
  184. return conf_data;
  185. }