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