Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aic94xx_reg.h
Go to the documentation of this file.
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 <[email protected]>
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 
27 #ifndef _AIC94XX_REG_H_
28 #define _AIC94XX_REG_H_
29 
30 #include <asm/io.h>
31 #include "aic94xx_hwi.h"
32 
33 /* Values */
34 #define AIC9410_DEV_REV_B0 0x8
35 
36 /* MBAR0, SWA, SWB, SWC, internal memory space addresses */
37 #define REG_BASE_ADDR 0xB8000000
38 #define REG_BASE_ADDR_CSEQCIO 0xB8002000
39 #define REG_BASE_ADDR_EXSI 0xB8042800
40 
41 #define MBAR0_SWA_SIZE 0x58
42 extern u32 MBAR0_SWB_SIZE;
43 #define MBAR0_SWC_SIZE 0x8
44 
45 /* MBAR1, points to On Chip Memory */
46 #define OCM_BASE_ADDR 0xA0000000
47 #define OCM_MAX_SIZE 0x20000
48 
49 /* Smallest address possible to reference */
50 #define ALL_BASE_ADDR OCM_BASE_ADDR
51 
52 /* PCI configuration space registers */
53 #define PCI_IOBAR_OFFSET 4
54 
55 #define PCI_CONF_MBAR1 0x6C
56 #define PCI_CONF_MBAR0_SWA 0x70
57 #define PCI_CONF_MBAR0_SWB 0x74
58 #define PCI_CONF_MBAR0_SWC 0x78
59 #define PCI_CONF_MBAR_KEY 0x7C
60 #define PCI_CONF_FLSH_BAR 0xB8
61 
62 #include "aic94xx_reg_def.h"
63 
64 u8 asd_read_reg_byte(struct asd_ha_struct *asd_ha, u32 reg);
65 u16 asd_read_reg_word(struct asd_ha_struct *asd_ha, u32 reg);
66 u32 asd_read_reg_dword(struct asd_ha_struct *asd_ha, u32 reg);
67 
68 void asd_write_reg_byte(struct asd_ha_struct *asd_ha, u32 reg, u8 val);
69 void asd_write_reg_word(struct asd_ha_struct *asd_ha, u32 reg, u16 val);
70 void asd_write_reg_dword(struct asd_ha_struct *asd_ha, u32 reg, u32 val);
71 
72 void asd_read_reg_string(struct asd_ha_struct *asd_ha, void *dst,
73  u32 offs, int count);
74 void asd_write_reg_string(struct asd_ha_struct *asd_ha, void *src,
75  u32 offs, int count);
76 
77 #define ASD_READ_OCM(type, ord, S) \
78 static inline type asd_read_ocm_##ord (struct asd_ha_struct *asd_ha, \
79  u32 offs) \
80 { \
81  struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
82  type val = read##S (io_handle->addr + (unsigned long) offs); \
83  rmb(); \
84  return val; \
85 }
86 
90 
91 #define ASD_WRITE_OCM(type, ord, S) \
92 static inline void asd_write_ocm_##ord (struct asd_ha_struct *asd_ha, \
93  u32 offs, type val) \
94 { \
95  struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1]; \
96  write##S (val, io_handle->addr + (unsigned long) offs); \
97  return; \
98 }
99 
103 
104 #define ASD_DDBSITE_READ(type, ord) \
105 static inline type asd_ddbsite_read_##ord (struct asd_ha_struct *asd_ha, \
106  u16 ddb_site_no, \
107  u16 offs) \
108 { \
109  asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
110  asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
111  return asd_read_reg_##ord (asd_ha, CTXACCESS); \
112 }
113 
116 
117 static inline u8 asd_ddbsite_read_byte(struct asd_ha_struct *asd_ha,
118  u16 ddb_site_no,
119  u16 offs)
120 {
121  if (offs & 1)
122  return asd_ddbsite_read_word(asd_ha, ddb_site_no,
123  offs & ~1) >> 8;
124  else
125  return asd_ddbsite_read_word(asd_ha, ddb_site_no,
126  offs) & 0xFF;
127 }
128 
129 
130 #define ASD_DDBSITE_WRITE(type, ord) \
131 static inline void asd_ddbsite_write_##ord (struct asd_ha_struct *asd_ha, \
132  u16 ddb_site_no, \
133  u16 offs, type val) \
134 { \
135  asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs); \
136  asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no); \
137  asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
138 }
139 
142 
143 static inline void asd_ddbsite_write_byte(struct asd_ha_struct *asd_ha,
144  u16 ddb_site_no,
145  u16 offs, u8 val)
146 {
147  u16 base = offs & ~1;
148  u16 rval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
149  if (offs & 1)
150  rval = (val << 8) | (rval & 0xFF);
151  else
152  rval = (rval & 0xFF00) | val;
153  asd_ddbsite_write_word(asd_ha, ddb_site_no, base, rval);
154 }
155 
156 
157 #define ASD_SCBSITE_READ(type, ord) \
158 static inline type asd_scbsite_read_##ord (struct asd_ha_struct *asd_ha, \
159  u16 scb_site_no, \
160  u16 offs) \
161 { \
162  asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
163  asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
164  return asd_read_reg_##ord (asd_ha, CTXACCESS); \
165 }
166 
169 
170 static inline u8 asd_scbsite_read_byte(struct asd_ha_struct *asd_ha,
171  u16 scb_site_no,
172  u16 offs)
173 {
174  if (offs & 1)
175  return asd_scbsite_read_word(asd_ha, scb_site_no,
176  offs & ~1) >> 8;
177  else
178  return asd_scbsite_read_word(asd_ha, scb_site_no,
179  offs) & 0xFF;
180 }
181 
182 
183 #define ASD_SCBSITE_WRITE(type, ord) \
184 static inline void asd_scbsite_write_##ord (struct asd_ha_struct *asd_ha, \
185  u16 scb_site_no, \
186  u16 offs, type val) \
187 { \
188  asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs); \
189  asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no); \
190  asd_write_reg_##ord (asd_ha, CTXACCESS, val); \
191 }
192 
195 
196 static inline void asd_scbsite_write_byte(struct asd_ha_struct *asd_ha,
197  u16 scb_site_no,
198  u16 offs, u8 val)
199 {
200  u16 base = offs & ~1;
201  u16 rval = asd_scbsite_read_word(asd_ha, scb_site_no, base);
202  if (offs & 1)
203  rval = (val << 8) | (rval & 0xFF);
204  else
205  rval = (rval & 0xFF00) | val;
206  asd_scbsite_write_word(asd_ha, scb_site_no, base, rval);
207 }
208 
224 static inline int asd_ddbsite_update_word(struct asd_ha_struct *asd_ha,
225  u16 ddb_site_no, u16 offs,
226  u16 oldval, u16 newval)
227 {
228  u8 done;
229  u16 oval = asd_ddbsite_read_word(asd_ha, ddb_site_no, offs);
230  if (oval != oldval)
231  return -EAGAIN;
232  asd_write_reg_word(asd_ha, AOLDDATA, oldval);
233  asd_write_reg_word(asd_ha, ANEWDATA, newval);
234  do {
235  done = asd_read_reg_byte(asd_ha, ATOMICSTATCTL);
236  } while (!(done & ATOMICDONE));
237  if (done & ATOMICERR)
238  return -EFAULT; /* parity error */
239  else if (done & ATOMICWIN)
240  return 0; /* success */
241  else
242  return -EAGAIN; /* oldval different than current value */
243 }
244 
245 static inline int asd_ddbsite_update_byte(struct asd_ha_struct *asd_ha,
246  u16 ddb_site_no, u16 offs,
247  u8 _oldval, u8 _newval)
248 {
249  u16 base = offs & ~1;
250  u16 oval;
251  u16 nval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
252  if (offs & 1) {
253  if ((nval >> 8) != _oldval)
254  return -EAGAIN;
255  nval = (_newval << 8) | (nval & 0xFF);
256  oval = (_oldval << 8) | (nval & 0xFF);
257  } else {
258  if ((nval & 0xFF) != _oldval)
259  return -EAGAIN;
260  nval = (nval & 0xFF00) | _newval;
261  oval = (nval & 0xFF00) | _oldval;
262  }
263  return asd_ddbsite_update_word(asd_ha, ddb_site_no, base, oval, nval);
264 }
265 
266 static inline void asd_write_reg_addr(struct asd_ha_struct *asd_ha, u32 reg,
268 {
269  asd_write_reg_dword(asd_ha, reg, ASD_BUSADDR_LO(dma_handle));
270  asd_write_reg_dword(asd_ha, reg+4, ASD_BUSADDR_HI(dma_handle));
271 }
272 
273 static inline u32 asd_get_cmdctx_size(struct asd_ha_struct *asd_ha)
274 {
275  /* DCHREVISION returns 0, possibly broken */
276  u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
277  return ctxmemsize ? 65536 : 32768;
278 }
279 
280 static inline u32 asd_get_devctx_size(struct asd_ha_struct *asd_ha)
281 {
282  u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
283  return ctxmemsize ? 8192 : 4096;
284 }
285 
286 static inline void asd_disable_ints(struct asd_ha_struct *asd_ha)
287 {
289 }
290 
291 static inline void asd_enable_ints(struct asd_ha_struct *asd_ha)
292 {
293  /* Enable COM SAS interrupt on errors, COMSTAT */
296  /* Enable DCH SAS CFIFTOERR */
298  /* Enable Host Device interrupts */
300 }
301 
302 #endif