xref: /linux/drivers/scsi/aic94xx/aic94xx_reg.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*65c85c83SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
22908d778SJames Bottomley /*
32908d778SJames Bottomley  * Aic94xx SAS/SATA driver hardware registers definitions.
42908d778SJames Bottomley  *
52908d778SJames Bottomley  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
62908d778SJames Bottomley  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
72908d778SJames Bottomley  */
82908d778SJames Bottomley 
92908d778SJames Bottomley #ifndef _AIC94XX_REG_H_
102908d778SJames Bottomley #define _AIC94XX_REG_H_
112908d778SJames Bottomley 
122908d778SJames Bottomley #include <asm/io.h>
132908d778SJames Bottomley #include "aic94xx_hwi.h"
142908d778SJames Bottomley 
152908d778SJames Bottomley /* Values */
162908d778SJames Bottomley #define AIC9410_DEV_REV_B0            0x8
172908d778SJames Bottomley 
182908d778SJames Bottomley /* MBAR0, SWA, SWB, SWC, internal memory space addresses */
192908d778SJames Bottomley #define REG_BASE_ADDR                 0xB8000000
202908d778SJames Bottomley #define REG_BASE_ADDR_CSEQCIO         0xB8002000
212908d778SJames Bottomley #define REG_BASE_ADDR_EXSI            0xB8042800
222908d778SJames Bottomley 
232908d778SJames Bottomley #define MBAR0_SWA_SIZE                0x58
242908d778SJames Bottomley extern  u32    MBAR0_SWB_SIZE;
252908d778SJames Bottomley #define MBAR0_SWC_SIZE                0x8
262908d778SJames Bottomley 
272908d778SJames Bottomley /* MBAR1, points to On Chip Memory */
282908d778SJames Bottomley #define OCM_BASE_ADDR                 0xA0000000
292908d778SJames Bottomley #define OCM_MAX_SIZE                  0x20000
302908d778SJames Bottomley 
312908d778SJames Bottomley /* Smallest address possible to reference */
322908d778SJames Bottomley #define ALL_BASE_ADDR                 OCM_BASE_ADDR
332908d778SJames Bottomley 
342908d778SJames Bottomley /* PCI configuration space registers */
352908d778SJames Bottomley #define PCI_IOBAR_OFFSET              4
362908d778SJames Bottomley 
372908d778SJames Bottomley #define PCI_CONF_MBAR1                0x6C
382908d778SJames Bottomley #define PCI_CONF_MBAR0_SWA            0x70
392908d778SJames Bottomley #define PCI_CONF_MBAR0_SWB            0x74
402908d778SJames Bottomley #define PCI_CONF_MBAR0_SWC            0x78
412908d778SJames Bottomley #define PCI_CONF_MBAR_KEY             0x7C
422908d778SJames Bottomley #define PCI_CONF_FLSH_BAR             0xB8
432908d778SJames Bottomley 
442908d778SJames Bottomley #include "aic94xx_reg_def.h"
452908d778SJames Bottomley 
462908d778SJames Bottomley u8  asd_read_reg_byte(struct asd_ha_struct *asd_ha, u32 reg);
472908d778SJames Bottomley u16 asd_read_reg_word(struct asd_ha_struct *asd_ha, u32 reg);
482908d778SJames Bottomley u32 asd_read_reg_dword(struct asd_ha_struct *asd_ha, u32 reg);
492908d778SJames Bottomley 
502908d778SJames Bottomley void asd_write_reg_byte(struct asd_ha_struct *asd_ha, u32 reg, u8 val);
512908d778SJames Bottomley void asd_write_reg_word(struct asd_ha_struct *asd_ha, u32 reg, u16 val);
522908d778SJames Bottomley void asd_write_reg_dword(struct asd_ha_struct *asd_ha, u32 reg, u32 val);
532908d778SJames Bottomley 
542908d778SJames Bottomley void asd_read_reg_string(struct asd_ha_struct *asd_ha, void *dst,
552908d778SJames Bottomley 			 u32 offs, int count);
562908d778SJames Bottomley void asd_write_reg_string(struct asd_ha_struct *asd_ha, void *src,
572908d778SJames Bottomley 			  u32 offs, int count);
582908d778SJames Bottomley 
592908d778SJames Bottomley #define ASD_READ_OCM(type, ord, S)                                    \
602908d778SJames Bottomley static inline type asd_read_ocm_##ord (struct asd_ha_struct *asd_ha,  \
612908d778SJames Bottomley 					 u32 offs)                    \
622908d778SJames Bottomley {                                                                     \
632908d778SJames Bottomley 	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1];   \
642908d778SJames Bottomley 	type val = read##S (io_handle->addr + (unsigned long) offs);  \
652908d778SJames Bottomley 	rmb();                                                        \
662908d778SJames Bottomley 	return val;                                                   \
672908d778SJames Bottomley }
682908d778SJames Bottomley 
692908d778SJames Bottomley ASD_READ_OCM(u8, byte, b);
702908d778SJames Bottomley ASD_READ_OCM(u16,word, w);
712908d778SJames Bottomley ASD_READ_OCM(u32,dword,l);
722908d778SJames Bottomley 
732908d778SJames Bottomley #define ASD_WRITE_OCM(type, ord, S)                                    \
742908d778SJames Bottomley static inline void asd_write_ocm_##ord (struct asd_ha_struct *asd_ha,  \
752908d778SJames Bottomley 					 u32 offs, type val)          \
762908d778SJames Bottomley {                                                                     \
772908d778SJames Bottomley 	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[1];   \
782908d778SJames Bottomley 	write##S (val, io_handle->addr + (unsigned long) offs);       \
792908d778SJames Bottomley 	return;                                                       \
802908d778SJames Bottomley }
812908d778SJames Bottomley 
822908d778SJames Bottomley ASD_WRITE_OCM(u8, byte, b);
832908d778SJames Bottomley ASD_WRITE_OCM(u16,word, w);
842908d778SJames Bottomley ASD_WRITE_OCM(u32,dword,l);
852908d778SJames Bottomley 
862908d778SJames Bottomley #define ASD_DDBSITE_READ(type, ord)                                        \
872908d778SJames Bottomley static inline type asd_ddbsite_read_##ord (struct asd_ha_struct *asd_ha,   \
882908d778SJames Bottomley 					   u16 ddb_site_no,                \
892908d778SJames Bottomley 					   u16 offs)                       \
902908d778SJames Bottomley {                                                                          \
912908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs);          \
922908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no);                  \
932908d778SJames Bottomley 	return asd_read_reg_##ord (asd_ha, CTXACCESS);                     \
942908d778SJames Bottomley }
952908d778SJames Bottomley 
962908d778SJames Bottomley ASD_DDBSITE_READ(u32, dword);
972908d778SJames Bottomley ASD_DDBSITE_READ(u16, word);
982908d778SJames Bottomley 
asd_ddbsite_read_byte(struct asd_ha_struct * asd_ha,u16 ddb_site_no,u16 offs)992908d778SJames Bottomley static inline u8 asd_ddbsite_read_byte(struct asd_ha_struct *asd_ha,
1002908d778SJames Bottomley 				       u16 ddb_site_no,
1012908d778SJames Bottomley 				       u16 offs)
1022908d778SJames Bottomley {
1032908d778SJames Bottomley 	if (offs & 1)
1042908d778SJames Bottomley 		return asd_ddbsite_read_word(asd_ha, ddb_site_no,
1052908d778SJames Bottomley 					     offs & ~1) >> 8;
1062908d778SJames Bottomley 	else
1072908d778SJames Bottomley 		return asd_ddbsite_read_word(asd_ha, ddb_site_no,
1082908d778SJames Bottomley 					     offs) & 0xFF;
1092908d778SJames Bottomley }
1102908d778SJames Bottomley 
1112908d778SJames Bottomley 
1122908d778SJames Bottomley #define ASD_DDBSITE_WRITE(type, ord)                                       \
1132908d778SJames Bottomley static inline void asd_ddbsite_write_##ord (struct asd_ha_struct *asd_ha,  \
1142908d778SJames Bottomley 					u16 ddb_site_no,                   \
1152908d778SJames Bottomley 					u16 offs, type val)                \
1162908d778SJames Bottomley {                                                                          \
1172908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ALTCIOADR, MnDDB_SITE + offs);          \
1182908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ADDBPTR, ddb_site_no);                  \
1192908d778SJames Bottomley 	asd_write_reg_##ord (asd_ha, CTXACCESS, val);                      \
1202908d778SJames Bottomley }
1212908d778SJames Bottomley 
1222908d778SJames Bottomley ASD_DDBSITE_WRITE(u32, dword);
1232908d778SJames Bottomley ASD_DDBSITE_WRITE(u16, word);
1242908d778SJames Bottomley 
asd_ddbsite_write_byte(struct asd_ha_struct * asd_ha,u16 ddb_site_no,u16 offs,u8 val)1252908d778SJames Bottomley static inline void asd_ddbsite_write_byte(struct asd_ha_struct *asd_ha,
1262908d778SJames Bottomley 					  u16 ddb_site_no,
1272908d778SJames Bottomley 					  u16 offs, u8 val)
1282908d778SJames Bottomley {
1292908d778SJames Bottomley 	u16 base = offs & ~1;
1302908d778SJames Bottomley 	u16 rval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
1312908d778SJames Bottomley 	if (offs & 1)
1322908d778SJames Bottomley 		rval = (val << 8) | (rval & 0xFF);
1332908d778SJames Bottomley 	else
1342908d778SJames Bottomley 		rval = (rval & 0xFF00) | val;
1352908d778SJames Bottomley 	asd_ddbsite_write_word(asd_ha, ddb_site_no, base, rval);
1362908d778SJames Bottomley }
1372908d778SJames Bottomley 
1382908d778SJames Bottomley 
1392908d778SJames Bottomley #define ASD_SCBSITE_READ(type, ord)                                        \
1402908d778SJames Bottomley static inline type asd_scbsite_read_##ord (struct asd_ha_struct *asd_ha,   \
1412908d778SJames Bottomley 					   u16 scb_site_no,                \
1422908d778SJames Bottomley 					   u16 offs)                       \
1432908d778SJames Bottomley {                                                                          \
1442908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs);          \
1452908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no);                  \
1462908d778SJames Bottomley 	return asd_read_reg_##ord (asd_ha, CTXACCESS);                     \
1472908d778SJames Bottomley }
1482908d778SJames Bottomley 
1492908d778SJames Bottomley ASD_SCBSITE_READ(u32, dword);
1502908d778SJames Bottomley ASD_SCBSITE_READ(u16, word);
1512908d778SJames Bottomley 
asd_scbsite_read_byte(struct asd_ha_struct * asd_ha,u16 scb_site_no,u16 offs)1522908d778SJames Bottomley static inline u8 asd_scbsite_read_byte(struct asd_ha_struct *asd_ha,
1532908d778SJames Bottomley 				       u16 scb_site_no,
1542908d778SJames Bottomley 				       u16 offs)
1552908d778SJames Bottomley {
1562908d778SJames Bottomley 	if (offs & 1)
1572908d778SJames Bottomley 		return asd_scbsite_read_word(asd_ha, scb_site_no,
1582908d778SJames Bottomley 					     offs & ~1) >> 8;
1592908d778SJames Bottomley 	else
1602908d778SJames Bottomley 		return asd_scbsite_read_word(asd_ha, scb_site_no,
1612908d778SJames Bottomley 					     offs) & 0xFF;
1622908d778SJames Bottomley }
1632908d778SJames Bottomley 
1642908d778SJames Bottomley 
1652908d778SJames Bottomley #define ASD_SCBSITE_WRITE(type, ord)                                       \
1662908d778SJames Bottomley static inline void asd_scbsite_write_##ord (struct asd_ha_struct *asd_ha,  \
1672908d778SJames Bottomley 					u16 scb_site_no,                   \
1682908d778SJames Bottomley 					u16 offs, type val)                \
1692908d778SJames Bottomley {                                                                          \
1702908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ALTCIOADR, MnSCB_SITE + offs);          \
1712908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ASCBPTR, scb_site_no);                  \
1722908d778SJames Bottomley 	asd_write_reg_##ord (asd_ha, CTXACCESS, val);                      \
1732908d778SJames Bottomley }
1742908d778SJames Bottomley 
1752908d778SJames Bottomley ASD_SCBSITE_WRITE(u32, dword);
1762908d778SJames Bottomley ASD_SCBSITE_WRITE(u16, word);
1772908d778SJames Bottomley 
asd_scbsite_write_byte(struct asd_ha_struct * asd_ha,u16 scb_site_no,u16 offs,u8 val)1782908d778SJames Bottomley static inline void asd_scbsite_write_byte(struct asd_ha_struct *asd_ha,
1792908d778SJames Bottomley 					  u16 scb_site_no,
1802908d778SJames Bottomley 					  u16 offs, u8 val)
1812908d778SJames Bottomley {
1822908d778SJames Bottomley 	u16 base = offs & ~1;
1832908d778SJames Bottomley 	u16 rval = asd_scbsite_read_word(asd_ha, scb_site_no, base);
1842908d778SJames Bottomley 	if (offs & 1)
1852908d778SJames Bottomley 		rval = (val << 8) | (rval & 0xFF);
1862908d778SJames Bottomley 	else
1872908d778SJames Bottomley 		rval = (rval & 0xFF00) | val;
1882908d778SJames Bottomley 	asd_scbsite_write_word(asd_ha, scb_site_no, base, rval);
1892908d778SJames Bottomley }
1902908d778SJames Bottomley 
1912908d778SJames Bottomley /**
1922908d778SJames Bottomley  * asd_ddbsite_update_word -- atomically update a word in a ddb site
1932908d778SJames Bottomley  * @asd_ha: pointer to host adapter structure
1942908d778SJames Bottomley  * @ddb_site_no: the DDB site number
1952908d778SJames Bottomley  * @offs: the offset into the DDB
1962908d778SJames Bottomley  * @oldval: old value found in that offset
1972908d778SJames Bottomley  * @newval: the new value to replace it
1982908d778SJames Bottomley  *
1992908d778SJames Bottomley  * This function is used when the sequencers are running and we need to
2002908d778SJames Bottomley  * update a DDB site atomically without expensive pausing and upausing
2012908d778SJames Bottomley  * of the sequencers and accessing the DDB site through the CIO bus.
2022908d778SJames Bottomley  *
2032908d778SJames Bottomley  * Return 0 on success; -EFAULT on parity error; -EAGAIN if the old value
2042908d778SJames Bottomley  * is different than the current value at that offset.
2052908d778SJames Bottomley  */
asd_ddbsite_update_word(struct asd_ha_struct * asd_ha,u16 ddb_site_no,u16 offs,u16 oldval,u16 newval)2062908d778SJames Bottomley static inline int asd_ddbsite_update_word(struct asd_ha_struct *asd_ha,
2072908d778SJames Bottomley 					  u16 ddb_site_no, u16 offs,
2082908d778SJames Bottomley 					  u16 oldval, u16 newval)
2092908d778SJames Bottomley {
2102908d778SJames Bottomley 	u8  done;
2112908d778SJames Bottomley 	u16 oval = asd_ddbsite_read_word(asd_ha, ddb_site_no, offs);
2122908d778SJames Bottomley 	if (oval != oldval)
2132908d778SJames Bottomley 		return -EAGAIN;
2142908d778SJames Bottomley 	asd_write_reg_word(asd_ha, AOLDDATA, oldval);
2152908d778SJames Bottomley 	asd_write_reg_word(asd_ha, ANEWDATA, newval);
2162908d778SJames Bottomley 	do {
2172908d778SJames Bottomley 		done = asd_read_reg_byte(asd_ha, ATOMICSTATCTL);
2182908d778SJames Bottomley 	} while (!(done & ATOMICDONE));
2192908d778SJames Bottomley 	if (done & ATOMICERR)
2202908d778SJames Bottomley 		return -EFAULT;	  /* parity error */
2212908d778SJames Bottomley 	else if (done & ATOMICWIN)
2222908d778SJames Bottomley 		return 0;	  /* success */
2232908d778SJames Bottomley 	else
2242908d778SJames Bottomley 		return -EAGAIN;	  /* oldval different than current value */
2252908d778SJames Bottomley }
2262908d778SJames Bottomley 
asd_ddbsite_update_byte(struct asd_ha_struct * asd_ha,u16 ddb_site_no,u16 offs,u8 _oldval,u8 _newval)2272908d778SJames Bottomley static inline int asd_ddbsite_update_byte(struct asd_ha_struct *asd_ha,
2282908d778SJames Bottomley 					  u16 ddb_site_no, u16 offs,
2292908d778SJames Bottomley 					  u8 _oldval, u8 _newval)
2302908d778SJames Bottomley {
2312908d778SJames Bottomley 	u16 base = offs & ~1;
2322908d778SJames Bottomley 	u16 oval;
2332908d778SJames Bottomley 	u16 nval = asd_ddbsite_read_word(asd_ha, ddb_site_no, base);
2342908d778SJames Bottomley 	if (offs & 1) {
2352908d778SJames Bottomley 		if ((nval >> 8) != _oldval)
2362908d778SJames Bottomley 			return -EAGAIN;
2372908d778SJames Bottomley 		nval = (_newval << 8) | (nval & 0xFF);
2382908d778SJames Bottomley 		oval = (_oldval << 8) | (nval & 0xFF);
2392908d778SJames Bottomley 	} else {
2402908d778SJames Bottomley 		if ((nval & 0xFF) != _oldval)
2412908d778SJames Bottomley 			return -EAGAIN;
2422908d778SJames Bottomley 		nval = (nval & 0xFF00) | _newval;
2432908d778SJames Bottomley 		oval = (nval & 0xFF00) | _oldval;
2442908d778SJames Bottomley 	}
2452908d778SJames Bottomley 	return asd_ddbsite_update_word(asd_ha, ddb_site_no, base, oval, nval);
2462908d778SJames Bottomley }
2472908d778SJames Bottomley 
asd_write_reg_addr(struct asd_ha_struct * asd_ha,u32 reg,dma_addr_t dma_handle)2482908d778SJames Bottomley static inline void asd_write_reg_addr(struct asd_ha_struct *asd_ha, u32 reg,
2492908d778SJames Bottomley 				      dma_addr_t dma_handle)
2502908d778SJames Bottomley {
2512908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, reg,   ASD_BUSADDR_LO(dma_handle));
2522908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, reg+4, ASD_BUSADDR_HI(dma_handle));
2532908d778SJames Bottomley }
2542908d778SJames Bottomley 
asd_get_cmdctx_size(struct asd_ha_struct * asd_ha)2552908d778SJames Bottomley static inline u32 asd_get_cmdctx_size(struct asd_ha_struct *asd_ha)
2562908d778SJames Bottomley {
2572908d778SJames Bottomley 	/* DCHREVISION returns 0, possibly broken */
2582908d778SJames Bottomley 	u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
2592908d778SJames Bottomley 	return ctxmemsize ? 65536 : 32768;
2602908d778SJames Bottomley }
2612908d778SJames Bottomley 
asd_get_devctx_size(struct asd_ha_struct * asd_ha)2622908d778SJames Bottomley static inline u32 asd_get_devctx_size(struct asd_ha_struct *asd_ha)
2632908d778SJames Bottomley {
2642908d778SJames Bottomley 	u32 ctxmemsize = asd_read_reg_dword(asd_ha, LmMnINT(0,0)) & CTXMEMSIZE;
2652908d778SJames Bottomley 	return ctxmemsize ? 8192 : 4096;
2662908d778SJames Bottomley }
2672908d778SJames Bottomley 
asd_disable_ints(struct asd_ha_struct * asd_ha)2682908d778SJames Bottomley static inline void asd_disable_ints(struct asd_ha_struct *asd_ha)
2692908d778SJames Bottomley {
2702908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, CHIMINTEN, RST_CHIMINTEN);
2712908d778SJames Bottomley }
2722908d778SJames Bottomley 
asd_enable_ints(struct asd_ha_struct * asd_ha)2732908d778SJames Bottomley static inline void asd_enable_ints(struct asd_ha_struct *asd_ha)
2742908d778SJames Bottomley {
2752908d778SJames Bottomley 	/* Enable COM SAS interrupt on errors, COMSTAT */
2762908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, COMSTATEN,
2772908d778SJames Bottomley 			    EN_CSBUFPERR | EN_CSERR | EN_OVLYERR);
2782908d778SJames Bottomley 	/* Enable DCH SAS CFIFTOERR */
2792908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, DCHSTATUS, EN_CFIFTOERR);
2802908d778SJames Bottomley 	/* Enable Host Device interrupts */
2812908d778SJames Bottomley 	asd_write_reg_dword(asd_ha, CHIMINTEN, SET_CHIMINTEN);
2822908d778SJames Bottomley }
2832908d778SJames Bottomley 
2842908d778SJames Bottomley #endif
285