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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SI3124REG_H 28 #define _SI3124REG_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #pragma pack(1) 37 38 typedef struct si_sge { 39 /* offset 0x00 */ 40 union { 41 uint64_t _sge_addr_ll; 42 uint32_t _sge_addr_la[2]; 43 } _sge_addr_un; 44 45 #define sge_addr_low _sge_addr_un._sge_addr_la[0] 46 #define sge_addr_high _sge_addr_un._sge_addr_la[1] 47 #define sge_addr _sge_addr_un._sge_addr_ll 48 49 /* offset 0x08 */ 50 uint32_t sge_data_count; 51 52 /* offset 0x0c */ 53 uint32_t sge_trm_lnk_drd_xcf_rsvd; 54 55 #define SET_SGE_LNK(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x40000000) 56 #define SET_SGE_TRM(sge) (sge.sge_trm_lnk_drd_xcf_rsvd = 0x80000000) 57 #define IS_SGE_TRM_SET(sge) (sge.sge_trm_lnk_drd_xcf_rsvd & 0x80000000) 58 59 } si_sge_t; 60 61 /* Scatter Gather Table consists of four SGE entries */ 62 typedef struct si_sgt { 63 si_sge_t sgt_sge[4]; 64 } si_sgt_t; 65 66 67 /* Register - Host to Device FIS (from SATA spec) */ 68 typedef struct fis_reg_h2d { 69 /* offset 0x00 */ 70 uint32_t fish_type_pmp_rsvd_cmddevctl_cmd_features; 71 72 #define SET_FIS_TYPE(fis, type) \ 73 (fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff)) 74 75 #define SET_FIS_PMP(fis, pmp) \ 76 (fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= ((pmp & 0xf) << 8)) 77 78 #define SET_FIS_CDMDEVCTL(fis, cmddevctl) \ 79 (fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 80 ((cmddevctl & 0x1) << 15)) 81 82 #define SET_FIS_COMMAND(fis, command) \ 83 (fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 84 ((command & 0xff) << 16)) 85 86 #define GET_FIS_COMMAND(fis) \ 87 ((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff) 88 89 #define SET_FIS_FEATURES(fis, features) \ 90 (fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= \ 91 ((features & 0xff) << 24)) 92 93 #define GET_FIS_FEATURES(fis) \ 94 ((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff) 95 96 /* offset 0x04 */ 97 uint32_t fish_sector_cyllow_cylhi_devhead; 98 99 #define SET_FIS_SECTOR(fis, sector) \ 100 (fis.fish_sector_cyllow_cylhi_devhead |= ((sector & 0xff))) 101 102 #define GET_FIS_SECTOR(fis) \ 103 (fis.fish_sector_cyllow_cylhi_devhead & 0xff) 104 105 #define SET_FIS_CYL_LOW(fis, cyl_low) \ 106 (fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8)) 107 108 #define GET_FIS_CYL_LOW(fis) \ 109 ((fis.fish_sector_cyllow_cylhi_devhead >> 8) & 0xff) 110 111 #define SET_FIS_CYL_HI(fis, cyl_hi) \ 112 (fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16)) 113 114 #define GET_FIS_CYL_HI(fis) \ 115 ((fis.fish_sector_cyllow_cylhi_devhead >> 16) & 0xff) 116 117 #define SET_FIS_DEV_HEAD(fis, dev_head) \ 118 (fis.fish_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24)) 119 120 #define GET_FIS_DEV_HEAD(fis) \ 121 ((fis.fish_sector_cyllow_cylhi_devhead >> 24) & 0xff) 122 123 124 /* offset 0x08 */ 125 uint32_t fish_sectexp_cyllowexp_cylhiexp_featuresexp; 126 127 #define SET_FIS_SECTOR_EXP(fis, sectorexp) \ 128 (fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 129 ((sectorexp & 0xff))) 130 131 #define GET_FIS_SECTOR_EXP(fis) \ 132 (fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp & 0xff) 133 134 #define SET_FIS_CYL_LOW_EXP(fis, cyllowexp) \ 135 (fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 136 ((cyllowexp & 0xff) << 8)) 137 138 #define GET_FIS_CYL_LOW_EXP(fis) \ 139 ((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff) 140 141 #define SET_FIS_CYL_HI_EXP(fis, cylhiexp) \ 142 (fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 143 ((cylhiexp & 0xff) << 16)) 144 145 #define GET_FIS_CYL_HI_EXP(fis) \ 146 ((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff) 147 148 #define SET_FIS_FEATURES_EXP(fis, features_exp) \ 149 (fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= \ 150 ((features_exp & 0xff) << 24)) 151 152 /* offset 0x0c */ 153 uint32_t fish_sectcount_sectcountexp_rsvd_devctl; 154 155 #define SET_FIS_SECTOR_COUNT(fis, sector_count) \ 156 (fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((sector_count & 0xff))) 157 158 #define GET_FIS_SECTOR_COUNT(fis) \ 159 (fis.fish_sectcount_sectcountexp_rsvd_devctl & 0xff) 160 161 #define SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp) \ 162 (fis.fish_sectcount_sectcountexp_rsvd_devctl |= \ 163 ((sector_count_exp & 0xff) << 8)) 164 165 #define GET_FIS_SECTOR_COUNT_EXP(fis) \ 166 ((fis.fish_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff) 167 168 #define SET_FIS_SECTOR_DEVCTL(fis, devctl) \ 169 (fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((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), \ 301 sizeof (si_sgblock_t), \ 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 3124 316 #define SI3132_DEV_ID 3132 317 318 #define PM_CSR(devid) ((devid == SI3124_DEV_ID) ? 0x68 : 0x58) 319 320 #define REGISTER_FIS_H2D 0x27 321 322 #define SI31xx_INTR_PORT_MASK 0xf 323 324 /* PCI BAR registers */ 325 #define PCI_BAR0 1 /* Contains global register set */ 326 #define PCI_BAR1 2 /* Contains port register set */ 327 328 /* Port Status and Control Registers (from port multiplier spec) */ 329 #define PSCR_REG0 0 330 #define PSCR_REG1 1 331 #define PSCR_REG2 2 332 #define PSCR_REG3 3 333 334 /* SStatus bit fields */ 335 #define SSTATUS_DET_MASK 0x0000000f 336 #define SSTATUS_SPD_MASK 0x000000f0 337 #define SSTATUS_SPD_SHIFT 4 338 #define SSTATUS_IPM_MASK 0x00000f00 339 #define SSTATUS_IPM_SHIFT 8 340 341 #define SSTATUS_GET_DET(x) \ 342 (x & SSTATUS_DET_MASK) 343 344 #define SSTATUS_SET_DET(x, new_val) \ 345 (x = (x & ~SSTATUS_DET_MASK) | (new_val & SSTATUS_DET_MASK)) 346 347 #define SSTATUS_DET_NODEV_NOPHY 0x0 /* No device, no PHY */ 348 #define SSTATUS_DET_DEVPRESENT_NOPHY 0x1 /* Dev present, no PHY */ 349 #define SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* Dev present, PHY online */ 350 #define SSTATUS_DET_PHYOFFLINE 0x4 /* PHY offline */ 351 352 #define SSTATUS_GET_IPM(x) \ 353 ((x & SSTATUS_IPM_MASK) >> SSTATUS_IPM_SHIFT) 354 355 #define SSTATUS_SET_IPM(x, new_val) \ 356 (x = (x & ~SSTATUS_IPM_MASK) | \ 357 ((new_val << SSTATUS_IPM_SHIFT) & SSTATUS_IPM_MASK)) 358 359 #define SSTATUS_IPM_NODEV_NOPHY 0x0 /* No dev, no PHY */ 360 #define SSTATUS_IPM_INTERFACE_ACTIVE 0x1 /* Interface active */ 361 #define SSTATUS_IPM_INTERFACE_POWERPARTIAL 0x2 /* partial power mgmnt */ 362 #define SSTATUS_IPM_INTERFACE_POWERSLUMBER 0x6 /* slumber power mgmt */ 363 364 /* SControl bit fields */ 365 #define SCONTROL_DET_MASK 0x0000000f 366 367 #define SCONTROL_GET_DET(x) \ 368 (x & SCONTROL_DET_MASK) 369 370 #define SCONTROL_SET_DET(x, new_val) \ 371 (x = (x & ~SCONTROL_DET_MASK) | (new_val & SCONTROL_DET_MASK)) 372 373 #define SCONTROL_DET_NOACTION 0x0 /* No action requested */ 374 #define SCONTROL_DET_COMRESET 0x1 /* Send COMRESET */ 375 376 /* Command Error codes */ 377 #define CMD_ERR_DEVICEERRROR 1 378 #define CMD_ERR_SDBERROR 2 379 #define CMD_ERR_DATAFISERROR 3 380 #define CMD_ERR_SENDFISERROR 4 381 #define CMD_ERR_INCONSISTENTSTATE 5 382 #define CMD_ERR_DIRECTIONERROR 6 383 #define CMD_ERR_UNDERRUNERROR 7 384 #define CMD_ERR_OVERRUNERROR 8 385 #define CMD_ERR_PACKETPROTOCOLERROR 11 386 #define CMD_ERR_PLDSGTERRORBOUNDARY 16 387 #define CMD_ERR_PLDSGTERRORTARETABORT 17 388 #define CMD_ERR_PLDSGTERRORMASTERABORT 18 389 #define CMD_ERR_PLDSGTERRORPCIERR 19 390 #define CMD_ERR_PLDCMDERRORBOUNDARY 24 391 #define CMD_ERR_PLDCMDERRORTARGETABORT 25 392 #define CMD_ERR_PLDCMDERRORMASTERABORT 26 393 #define CMD_ERR_PLDCMDERORPCIERR 27 394 #define CMD_ERR_PSDERRORTARGETABORT 33 395 #define CMD_ERR_PSDERRORMASTERABORT 34 396 #define CMD_ERR_PSDERRORPCIERR 35 397 #define CMD_ERR_SENDSERVICEERROR 36 398 399 #ifdef __cplusplus 400 } 401 #endif 402 403 #endif /* _SI3124REG_H */ 404