sata_vsc.c (11412B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * sata_vsc.c - Vitesse VSC7174 4 port DPA SATA 4 * 5 * Maintained by: Jeremy Higdon @ SGI 6 * Please ALWAYS copy linux-ide@vger.kernel.org 7 * on emails. 8 * 9 * Copyright 2004 SGI 10 * 11 * Bits from Jeff Garzik, Copyright RedHat, Inc. 12 * 13 * libata documentation is available via 'make {ps|pdf}docs', 14 * as Documentation/driver-api/libata.rst 15 * 16 * Vitesse hardware documentation presumably available under NDA. 17 * Intel 31244 (same hardware interface) documentation presumably 18 * available from http://developer.intel.com/ 19 */ 20 21#include <linux/kernel.h> 22#include <linux/module.h> 23#include <linux/pci.h> 24#include <linux/blkdev.h> 25#include <linux/delay.h> 26#include <linux/interrupt.h> 27#include <linux/dma-mapping.h> 28#include <linux/device.h> 29#include <scsi/scsi_host.h> 30#include <linux/libata.h> 31 32#define DRV_NAME "sata_vsc" 33#define DRV_VERSION "2.3" 34 35enum { 36 VSC_MMIO_BAR = 0, 37 38 /* Interrupt register offsets (from chip base address) */ 39 VSC_SATA_INT_STAT_OFFSET = 0x00, 40 VSC_SATA_INT_MASK_OFFSET = 0x04, 41 42 /* Taskfile registers offsets */ 43 VSC_SATA_TF_CMD_OFFSET = 0x00, 44 VSC_SATA_TF_DATA_OFFSET = 0x00, 45 VSC_SATA_TF_ERROR_OFFSET = 0x04, 46 VSC_SATA_TF_FEATURE_OFFSET = 0x06, 47 VSC_SATA_TF_NSECT_OFFSET = 0x08, 48 VSC_SATA_TF_LBAL_OFFSET = 0x0c, 49 VSC_SATA_TF_LBAM_OFFSET = 0x10, 50 VSC_SATA_TF_LBAH_OFFSET = 0x14, 51 VSC_SATA_TF_DEVICE_OFFSET = 0x18, 52 VSC_SATA_TF_STATUS_OFFSET = 0x1c, 53 VSC_SATA_TF_COMMAND_OFFSET = 0x1d, 54 VSC_SATA_TF_ALTSTATUS_OFFSET = 0x28, 55 VSC_SATA_TF_CTL_OFFSET = 0x29, 56 57 /* DMA base */ 58 VSC_SATA_UP_DESCRIPTOR_OFFSET = 0x64, 59 VSC_SATA_UP_DATA_BUFFER_OFFSET = 0x6C, 60 VSC_SATA_DMA_CMD_OFFSET = 0x70, 61 62 /* SCRs base */ 63 VSC_SATA_SCR_STATUS_OFFSET = 0x100, 64 VSC_SATA_SCR_ERROR_OFFSET = 0x104, 65 VSC_SATA_SCR_CONTROL_OFFSET = 0x108, 66 67 /* Port stride */ 68 VSC_SATA_PORT_OFFSET = 0x200, 69 70 /* Error interrupt status bit offsets */ 71 VSC_SATA_INT_ERROR_CRC = 0x40, 72 VSC_SATA_INT_ERROR_T = 0x20, 73 VSC_SATA_INT_ERROR_P = 0x10, 74 VSC_SATA_INT_ERROR_R = 0x8, 75 VSC_SATA_INT_ERROR_E = 0x4, 76 VSC_SATA_INT_ERROR_M = 0x2, 77 VSC_SATA_INT_PHY_CHANGE = 0x1, 78 VSC_SATA_INT_ERROR = (VSC_SATA_INT_ERROR_CRC | VSC_SATA_INT_ERROR_T | \ 79 VSC_SATA_INT_ERROR_P | VSC_SATA_INT_ERROR_R | \ 80 VSC_SATA_INT_ERROR_E | VSC_SATA_INT_ERROR_M | \ 81 VSC_SATA_INT_PHY_CHANGE), 82}; 83 84static int vsc_sata_scr_read(struct ata_link *link, 85 unsigned int sc_reg, u32 *val) 86{ 87 if (sc_reg > SCR_CONTROL) 88 return -EINVAL; 89 *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4)); 90 return 0; 91} 92 93 94static int vsc_sata_scr_write(struct ata_link *link, 95 unsigned int sc_reg, u32 val) 96{ 97 if (sc_reg > SCR_CONTROL) 98 return -EINVAL; 99 writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4)); 100 return 0; 101} 102 103 104static void vsc_freeze(struct ata_port *ap) 105{ 106 void __iomem *mask_addr; 107 108 mask_addr = ap->host->iomap[VSC_MMIO_BAR] + 109 VSC_SATA_INT_MASK_OFFSET + ap->port_no; 110 111 writeb(0, mask_addr); 112} 113 114 115static void vsc_thaw(struct ata_port *ap) 116{ 117 void __iomem *mask_addr; 118 119 mask_addr = ap->host->iomap[VSC_MMIO_BAR] + 120 VSC_SATA_INT_MASK_OFFSET + ap->port_no; 121 122 writeb(0xff, mask_addr); 123} 124 125 126static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl) 127{ 128 void __iomem *mask_addr; 129 u8 mask; 130 131 mask_addr = ap->host->iomap[VSC_MMIO_BAR] + 132 VSC_SATA_INT_MASK_OFFSET + ap->port_no; 133 mask = readb(mask_addr); 134 if (ctl & ATA_NIEN) 135 mask |= 0x80; 136 else 137 mask &= 0x7F; 138 writeb(mask, mask_addr); 139} 140 141 142static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) 143{ 144 struct ata_ioports *ioaddr = &ap->ioaddr; 145 unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; 146 147 /* 148 * The only thing the ctl register is used for is SRST. 149 * That is not enabled or disabled via tf_load. 150 * However, if ATA_NIEN is changed, then we need to change 151 * the interrupt register. 152 */ 153 if ((tf->ctl & ATA_NIEN) != (ap->last_ctl & ATA_NIEN)) { 154 ap->last_ctl = tf->ctl; 155 vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN); 156 } 157 if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { 158 writew(tf->feature | (((u16)tf->hob_feature) << 8), 159 ioaddr->feature_addr); 160 writew(tf->nsect | (((u16)tf->hob_nsect) << 8), 161 ioaddr->nsect_addr); 162 writew(tf->lbal | (((u16)tf->hob_lbal) << 8), 163 ioaddr->lbal_addr); 164 writew(tf->lbam | (((u16)tf->hob_lbam) << 8), 165 ioaddr->lbam_addr); 166 writew(tf->lbah | (((u16)tf->hob_lbah) << 8), 167 ioaddr->lbah_addr); 168 } else if (is_addr) { 169 writew(tf->feature, ioaddr->feature_addr); 170 writew(tf->nsect, ioaddr->nsect_addr); 171 writew(tf->lbal, ioaddr->lbal_addr); 172 writew(tf->lbam, ioaddr->lbam_addr); 173 writew(tf->lbah, ioaddr->lbah_addr); 174 } 175 176 if (tf->flags & ATA_TFLAG_DEVICE) 177 writeb(tf->device, ioaddr->device_addr); 178 179 ata_wait_idle(ap); 180} 181 182 183static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) 184{ 185 struct ata_ioports *ioaddr = &ap->ioaddr; 186 u16 nsect, lbal, lbam, lbah, error; 187 188 tf->status = ata_sff_check_status(ap); 189 tf->device = readw(ioaddr->device_addr); 190 error = readw(ioaddr->error_addr); 191 nsect = readw(ioaddr->nsect_addr); 192 lbal = readw(ioaddr->lbal_addr); 193 lbam = readw(ioaddr->lbam_addr); 194 lbah = readw(ioaddr->lbah_addr); 195 196 tf->error = error; 197 tf->nsect = nsect; 198 tf->lbal = lbal; 199 tf->lbam = lbam; 200 tf->lbah = lbah; 201 202 if (tf->flags & ATA_TFLAG_LBA48) { 203 tf->hob_feature = error >> 8; 204 tf->hob_nsect = nsect >> 8; 205 tf->hob_lbal = lbal >> 8; 206 tf->hob_lbam = lbam >> 8; 207 tf->hob_lbah = lbah >> 8; 208 } 209} 210 211static inline void vsc_error_intr(u8 port_status, struct ata_port *ap) 212{ 213 if (port_status & (VSC_SATA_INT_PHY_CHANGE | VSC_SATA_INT_ERROR_M)) 214 ata_port_freeze(ap); 215 else 216 ata_port_abort(ap); 217} 218 219static void vsc_port_intr(u8 port_status, struct ata_port *ap) 220{ 221 struct ata_queued_cmd *qc; 222 int handled = 0; 223 224 if (unlikely(port_status & VSC_SATA_INT_ERROR)) { 225 vsc_error_intr(port_status, ap); 226 return; 227 } 228 229 qc = ata_qc_from_tag(ap, ap->link.active_tag); 230 if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING))) 231 handled = ata_bmdma_port_intr(ap, qc); 232 233 /* We received an interrupt during a polled command, 234 * or some other spurious condition. Interrupt reporting 235 * with this hardware is fairly reliable so it is safe to 236 * simply clear the interrupt 237 */ 238 if (unlikely(!handled)) 239 ap->ops->sff_check_status(ap); 240} 241 242/* 243 * vsc_sata_interrupt 244 * 245 * Read the interrupt register and process for the devices that have 246 * them pending. 247 */ 248static irqreturn_t vsc_sata_interrupt(int irq, void *dev_instance) 249{ 250 struct ata_host *host = dev_instance; 251 unsigned int i; 252 unsigned int handled = 0; 253 u32 status; 254 255 status = readl(host->iomap[VSC_MMIO_BAR] + VSC_SATA_INT_STAT_OFFSET); 256 257 if (unlikely(status == 0xffffffff || status == 0)) { 258 if (status) 259 dev_err(host->dev, 260 ": IRQ status == 0xffffffff, PCI fault or device removal?\n"); 261 goto out; 262 } 263 264 spin_lock(&host->lock); 265 266 for (i = 0; i < host->n_ports; i++) { 267 u8 port_status = (status >> (8 * i)) & 0xff; 268 if (port_status) { 269 vsc_port_intr(port_status, host->ports[i]); 270 handled++; 271 } 272 } 273 274 spin_unlock(&host->lock); 275out: 276 return IRQ_RETVAL(handled); 277} 278 279 280static struct scsi_host_template vsc_sata_sht = { 281 ATA_BMDMA_SHT(DRV_NAME), 282}; 283 284 285static struct ata_port_operations vsc_sata_ops = { 286 .inherits = &ata_bmdma_port_ops, 287 /* The IRQ handling is not quite standard SFF behaviour so we 288 cannot use the default lost interrupt handler */ 289 .lost_interrupt = ATA_OP_NULL, 290 .sff_tf_load = vsc_sata_tf_load, 291 .sff_tf_read = vsc_sata_tf_read, 292 .freeze = vsc_freeze, 293 .thaw = vsc_thaw, 294 .scr_read = vsc_sata_scr_read, 295 .scr_write = vsc_sata_scr_write, 296}; 297 298static void vsc_sata_setup_port(struct ata_ioports *port, void __iomem *base) 299{ 300 port->cmd_addr = base + VSC_SATA_TF_CMD_OFFSET; 301 port->data_addr = base + VSC_SATA_TF_DATA_OFFSET; 302 port->error_addr = base + VSC_SATA_TF_ERROR_OFFSET; 303 port->feature_addr = base + VSC_SATA_TF_FEATURE_OFFSET; 304 port->nsect_addr = base + VSC_SATA_TF_NSECT_OFFSET; 305 port->lbal_addr = base + VSC_SATA_TF_LBAL_OFFSET; 306 port->lbam_addr = base + VSC_SATA_TF_LBAM_OFFSET; 307 port->lbah_addr = base + VSC_SATA_TF_LBAH_OFFSET; 308 port->device_addr = base + VSC_SATA_TF_DEVICE_OFFSET; 309 port->status_addr = base + VSC_SATA_TF_STATUS_OFFSET; 310 port->command_addr = base + VSC_SATA_TF_COMMAND_OFFSET; 311 port->altstatus_addr = base + VSC_SATA_TF_ALTSTATUS_OFFSET; 312 port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET; 313 port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET; 314 port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET; 315 writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET); 316 writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET); 317} 318 319 320static int vsc_sata_init_one(struct pci_dev *pdev, 321 const struct pci_device_id *ent) 322{ 323 static const struct ata_port_info pi = { 324 .flags = ATA_FLAG_SATA, 325 .pio_mask = ATA_PIO4, 326 .mwdma_mask = ATA_MWDMA2, 327 .udma_mask = ATA_UDMA6, 328 .port_ops = &vsc_sata_ops, 329 }; 330 const struct ata_port_info *ppi[] = { &pi, NULL }; 331 struct ata_host *host; 332 void __iomem *mmio_base; 333 int i, rc; 334 u8 cls; 335 336 ata_print_version_once(&pdev->dev, DRV_VERSION); 337 338 /* allocate host */ 339 host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4); 340 if (!host) 341 return -ENOMEM; 342 343 rc = pcim_enable_device(pdev); 344 if (rc) 345 return rc; 346 347 /* check if we have needed resource mapped */ 348 if (pci_resource_len(pdev, 0) == 0) 349 return -ENODEV; 350 351 /* map IO regions and initialize host accordingly */ 352 rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME); 353 if (rc == -EBUSY) 354 pcim_pin_device(pdev); 355 if (rc) 356 return rc; 357 host->iomap = pcim_iomap_table(pdev); 358 359 mmio_base = host->iomap[VSC_MMIO_BAR]; 360 361 for (i = 0; i < host->n_ports; i++) { 362 struct ata_port *ap = host->ports[i]; 363 unsigned int offset = (i + 1) * VSC_SATA_PORT_OFFSET; 364 365 vsc_sata_setup_port(&ap->ioaddr, mmio_base + offset); 366 367 ata_port_pbar_desc(ap, VSC_MMIO_BAR, -1, "mmio"); 368 ata_port_pbar_desc(ap, VSC_MMIO_BAR, offset, "port"); 369 } 370 371 /* 372 * Use 32 bit DMA mask, because 64 bit address support is poor. 373 */ 374 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 375 if (rc) 376 return rc; 377 378 /* 379 * Due to a bug in the chip, the default cache line size can't be 380 * used (unless the default is non-zero). 381 */ 382 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls); 383 if (cls == 0x00) 384 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80); 385 386 if (pci_enable_msi(pdev) == 0) 387 pci_intx(pdev, 0); 388 389 /* 390 * Config offset 0x98 is "Extended Control and Status Register 0" 391 * Default value is (1 << 28). All bits except bit 28 are reserved in 392 * DPA mode. If bit 28 is set, LED 0 reflects all ports' activity. 393 * If bit 28 is clear, each port has its own LED. 394 */ 395 pci_write_config_dword(pdev, 0x98, 0); 396 397 pci_set_master(pdev); 398 return ata_host_activate(host, pdev->irq, vsc_sata_interrupt, 399 IRQF_SHARED, &vsc_sata_sht); 400} 401 402static const struct pci_device_id vsc_sata_pci_tbl[] = { 403 { PCI_VENDOR_ID_VITESSE, 0x7174, 404 PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 405 { PCI_VENDOR_ID_INTEL, 0x3200, 406 PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 407 408 { } /* terminate list */ 409}; 410 411static struct pci_driver vsc_sata_pci_driver = { 412 .name = DRV_NAME, 413 .id_table = vsc_sata_pci_tbl, 414 .probe = vsc_sata_init_one, 415 .remove = ata_pci_remove_one, 416}; 417 418module_pci_driver(vsc_sata_pci_driver); 419 420MODULE_AUTHOR("Jeremy Higdon"); 421MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller"); 422MODULE_LICENSE("GPL"); 423MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl); 424MODULE_VERSION(DRV_VERSION);