1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _SI3124REG_H 27 #define _SI3124REG_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #pragma pack(1) 34 35 typedef struct si_sge { 36 /* offset 0x00 */ 37 union { 38 uint64_t _sge_addr_ll; 39 uint32_t _sge_addr_la[2]; 40 } _sge_addr_un; 41 42 #define sge_addr_low _sge_addr_un._sge_addr_la[0] 43 #define sge_addr_high _sge_addr_un._sge_addr_la[1] 44 #define sge_addr _sge_addr_un._sge_addr_ll 45 46 /* offset 0x08 */ 47 uint32_t sge_data_count; 48 49 /* offset 0x0c */ 50 uint32_t sge_trm_lnk_drd_xcf_rsvd; 51 52 #define SET_SGE_LNK(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x40000000) 53 #define SET_SGE_TRM(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x80000000) 54 #define IS_SGE_TRM_SET(sge) (sge.sge_trm_lnk_drd_xcf_rsvd & 0x80000000) 55 56 } si_sge_t; 57 58 /* Scatter Gather Table consists of four SGE entries */ 59 typedef struct si_sgt { 60 si_sge_t sgt_sge[4]; 61 } si_sgt_t; 62 63 64 /* Register - Host to Device FIS (from SATA spec) */ 65 typedef struct fis_reg_h2d { 66 /* offset 0x00 */ 67 uint32_t fish_type_pmp_rsvd_cmddevctl_cmd_features; 68 69 #define SET_FIS_TYPE(fis, type) \ 70 ((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff)) 71 72 #define SET_FIS_PMP(fis, pmp) \ 73 ((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 74 ((pmp & 0xf) << 8)) 75 76 #define SET_FIS_CDMDEVCTL(fis, cmddevctl) \ 77 ((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 78 ((cmddevctl & 0x1) << 15)) 79 80 #define SET_FIS_COMMAND(fis, command) \ 81 ((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 82 ((command & 0xff) << 16)) 83 84 #define GET_FIS_COMMAND(fis) \ 85 (((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff) 86 87 #define SET_FIS_FEATURES(fis, features) \ 88 ((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 89 ((features & 0xff) << 24)) 90 91 #define GET_FIS_FEATURES(fis) \ 92 (((&fis)->fish_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff) 93 94 /* offset 0x04 */ 95 uint32_t fish_sector_cyllow_cylhi_devhead; 96 97 #define SET_FIS_SECTOR(fis, sector) \ 98 ((&fis)->fish_sector_cyllow_cylhi_devhead |= ((sector & 0xff))) 99 100 #define GET_FIS_SECTOR(fis) \ 101 ((&fis)->fish_sector_cyllow_cylhi_devhead & 0xff) 102 103 #define SET_FIS_CYL_LOW(fis, cyl_low) \ 104 ((&fis)->fish_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8)) 105 106 #define GET_FIS_CYL_LOW(fis) \ 107 (((&fis)->fish_sector_cyllow_cylhi_devhead >> 8) & 0xff) 108 109 #define SET_FIS_CYL_HI(fis, cyl_hi) \ 110 ((&fis)->fish_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16)) 111 112 #define GET_FIS_CYL_HI(fis) \ 113 (((&fis)->fish_sector_cyllow_cylhi_devhead >> 16) & 0xff) 114 115 #define SET_FIS_DEV_HEAD(fis, dev_head) \ 116 ((&fis)->fish_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24)) 117 118 #define GET_FIS_DEV_HEAD(fis) \ 119 (((&fis)->fish_sector_cyllow_cylhi_devhead >> 24) & 0xff) 120 121 122 /* offset 0x08 */ 123 uint32_t fish_sectexp_cyllowexp_cylhiexp_featuresexp; 124 125 #define SET_FIS_SECTOR_EXP(fis, sectorexp) \ 126 ((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 127 ((sectorexp & 0xff))) 128 129 #define GET_FIS_SECTOR_EXP(fis) \ 130 ((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp & 0xff) 131 132 #define SET_FIS_CYL_LOW_EXP(fis, cyllowexp) \ 133 ((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 134 ((cyllowexp & 0xff) << 8)) 135 136 #define GET_FIS_CYL_LOW_EXP(fis) \ 137 (((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff) 138 139 #define SET_FIS_CYL_HI_EXP(fis, cylhiexp) \ 140 ((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 141 ((cylhiexp & 0xff) << 16)) 142 143 #define GET_FIS_CYL_HI_EXP(fis) \ 144 (((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff) 145 146 #define SET_FIS_FEATURES_EXP(fis, features_exp) \ 147 ((&fis)->fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 148 ((features_exp & 0xff) << 24)) 149 150 /* offset 0x0c */ 151 uint32_t fish_sectcount_sectcountexp_rsvd_devctl; 152 153 #define SET_FIS_SECTOR_COUNT(fis, sector_count) \ 154 ((&fis)->fish_sectcount_sectcountexp_rsvd_devctl |= \ 155 ((sector_count & 0xff))) 156 157 #define GET_FIS_SECTOR_COUNT(fis) \ 158 ((&fis)->fish_sectcount_sectcountexp_rsvd_devctl & 0xff) 159 160 #define SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp) \ 161 ((&fis)->fish_sectcount_sectcountexp_rsvd_devctl |= \ 162 ((sector_count_exp & 0xff) << 8)) 163 164 #define GET_FIS_SECTOR_COUNT_EXP(fis) \ 165 (((&fis)->fish_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff) 166 167 #define SET_FIS_SECTOR_DEVCTL(fis, devctl) \ 168 ((&fis)->fish_sectcount_sectcountexp_rsvd_devctl |= \ 169 ((devctl & 0xff) << 24)) 170 171 /* offset 0x10 */ 172 uint32_t fish_rsvd3; /* should be zero */ 173 } fis_reg_h2d_t; 174 175 176 177 178 /* 179 * Port Request Block 180 */ 181 typedef struct si_prb { 182 /* offset 0x00 */ 183 uint32_t prb_control_override; 184 185 #define SET_PRB_CONTROL_PKT_READ(prb) \ 186 (prb->prb_control_override |= (0x1 << 4)) 187 188 #define SET_PRB_CONTROL_PKT_WRITE(prb) \ 189 (prb->prb_control_override |= (0x1 << 5)) 190 191 #define SET_PRB_CONTROL_SOFT_RESET(prb) \ 192 (prb->prb_control_override |= (0x1 << 7)) 193 194 /* offset 0x04 */ 195 uint32_t prb_received_count; 196 197 /* offset 0x08 */ 198 fis_reg_h2d_t prb_fis; /* this is of 0x14 bytes size */ 199 200 /* offset 0x1c */ 201 uint32_t prb_rsvd3; 202 203 /* offset 0x20 */ 204 si_sge_t prb_sge0; 205 206 /* offset 0x30 */ 207 si_sge_t prb_sge1; 208 209 } si_prb_t; 210 211 #pragma pack() 212 213 214 /* Various interrupt bits */ 215 #define INTR_COMMAND_COMPLETE (0x1 << 0) 216 #define INTR_COMMAND_ERROR (0x1 << 1) 217 #define INTR_PORT_READY (0x1 << 2) 218 #define INTR_POWER_CHANGE (0x1 << 3) 219 #define INTR_PHYRDY_CHANGE (0x1 << 4) 220 #define INTR_COMWAKE_RECEIVED (0x1 << 5) 221 #define INTR_UNRECOG_FIS (0x1 << 6) 222 #define INTR_DEV_XCHANGED (0x1 << 7) 223 #define INTR_8B10B_DECODE_ERROR (0x1 << 8) 224 #define INTR_CRC_ERROR (0x1 << 9) 225 #define INTR_HANDSHAKE_ERROR (0x1 << 10) 226 #define INTR_SETDEVBITS_NOTIFY (0x1 << 11) 227 #define INTR_MASK (0xfff) 228 229 /* Device signatures */ 230 #define SI_SIGNATURE_PORT_MULTIPLIER 0x96690101 231 #define SI_SIGNATURE_ATAPI 0xeb140101 232 #define SI_SIGNATURE_DISK 0x00000101 233 234 235 /* Global definitions */ 236 #define GLOBAL_OFFSET(si_ctlp) (si_ctlp->sictl_global_addr) 237 #define GLOBAL_CONTROL_REG(si_ctlp) (GLOBAL_OFFSET(si_ctlp)+0x40) 238 #define GLOBAL_INTERRUPT_STATUS(si_ctlp) (GLOBAL_OFFSET(si_ctlp)+0x44) 239 240 /* Per port definitions */ 241 #define PORT_OFFSET(si_ctlp, port) (si_ctlp->sictl_port_addr + port*0x2000) 242 #define PORT_LRAM(si_ctlp, port, slot) \ 243 (PORT_OFFSET(si_ctlp, port) + 0x0 + slot*0x80) 244 #define PORT_CONTROL_SET(si_ctlp, port) \ 245 (PORT_OFFSET(si_ctlp, port) + 0x1000) 246 #define PORT_STATUS(si_ctlp, port) \ 247 (PORT_OFFSET(si_ctlp, port) + 0x1000) 248 #define PORT_CONTROL_CLEAR(si_ctlp, port) \ 249 (PORT_OFFSET(si_ctlp, port) + 0x1004) 250 #define PORT_INTERRUPT_STATUS(si_ctlp, port) \ 251 (PORT_OFFSET(si_ctlp, port) + 0x1008) 252 #define PORT_INTERRUPT_ENABLE_SET(si_ctlp, port) \ 253 (PORT_OFFSET(si_ctlp, port) + 0x1010) 254 #define PORT_INTERRUPT_ENABLE_CLEAR(si_ctlp, port) \ 255 (PORT_OFFSET(si_ctlp, port) + 0x1014) 256 #define PORT_COMMAND_ERROR(si_ctlp, port) \ 257 (PORT_OFFSET(si_ctlp, port) + 0x1024) 258 #define PORT_SLOT_STATUS(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1800) 259 260 #define PORT_SCONTROL(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f00) 261 #define PORT_SSTATUS(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f04) 262 #define PORT_SERROR(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f08) 263 #define PORT_SACTIVE(si_ctlp, port) (PORT_OFFSET(si_ctlp, port) + 0x1f0c) 264 265 #define PORT_COMMAND_ACTIVATION(si_ctlp, port, slot) \ 266 (PORT_OFFSET(si_ctlp, port) + 0x1c00 + slot*0x8) 267 268 #define PORT_SIGNATURE_MSB(si_ctlp, port, slot) \ 269 (PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x0c) 270 #define PORT_SIGNATURE_LSB(si_ctlp, port, slot) \ 271 (PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x14) 272 273 /* Interesting bits of Port Control Set register */ 274 #define PORT_CONTROL_SET_BITS_PORT_RESET 0x1 275 #define PORT_CONTROL_SET_BITS_DEV_RESET 0x2 276 #define PORT_CONTROL_SET_BITS_PORT_INITIALIZE 0x4 277 #define PORT_CONTROL_SET_BITS_PACKET_LEN 0x20 278 #define PORT_CONTROL_SET_BITS_RESUME 0x40 279 #define PORT_CONTROL_SET_BITS_PM_ENABLE 0x2000 280 281 /* Interesting bits of Port Control Clear register */ 282 #define PORT_CONTROL_CLEAR_BITS_PORT_RESET 0x1 283 #define PORT_CONTROL_CLEAR_BITS_INTR_NCoR 0x8 284 #define PORT_CONTROL_CLEAR_BITS_PACKET_LEN 0x20 285 #define PORT_CONTROL_CLEAR_BITS_RESUME 0x40 286 287 /* Interesting bits of Port Status register */ 288 #define PORT_STATUS_BITS_PORT_READY 0x80000000 289 290 /* Interesting bits of Global Control register */ 291 #define GLOBAL_CONTROL_REG_BITS_CLEAR 0x00000000 292 293 #define POST_PRB_ADDR(si_ctlp, si_portp, port, slot) \ 294 (void) ddi_dma_sync(si_portp->siport_prbpool_dma_handle, \ 295 slot * sizeof (si_prb_t), \ 296 sizeof (si_prb_t), \ 297 DDI_DMA_SYNC_FORDEV); \ 298 \ 299 (void) ddi_dma_sync(si_portp->siport_sgbpool_dma_handle, \ 300 slot * sizeof (si_sgblock_t) * si_dma_sg_number, \ 301 sizeof (si_sgblock_t) * si_dma_sg_number, \ 302 DDI_DMA_SYNC_FORDEV); \ 303 \ 304 ddi_put64(si_ctlp->sictl_port_acc_handle, \ 305 (uint64_t *)PORT_COMMAND_ACTIVATION(si_ctlp, port, slot), \ 306 (uint64_t)(si_portp->siport_prbpool_physaddr + \ 307 slot*sizeof (si_prb_t))); 308 309 #define SI_SLOT_MASK 0x7fffffff 310 #define SI_NUM_SLOTS 0x1f /* 31 */ 311 312 #define ATTENTION_BIT 0x80000000 313 #define IS_ATTENTION_RAISED(slot_status) (slot_status & ATTENTION_BIT) 314 315 #define SI3124_DEV_ID 0x3124 316 #define SI3132_DEV_ID 0x3132 317 #define SI3531_DEV_ID 0x3531 318 319 #define PM_CSR(devid) ((devid == SI3124_DEV_ID) ? 0x68 : 0x58) 320 321 #define REGISTER_FIS_H2D 0x27 322 323 #define SI31xx_INTR_PORT_MASK 0xf 324 325 /* PCI BAR registers */ 326 #define PCI_BAR0 1 /* Contains global register set */ 327 #define PCI_BAR1 2 /* Contains port register set */ 328 329 /* Port Status and Control Registers (from port multiplier spec) */ 330 #define PSCR_REG0 0 331 #define PSCR_REG1 1 332 #define PSCR_REG2 2 333 #define PSCR_REG3 3 334 335 /* SStatus bit fields */ 336 #define SSTATUS_DET_MASK 0x0000000f 337 #define SSTATUS_SPD_MASK 0x000000f0 338 #define SSTATUS_SPD_SHIFT 4 339 #define SSTATUS_IPM_MASK 0x00000f00 340 #define SSTATUS_IPM_SHIFT 8 341 342 343 #define SSTATUS_DET_NODEV_NOPHY 0x0 /* No device, no PHY */ 344 #define SSTATUS_DET_DEVPRESENT_NOPHY 0x1 /* Dev present, no PHY */ 345 #define SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* Dev present, PHY online */ 346 347 #define SSTATUS_IPM_NODEV_NOPHY 0x0 /* No dev, no PHY */ 348 #define SSTATUS_IPM_INTERFACE_ACTIVE 0x1 /* Interface active */ 349 #define SSTATUS_IPM_INTERFACE_POWERPARTIAL 0x2 /* partial power mgmnt */ 350 #define SSTATUS_IPM_INTERFACE_POWERSLUMBER 0x6 /* slumber power mgmt */ 351 352 /* SControl bit fields */ 353 #define SCONTROL_DET_MASK 0x0000000f 354 355 356 357 358 /* Command Error codes */ 359 #define CMD_ERR_DEVICEERRROR 1 360 #define CMD_ERR_SDBERROR 2 361 #define CMD_ERR_DATAFISERROR 3 362 #define CMD_ERR_SENDFISERROR 4 363 #define CMD_ERR_INCONSISTENTSTATE 5 364 #define CMD_ERR_DIRECTIONERROR 6 365 #define CMD_ERR_UNDERRUNERROR 7 366 #define CMD_ERR_OVERRUNERROR 8 367 #define CMD_ERR_PACKETPROTOCOLERROR 11 368 #define CMD_ERR_PLDSGTERRORBOUNDARY 16 369 #define CMD_ERR_PLDSGTERRORTARETABORT 17 370 #define CMD_ERR_PLDSGTERRORMASTERABORT 18 371 #define CMD_ERR_PLDSGTERRORPCIERR 19 372 #define CMD_ERR_PLDCMDERRORBOUNDARY 24 373 #define CMD_ERR_PLDCMDERRORTARGETABORT 25 374 #define CMD_ERR_PLDCMDERRORMASTERABORT 26 375 #define CMD_ERR_PLDCMDERORPCIERR 27 376 #define CMD_ERR_PSDERRORTARGETABORT 33 377 #define CMD_ERR_PSDERRORMASTERABORT 34 378 #define CMD_ERR_PSDERRORPCIERR 35 379 #define CMD_ERR_SENDSERVICEERROR 36 380 381 #ifdef __cplusplus 382 } 383 #endif 384 385 #endif /* _SI3124REG_H */ 386