aic94xx_reg.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Aic94xx SAS/SATA driver hardware registers definitions.
  3. *
  4. * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
  5. * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
  6. *
  7. * This file is licensed under GPLv2.
  8. *
  9. * This file is part of the aic94xx driver.
  10. *
  11. * The aic94xx driver is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; version 2 of the
  14. * License.
  15. *
  16. * The aic94xx driver is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with the aic94xx driver; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. */
  26. #ifndef _AIC94XX_REG_H_
  27. #define _AIC94XX_REG_H_
  28. #include <asm/io.h>
  29. #include "aic94xx_hwi.h"
  30. /* Values */
  31. #define AIC9410_DEV_REV_B0 0x8
  32. /* MBAR0, SWA, SWB, SWC, internal memory space addresses */
  33. #define REG_BASE_ADDR 0xB8000000
  34. #define REG_BASE_ADDR_CSEQCIO 0xB8002000
  35. #define REG_BASE_ADDR_EXSI 0xB8042800
  36. #define MBAR0_SWA_SIZE 0x58
  37. extern u32 MBAR0_SWB_SIZE;
  38. #define MBAR0_SWC_SIZE 0x8
  39. /* MBAR1, points to On Chip Memory */
  40. #define OCM_BASE_ADDR 0xA0000000
  41. #define OCM_MAX_SIZE 0x20000
  42. /* Smallest address possible to reference */
  43. #define ALL_BASE_ADDR OCM_BASE_ADDR
  44. /* PCI configuration space registers */
  45. #define PCI_IOBAR_OFFSET 4
  46. #define PCI_CONF_MBAR1 0x6C
  47. #define PCI_CONF_MBAR0_SWA 0x70
  48. #define PCI_CONF_MBAR0_SWB 0x74
  49. #define PCI_CONF_MBAR0_SWC 0x78
  50. #define PCI_CONF_MBAR_KEY 0x7C
  51. #define PCI_CONF_FLSH_BAR 0xB8
  52. #include "aic94xx_reg_def.h"
  53. u8 asd_read_reg_byte(struct asd_ha_struct *asd_ha, u32 reg);
  54. u16 asd_read_reg_word(struct asd_ha_struct *asd_ha, u32 reg);
  55. u32 asd_read_reg_dword(struct asd_ha_struct *asd_ha, u32 reg);
  56. void asd_write_reg_byte(struct asd_ha_struct *asd_ha, u32 reg, u8 val);
  57. void asd_write_reg_word(struct asd_ha_struct *asd_ha, u32 reg, u16 val);
  58. void asd_write_reg_dword(struct asd_ha_struct *asd_ha, u32 reg, u32 val);
  59. void asd_read_reg_string(struct asd_ha_struct *asd_ha, void *dst,
  60. u32 offs, int count);
  61. void asd_write_reg_string(struct asd_ha_struct *asd_ha, void *src,
  62. u32 offs, int count);
  63. #define ASD_READ_OCM(type, ord, S) \
  64. static inline type asd_read_ocm_##ord (struct asd_ha_struct *asd_ha, \
  65. u32 offs) \
  66. { \
  67. struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
  68. type val = read##S (io_handle->addr + (unsigned long) offs); \
  69. rmb(); \
  70. return val; \
  71. }
  72. ASD_READ_OCM(u8, byte, b);
  73. ASD_READ_OCM(u16,word, w);
  74. ASD_READ_OCM(u32,dword,l);
  75. #define ASD_WRITE_OCM(type, ord, S) \
  76. static inline void asd_write_ocm_##ord (struct asd_ha_struct *asd_ha, \
  77. u32 offs, type val) \
  78. { \
  79. struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
  80. write##S (val, io_handle->addr + (unsigned long) offs); \
  81. return; \
  82. }
  83. ASD_WRITE_OCM(u8, byte, b);
  84. ASD_WRITE_OCM(u16,word, w);
  85. ASD_WRITE_OCM(u32,dword,l);
  86. #define ASD_DDBSITE_READ(type, ord) \
  87. static inline type asd_ddbsite_read_##ord (struct asd_ha_struct *asd_ha, \
  88. u16 ddb_site_no, \
  89. u16 offs) \
  90. { \
  91. asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
  92. asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
  93. return asd_read_reg_##ord (asd_ha, CTXACCESS); \
  94. }
  95. ASD_DDBSITE_READ(u32, dword);
  96. ASD_DDBSITE_READ(u16, word);
  97. static inline u8 asd_ddbsite_read_byte(struct asd_ha_struct *asd_ha,
  98. u16 ddb_site_no,
  99. u16 offs)
  100. {
  101. if (offs & 1)
  102. return asd_ddbsite_read_word(asd_ha, ddb_site_no,
  103. offs & ~1) >> 8;
  104. else
  105. return asd_ddbsite_read_word(asd_ha, ddb_site_no,
  106. offs) & 0xFF;
  107. }
  108. #define ASD_DDBSITE_WRITE(type, ord) \
  109. static inline void asd_ddbsite_write_##ord (struct asd_ha_struct *asd_ha, \
  110. u16 ddb_site_no, \
  111. u16 offs, type val) \
  112. { \
  113. asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
  114. asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
  115. asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
  116. }
  117. ASD_DDBSITE_WRITE(u32, dword);
  118. ASD_DDBSITE_WRITE(u16, word);
  119. static inline void asd_ddbsite_write_byte(struct asd_ha_struct *asd_ha,
  120. u16 ddb_site_no,
  121. u16 offs, u8 val)
  122. {
  123. u16 base = offs & ~1;
  124. u16 rval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
  125. if (offs & 1)
  126. rval = (val << 8) | (rval & 0xFF);
  127. else
  128. rval = (rval & 0xFF00) | val;
  129. asd_ddbsite_write_word(asd_ha, ddb_site_no, base, rval);
  130. }
  131. #define ASD_SCBSITE_READ(type, ord) \
  132. static inline type asd_scbsite_read_##ord (struct asd_ha_struct *asd_ha, \
  133. u16 scb_site_no, \
  134. u16 offs) \
  135. { \
  136. asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
  137. asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
  138. return asd_read_reg_##ord (asd_ha, CTXACCESS); \
  139. }
  140. ASD_SCBSITE_READ(u32, dword);
  141. ASD_SCBSITE_READ(u16, word);
  142. static inline u8 asd_scbsite_read_byte(struct asd_ha_struct *asd_ha,
  143. u16 scb_site_no,
  144. u16 offs)
  145. {
  146. if (offs & 1)
  147. return asd_scbsite_read_word(asd_ha, scb_site_no,
  148. offs & ~1) >> 8;
  149. else
  150. return asd_scbsite_read_word(asd_ha, scb_site_no,
  151. offs) & 0xFF;
  152. }
  153. #define ASD_SCBSITE_WRITE(type, ord) \
  154. static inline void asd_scbsite_write_##ord (struct asd_ha_struct *asd_ha, \
  155. u16 scb_site_no, \
  156. u16 offs, type val) \
  157. { \
  158. asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
  159. asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
  160. asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
  161. }
  162. ASD_SCBSITE_WRITE(u32, dword);
  163. ASD_SCBSITE_WRITE(u16, word);
  164. static inline void asd_scbsite_write_byte(struct asd_ha_struct *asd_ha,
  165. u16 scb_site_no,
  166. u16 offs, u8 val)
  167. {
  168. u16 base = offs & ~1;
  169. u16 rval = asd_scbsite_read_word(asd_ha, scb_site_no, base);
  170. if (offs & 1)
  171. rval = (val << 8) | (rval & 0xFF);
  172. else
  173. rval = (rval & 0xFF00) | val;
  174. asd_scbsite_write_word(asd_ha, scb_site_no, base, rval);
  175. }
  176. /**
  177. * asd_ddbsite_update_word -- atomically update a word in a ddb site
  178. * @asd_ha: pointer to host adapter structure
  179. * @ddb_site_no: the DDB site number
  180. * @offs: the offset into the DDB
  181. * @oldval: old value found in that offset
  182. * @newval: the new value to replace it
  183. *
  184. * This function is used when the sequencers are running and we need to
  185. * update a DDB site atomically without expensive pausing and upausing
  186. * of the sequencers and accessing the DDB site through the CIO bus.
  187. *
  188. * Return 0 on success; -EFAULT on parity error; -EAGAIN if the old value
  189. * is different than the current value at that offset.
  190. */
  191. static inline int asd_ddbsite_update_word(struct asd_ha_struct *asd_ha,
  192. u16 ddb_site_no, u16 offs,
  193. u16 oldval, u16 newval)
  194. {
  195. u8 done;
  196. u16 oval = asd_ddbsite_read_word(asd_ha, ddb_site_no, offs);
  197. if (oval != oldval)
  198. return -EAGAIN;
  199. asd_write_reg_word(asd_ha, AOLDDATA, oldval);
  200. asd_write_reg_word(asd_ha, ANEWDATA, newval);
  201. do {
  202. done = asd_read_reg_byte(asd_ha, ATOMICSTATCTL);
  203. } while (!(done & ATOMICDONE));
  204. if (done & ATOMICERR)
  205. return -EFAULT; /* parity error */
  206. else if (done & ATOMICWIN)
  207. return 0; /* success */
  208. else
  209. return -EAGAIN; /* oldval different than current value */
  210. }
  211. static inline int asd_ddbsite_update_byte(struct asd_ha_struct *asd_ha,
  212. u16 ddb_site_no, u16 offs,
  213. u8 _oldval, u8 _newval)
  214. {
  215. u16 base = offs & ~1;
  216. u16 oval;
  217. u16 nval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
  218. if (offs & 1) {
  219. if ((nval >> 8) != _oldval)
  220. return -EAGAIN;
  221. nval = (_newval << 8) | (nval & 0xFF);
  222. oval = (_oldval << 8) | (nval & 0xFF);
  223. } else {
  224. if ((nval & 0xFF) != _oldval)
  225. return -EAGAIN;
  226. nval = (nval & 0xFF00) | _newval;
  227. oval = (nval & 0xFF00) | _oldval;
  228. }
  229. return asd_ddbsite_update_word(asd_ha, ddb_site_no, base, oval, nval);
  230. }
  231. static inline void asd_write_reg_addr(struct asd_ha_struct *asd_ha, u32 reg,
  232. dma_addr_t dma_handle)
  233. {
  234. asd_write_reg_dword(asd_ha, reg, ASD_BUSADDR_LO(dma_handle));
  235. asd_write_reg_dword(asd_ha, reg+4, ASD_BUSADDR_HI(dma_handle));
  236. }
  237. static inline u32 asd_get_cmdctx_size(struct asd_ha_struct *asd_ha)
  238. {
  239. /* DCHREVISION returns 0, possibly broken */
  240. u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
  241. return ctxmemsize ? 65536 : 32768;
  242. }
  243. static inline u32 asd_get_devctx_size(struct asd_ha_struct *asd_ha)
  244. {
  245. u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
  246. return ctxmemsize ? 8192 : 4096;
  247. }
  248. static inline void asd_disable_ints(struct asd_ha_struct *asd_ha)
  249. {
  250. asd_write_reg_dword(asd_ha, CHIMINTEN, RST_CHIMINTEN);
  251. }
  252. static inline void asd_enable_ints(struct asd_ha_struct *asd_ha)
  253. {
  254. /* Enable COM SAS interrupt on errors, COMSTAT */
  255. asd_write_reg_dword(asd_ha, COMSTATEN,
  256. EN_CSBUFPERR | EN_CSERR | EN_OVLYERR);
  257. /* Enable DCH SAS CFIFTOERR */
  258. asd_write_reg_dword(asd_ha, DCHSTATUS, EN_CFIFTOERR);
  259. /* Enable Host Device interrupts */
  260. asd_write_reg_dword(asd_ha, CHIMINTEN, SET_CHIMINTEN);
  261. }
  262. #endif