si3124reg.h revision 8d483882aa3390058094b043f3d62187b5d1de03
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SI3124REG_H
#define _SI3124REG_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(1)
typedef struct si_sge {
/* offset 0x00 */
union {
uint64_t _sge_addr_ll;
uint32_t _sge_addr_la[2];
} _sge_addr_un;
#define sge_addr_low _sge_addr_un._sge_addr_la[0]
#define sge_addr_high _sge_addr_un._sge_addr_la[1]
#define sge_addr _sge_addr_un._sge_addr_ll
/* offset 0x08 */
uint32_t sge_data_count;
/* offset 0x0c */
uint32_t sge_trm_lnk_drd_xcf_rsvd;
#define SET_SGE_LNK(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x40000000)
#define SET_SGE_TRM(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x80000000)
#define IS_SGE_TRM_SET(sge) (sge.sge_trm_lnk_drd_xcf_rsvd & 0x80000000)
} si_sge_t;
/* Scatter Gather Table consists of four SGE entries */
typedef struct si_sgt {
si_sge_t sgt_sge[4];
} si_sgt_t;
/* Register - Host to Device FIS (from SATA spec) */
typedef struct fis_reg_h2d {
/* offset 0x00 */
uint32_t fish_type_pmp_rsvd_cmddevctl_cmd_features;
#define SET_FIS_TYPE(fis, type) \
(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff))
#define SET_FIS_PMP(fis, pmp) \
(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= ((pmp & 0xf) << 8))
#define SET_FIS_CDMDEVCTL(fis, cmddevctl) \
(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \
((cmddevctl & 0x1) << 15))
#define SET_FIS_COMMAND(fis, command) \
(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \
((command & 0xff) << 16))
#define GET_FIS_COMMAND(fis) \
((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff)
#define SET_FIS_FEATURES(fis, features) \
(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \
((features & 0xff) << 24))
#define GET_FIS_FEATURES(fis) \
((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff)
/* offset 0x04 */
uint32_t fish_sector_cyllow_cylhi_devhead;
#define SET_FIS_SECTOR(fis, sector) \
(fis.fish_sector_cyllow_cylhi_devhead |= ((sector & 0xff)))
#define GET_FIS_SECTOR(fis) \
(fis.fish_sector_cyllow_cylhi_devhead & 0xff)
#define SET_FIS_CYL_LOW(fis, cyl_low) \
(fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8))
#define GET_FIS_CYL_LOW(fis) \
((fis.fish_sector_cyllow_cylhi_devhead >> 8) & 0xff)
#define SET_FIS_CYL_HI(fis, cyl_hi) \
(fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16))
#define GET_FIS_CYL_HI(fis) \
((fis.fish_sector_cyllow_cylhi_devhead >> 16) & 0xff)
#define SET_FIS_DEV_HEAD(fis, dev_head) \
(fis.fish_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24))
#define GET_FIS_DEV_HEAD(fis) \
((fis.fish_sector_cyllow_cylhi_devhead >> 24) & 0xff)
/* offset 0x08 */
uint32_t fish_sectexp_cyllowexp_cylhiexp_featuresexp;
#define SET_FIS_SECTOR_EXP(fis, sectorexp) \
(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \
((sectorexp & 0xff)))
#define GET_FIS_SECTOR_EXP(fis) \
(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp & 0xff)
#define SET_FIS_CYL_LOW_EXP(fis, cyllowexp) \
(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \
((cyllowexp & 0xff) << 8))
#define GET_FIS_CYL_LOW_EXP(fis) \
((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff)
#define SET_FIS_CYL_HI_EXP(fis, cylhiexp) \
(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \
((cylhiexp & 0xff) << 16))
#define GET_FIS_CYL_HI_EXP(fis) \
((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff)
#define SET_FIS_FEATURES_EXP(fis, features_exp) \
(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \
((features_exp & 0xff) << 24))
/* offset 0x0c */
uint32_t fish_sectcount_sectcountexp_rsvd_devctl;
#define SET_FIS_SECTOR_COUNT(fis, sector_count) \
(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((sector_count & 0xff)))
#define GET_FIS_SECTOR_COUNT(fis) \
(fis.fish_sectcount_sectcountexp_rsvd_devctl & 0xff)
#define SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp) \
(fis.fish_sectcount_sectcountexp_rsvd_devctl |= \
((sector_count_exp & 0xff) << 8))
#define GET_FIS_SECTOR_COUNT_EXP(fis) \
((fis.fish_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff)
#define SET_FIS_SECTOR_DEVCTL(fis, devctl) \
(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((devctl & 0xff) << 24))
/* offset 0x10 */
uint32_t fish_rsvd3; /* should be zero */
} fis_reg_h2d_t;
/*
* Port Request Block
*/
typedef struct si_prb {
/* offset 0x00 */
uint32_t prb_control_override;
#define SET_PRB_CONTROL_PKT_READ(prb) \
(prb->prb_control_override |= (0x1 << 4))
#define SET_PRB_CONTROL_PKT_WRITE(prb) \
(prb->prb_control_override |= (0x1 << 5))
#define SET_PRB_CONTROL_SOFT_RESET(prb) \
(prb->prb_control_override |= (0x1 << 7))
/* offset 0x04 */
uint32_t prb_received_count;
/* offset 0x08 */
fis_reg_h2d_t prb_fis; /* this is of 0x14 bytes size */
/* offset 0x1c */
uint32_t prb_rsvd3;
/* offset 0x20 */
si_sge_t prb_sge0;
/* offset 0x30 */
si_sge_t prb_sge1;
} si_prb_t;
#pragma pack()
/* Various interrupt bits */
#define INTR_COMMAND_COMPLETE (0x1 << 0)
#define INTR_COMMAND_ERROR (0x1 << 1)
#define INTR_PORT_READY (0x1 << 2)
#define INTR_POWER_CHANGE (0x1 << 3)
#define INTR_PHYRDY_CHANGE (0x1 << 4)
#define INTR_COMWAKE_RECEIVED (0x1 << 5)
#define INTR_UNRECOG_FIS (0x1 << 6)
#define INTR_DEV_XCHANGED (0x1 << 7)
#define INTR_8B10B_DECODE_ERROR (0x1 << 8)
#define INTR_CRC_ERROR (0x1 << 9)
#define INTR_HANDSHAKE_ERROR (0x1 << 10)
#define INTR_SETDEVBITS_NOTIFY (0x1 << 11)
#define INTR_MASK (0xfff)
/* Device signatures */
#define SI_SIGNATURE_PORT_MULTIPLIER 0x96690101
#define SI_SIGNATURE_ATAPI 0xeb140101
#define SI_SIGNATURE_DISK 0x00000101
/* Global definitions */
#define GLOBAL_OFFSET(si_ctlp) (si_ctlp->sictl_global_addr)
#define GLOBAL_CONTROL_REG(si_ctlp) (GLOBAL_OFFSET(si_ctlp)+0x40)
#define GLOBAL_INTERRUPT_STATUS(si_ctlp) (GLOBAL_OFFSET(si_ctlp)+0x44)
/* Per port definitions */
#define PORT_OFFSET(si_ctlp, port) (si_ctlp->sictl_port_addr + port*0x2000)
#define PORT_LRAM(si_ctlp, port, slot) \
(PORT_OFFSET(si_ctlp, port) + 0x0 + slot*0x80)
#define PORT_CONTROL_SET(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1000)
#define PORT_STATUS(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1000)
#define PORT_CONTROL_CLEAR(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1004)
#define PORT_INTERRUPT_STATUS(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1008)
#define PORT_INTERRUPT_ENABLE_SET(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1010)
#define PORT_INTERRUPT_ENABLE_CLEAR(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1014)
#define PORT_COMMAND_ERROR(si_ctlp, port) \
(PORT_OFFSET(si_ctlp, port) + 0x1024)
#define PORT_SLOT_STATUS(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1800)
#define PORT_SCONTROL(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f00)
#define PORT_SSTATUS(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f04)
#define PORT_SERROR(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f08)
#define PORT_SACTIVE(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f0c)
#define PORT_COMMAND_ACTIVATION(si_ctlp, port, slot) \
(PORT_OFFSET(si_ctlp, port) + 0x1c00 + slot*0x8)
#define PORT_SIGNATURE_MSB(si_ctlp, port, slot) \
(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x0c)
#define PORT_SIGNATURE_LSB(si_ctlp, port, slot) \
(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x14)
/* Interesting bits of Port Control Set register */
#define PORT_CONTROL_SET_BITS_PORT_RESET 0x1
#define PORT_CONTROL_SET_BITS_DEV_RESET 0x2
#define PORT_CONTROL_SET_BITS_PORT_INITIALIZE 0x4
#define PORT_CONTROL_SET_BITS_PACKET_LEN 0x20
#define PORT_CONTROL_SET_BITS_RESUME 0x40
#define PORT_CONTROL_SET_BITS_PM_ENABLE 0x2000
/* Interesting bits of Port Control Clear register */
#define PORT_CONTROL_CLEAR_BITS_PORT_RESET 0x1
#define PORT_CONTROL_CLEAR_BITS_INTR_NCoR 0x8
#define PORT_CONTROL_CLEAR_BITS_PACKET_LEN 0x20
#define PORT_CONTROL_CLEAR_BITS_RESUME 0x40
/* Interesting bits of Port Status register */
#define PORT_STATUS_BITS_PORT_READY 0x80000000
/* Interesting bits of Global Control register */
#define GLOBAL_CONTROL_REG_BITS_CLEAR 0x00000000
#define POST_PRB_ADDR(si_ctlp, si_portp, port, slot) \
(void) ddi_dma_sync(si_portp->siport_prbpool_dma_handle, \
slot * sizeof (si_prb_t), \
sizeof (si_prb_t), \
DDI_DMA_SYNC_FORDEV); \
\
(void) ddi_dma_sync(si_portp->siport_sgbpool_dma_handle, \
slot * sizeof (si_sgblock_t), \
sizeof (si_sgblock_t), \
DDI_DMA_SYNC_FORDEV); \
\
ddi_put64(si_ctlp->sictl_port_acc_handle, \
(uint64_t *)PORT_COMMAND_ACTIVATION(si_ctlp, port, slot), \
(uint64_t)(si_portp->siport_prbpool_physaddr + \
slot*sizeof (si_prb_t)));
#define SI_SLOT_MASK 0x7fffffff
#define SI_NUM_SLOTS 0x1f /* 31 */
#define ATTENTION_BIT 0x80000000
#define IS_ATTENTION_RAISED(slot_status) (slot_status & ATTENTION_BIT)
#define SI3124_DEV_ID 0x3124
#define SI3132_DEV_ID 0x3132
#define PM_CSR(devid) ((devid == SI3124_DEV_ID) ? 0x68 : 0x58)
#define REGISTER_FIS_H2D 0x27
#define SI31xx_INTR_PORT_MASK 0xf
/* PCI BAR registers */
#define PCI_BAR0 1 /* Contains global register set */
#define PCI_BAR1 2 /* Contains port register set */
/* Port Status and Control Registers (from port multiplier spec) */
#define PSCR_REG0 0
#define PSCR_REG1 1
#define PSCR_REG2 2
#define PSCR_REG3 3
/* SStatus bit fields */
#define SSTATUS_DET_MASK 0x0000000f
#define SSTATUS_SPD_MASK 0x000000f0
#define SSTATUS_SPD_SHIFT 4
#define SSTATUS_IPM_MASK 0x00000f00
#define SSTATUS_IPM_SHIFT 8
#define SSTATUS_DET_NODEV_NOPHY 0x0 /* No device, no PHY */
#define SSTATUS_DET_DEVPRESENT_NOPHY 0x1 /* Dev present, no PHY */
#define SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* Dev present, PHY online */
#define SSTATUS_IPM_NODEV_NOPHY 0x0 /* No dev, no PHY */
#define SSTATUS_IPM_INTERFACE_ACTIVE 0x1 /* Interface active */
#define SSTATUS_IPM_INTERFACE_POWERPARTIAL 0x2 /* partial power mgmnt */
#define SSTATUS_IPM_INTERFACE_POWERSLUMBER 0x6 /* slumber power mgmt */
/* SControl bit fields */
#define SCONTROL_DET_MASK 0x0000000f
/* Command Error codes */
#define CMD_ERR_DEVICEERRROR 1
#define CMD_ERR_SDBERROR 2
#define CMD_ERR_DATAFISERROR 3
#define CMD_ERR_SENDFISERROR 4
#define CMD_ERR_INCONSISTENTSTATE 5
#define CMD_ERR_DIRECTIONERROR 6
#define CMD_ERR_UNDERRUNERROR 7
#define CMD_ERR_OVERRUNERROR 8
#define CMD_ERR_PACKETPROTOCOLERROR 11
#define CMD_ERR_PLDSGTERRORBOUNDARY 16
#define CMD_ERR_PLDSGTERRORTARETABORT 17
#define CMD_ERR_PLDSGTERRORMASTERABORT 18
#define CMD_ERR_PLDSGTERRORPCIERR 19
#define CMD_ERR_PLDCMDERRORBOUNDARY 24
#define CMD_ERR_PLDCMDERRORTARGETABORT 25
#define CMD_ERR_PLDCMDERRORMASTERABORT 26
#define CMD_ERR_PLDCMDERORPCIERR 27
#define CMD_ERR_PSDERRORTARGETABORT 33
#define CMD_ERR_PSDERRORMASTERABORT 34
#define CMD_ERR_PSDERRORPCIERR 35
#define CMD_ERR_SENDSERVICEERROR 36
#ifdef __cplusplus
}
#endif
#endif /* _SI3124REG_H */