^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * sata_qstor.c - Pacific Digital Corporation QStor SATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Maintained by: Mark Lord <mlord@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2005 Pacific Digital Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (OSL/GPL code release authorized by Jalil Fadavi).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * libata documentation is available via 'make {ps|pdf}docs',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * as Documentation/driver-api/libata.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/libata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DRV_NAME "sata_qstor"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DRV_VERSION "0.09"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) QS_MMIO_BAR = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) QS_PORTS = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) QS_MAX_PRD = LIBATA_MAX_PRD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) QS_CPB_ORDER = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) QS_CPB_BYTES = (1 << QS_CPB_ORDER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) QS_PRD_BYTES = QS_MAX_PRD * 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) QS_PKT_BYTES = QS_CPB_BYTES + QS_PRD_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* global register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) QS_HCF_CNFG3 = 0x0003, /* host configuration offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) QS_HID_HPHY = 0x0004, /* host physical interface info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) QS_HCT_CTRL = 0x00e4, /* global interrupt mask offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) QS_HST_SFF = 0x0100, /* host status fifo offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) QS_HVS_SERD3 = 0x0393, /* PHY enable offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* global control bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) QS_HPHY_64BIT = (1 << 1), /* 64-bit bus detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) QS_CNFG3_GSRST = 0x01, /* global chip reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) QS_SERD3_PHY_ENA = 0xf0, /* PHY detection ENAble*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* per-channel register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) QS_CCF_CPBA = 0x0710, /* chan CPB base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) QS_CCF_CSEP = 0x0718, /* chan CPB separation factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) QS_CFC_HUFT = 0x0800, /* host upstream fifo threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) QS_CFC_HDFT = 0x0804, /* host downstream fifo threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) QS_CFC_DUFT = 0x0808, /* dev upstream fifo threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) QS_CFC_DDFT = 0x080c, /* dev downstream fifo threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) QS_CCT_CTR0 = 0x0900, /* chan control-0 offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) QS_CCT_CTR1 = 0x0901, /* chan control-1 offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) QS_CCT_CFF = 0x0a00, /* chan command fifo offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* channel control bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) QS_CTR0_REG = (1 << 1), /* register mode (vs. pkt mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) QS_CTR0_CLER = (1 << 2), /* clear channel errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) QS_CTR1_RDEV = (1 << 1), /* sata phy/comms reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) QS_CTR1_RCHN = (1 << 4), /* reset channel logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) QS_CCF_RUN_PKT = 0x107, /* RUN a new dma PKT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* pkt sub-field headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) QS_HCB_HDR = 0x01, /* Host Control Block header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) QS_DCB_HDR = 0x02, /* Device Control Block header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* pkt HCB flag bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) QS_HF_DIRO = (1 << 0), /* data DIRection Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) QS_HF_DAT = (1 << 3), /* DATa pkt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) QS_HF_IEN = (1 << 4), /* Interrupt ENable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) QS_HF_VLD = (1 << 5), /* VaLiD pkt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* pkt DCB flag bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) QS_DF_PORD = (1 << 2), /* Pio OR Dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) QS_DF_ELBA = (1 << 3), /* Extended LBA (lba48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* PCI device IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) board_2068_idx = 0, /* QStor 4-port SATA/RAID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) QS_DMA_BOUNDARY = ~0UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) typedef enum { qs_state_mmio, qs_state_pkt } qs_state_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct qs_port_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dma_addr_t pkt_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) qs_state_t state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int qs_port_start(struct ata_port *ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void qs_host_stop(struct ata_host *host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static enum ata_completion_errors qs_qc_prep(struct ata_queued_cmd *qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void qs_freeze(struct ata_port *ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void qs_thaw(struct ata_port *ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int qs_prereset(struct ata_link *link, unsigned long deadline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void qs_error_handler(struct ata_port *ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static struct scsi_host_template qs_ata_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ATA_BASE_SHT(DRV_NAME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .sg_tablesize = QS_MAX_PRD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .dma_boundary = QS_DMA_BOUNDARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static struct ata_port_operations qs_ata_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .inherits = &ata_sff_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .check_atapi_dma = qs_check_atapi_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .qc_prep = qs_qc_prep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .qc_issue = qs_qc_issue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .freeze = qs_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .thaw = qs_thaw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .prereset = qs_prereset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .softreset = ATA_OP_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .error_handler = qs_error_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .lost_interrupt = ATA_OP_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .scr_read = qs_scr_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .scr_write = qs_scr_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .port_start = qs_port_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .host_stop = qs_host_stop,
^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) static const struct ata_port_info qs_port_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* board_2068_idx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_POLLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .pio_mask = ATA_PIO4_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .udma_mask = ATA_UDMA6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .port_ops = &qs_ata_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static const struct pci_device_id qs_ata_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { PCI_VDEVICE(PDC, 0x2068), board_2068_idx },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { } /* terminate list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static struct pci_driver qs_ata_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .id_table = qs_ata_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .probe = qs_ata_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .remove = ata_pci_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static void __iomem *qs_mmio_base(struct ata_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return host->iomap[QS_MMIO_BAR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 1; /* ATAPI DMA not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static inline void qs_enter_reg_mode(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct qs_port_priv *pp = ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pp->state = qs_state_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) readb(chan + QS_CCT_CTR0); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline void qs_reset_channel_logic(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) readb(chan + QS_CCT_CTR0); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) qs_enter_reg_mode(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void qs_freeze(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u8 __iomem *mmio_base = qs_mmio_base(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) qs_enter_reg_mode(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void qs_thaw(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u8 __iomem *mmio_base = qs_mmio_base(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) qs_enter_reg_mode(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int qs_prereset(struct ata_link *link, unsigned long deadline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct ata_port *ap = link->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) qs_reset_channel_logic(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return ata_sff_prereset(link, deadline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (sc_reg > SCR_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void qs_error_handler(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) qs_enter_reg_mode(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ata_sff_error_handler(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (sc_reg > SCR_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct ata_port *ap = qc->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct qs_port_priv *pp = ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u8 *prd = pp->pkt + QS_CPB_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for_each_sg(qc->sg, sg, qc->n_elem, si) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *(__le64 *)prd = cpu_to_le64(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) prd += sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) len = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *(__le32 *)prd = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) prd += sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (unsigned long long)addr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static enum ata_completion_errors qs_qc_prep(struct ata_queued_cmd *qc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct qs_port_priv *pp = qc->ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) u8 dflags = QS_DF_PORD, *buf = pp->pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int nelem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) VPRINTK("ENTER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) qs_enter_reg_mode(qc->ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (qc->tf.protocol != ATA_PROT_DMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return AC_ERR_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) nelem = qs_fill_sg(qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if ((qc->tf.flags & ATA_TFLAG_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) hflags |= QS_HF_DIRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if ((qc->tf.flags & ATA_TFLAG_LBA48))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dflags |= QS_DF_ELBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* host control block (HCB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) buf[ 0] = QS_HCB_HDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) buf[ 1] = hflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *(__le64 *)(&buf[16]) = cpu_to_le64(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* device control block (DCB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) buf[24] = QS_DCB_HDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) buf[28] = dflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* frame information structure (FIS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return AC_ERR_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static inline void qs_packet_start(struct ata_queued_cmd *qc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct ata_port *ap = qc->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) VPRINTK("ENTER, ap %p\n", ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) writeb(QS_CTR0_CLER, chan + QS_CCT_CTR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) wmb(); /* flush PRDs and pkt to memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) writel(QS_CCF_RUN_PKT, chan + QS_CCT_CFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) readl(chan + QS_CCT_CFF); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct qs_port_priv *pp = qc->ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) switch (qc->tf.protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case ATA_PROT_DMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pp->state = qs_state_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) qs_packet_start(qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case ATAPI_PROT_DMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) pp->state = qs_state_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return ata_sff_qc_issue(qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) qc->err_mask |= ac_err_mask(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!qc->err_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ata_qc_complete(qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct ata_port *ap = qc->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct ata_eh_info *ehi = &ap->link.eh_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ata_ehi_clear_desc(ehi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ata_ehi_push_desc(ehi, "status 0x%02X", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (qc->err_mask == AC_ERR_DEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ata_port_abort(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ata_port_freeze(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static inline unsigned int qs_intr_pkt(struct ata_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) u8 sFFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u8 __iomem *mmio_base = qs_mmio_base(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u32 sff0 = readl(mmio_base + QS_HST_SFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 sff1 = readl(mmio_base + QS_HST_SFF + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u8 sEVLD = (sff1 >> 30) & 0x01; /* valid flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sFFE = sff1 >> 31; /* empty flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (sEVLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) u8 sDST = sff0 >> 16; /* dev status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) u8 sHST = sff1 & 0x3f; /* host status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int port_no = (sff1 >> 8) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct ata_port *ap = host->ports[port_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct qs_port_priv *pp = ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct ata_queued_cmd *qc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sff1, sff0, port_no, sHST, sDST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!pp || pp->state != qs_state_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) qc = ata_qc_from_tag(ap, ap->link.active_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) switch (sHST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case 0: /* successful CPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case 3: /* device error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) qs_enter_reg_mode(qc->ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) qs_do_or_die(qc, sDST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } while (!sFFE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return handled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static inline unsigned int qs_intr_mmio(struct ata_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned int handled = 0, port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) for (port_no = 0; port_no < host->n_ports; ++port_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct ata_port *ap = host->ports[port_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct qs_port_priv *pp = ap->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct ata_queued_cmd *qc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) qc = ata_qc_from_tag(ap, ap->link.active_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!qc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * The qstor hardware generates spurious
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * interrupts from time to time when switching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * in and out of packet mode. There's no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * obvious way to know if we're here now due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * to that, so just ack the irq and pretend we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * knew it was ours.. (ugh). This does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * affect packet mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ata_sff_check_status(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!pp || pp->state != qs_state_mmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!(qc->tf.flags & ATA_TFLAG_POLLING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) handled |= ata_sff_port_intr(ap, qc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return handled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static irqreturn_t qs_intr(int irq, void *dev_instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct ata_host *host = dev_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) VPRINTK("ENTER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) handled = qs_intr_pkt(host) | qs_intr_mmio(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) VPRINTK("EXIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) port->cmd_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) port->data_addr = base + 0x400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) port->error_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) port->feature_addr = base + 0x408; /* hob_feature = 0x409 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) port->nsect_addr = base + 0x410; /* hob_nsect = 0x411 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) port->lbal_addr = base + 0x418; /* hob_lbal = 0x419 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) port->lbam_addr = base + 0x420; /* hob_lbam = 0x421 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) port->lbah_addr = base + 0x428; /* hob_lbah = 0x429 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) port->device_addr = base + 0x430;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) port->status_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) port->command_addr = base + 0x438;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) port->altstatus_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) port->ctl_addr = base + 0x440;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) port->scr_addr = base + 0xc00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int qs_port_start(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct device *dev = ap->host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct qs_port_priv *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) void __iomem *mmio_base = qs_mmio_base(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (!pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!pp->pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ap->private_data = pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) qs_enter_reg_mode(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) addr = (u64)pp->pkt_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) writel((u32) addr, chan + QS_CCF_CPBA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static void qs_host_stop(struct ata_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void __iomem *mmio_base = qs_mmio_base(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void qs_host_init(struct ata_host *host, unsigned int chip_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) void __iomem *mmio_base = host->iomap[QS_MMIO_BAR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned int port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* reset each channel in turn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) for (port_no = 0; port_no < host->n_ports; ++port_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 __iomem *chan = mmio_base + (port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) readb(chan + QS_CCT_CTR0); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) for (port_no = 0; port_no < host->n_ports; ++port_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) u8 __iomem *chan = mmio_base + (port_no * 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* set FIFO depths to same settings as Windows driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) writew(32, chan + QS_CFC_HUFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) writew(32, chan + QS_CFC_HDFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) writew(10, chan + QS_CFC_DUFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) writew( 8, chan + QS_CFC_DDFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* set CPB size in bytes, as a power of two */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) writeb(QS_CPB_ORDER, chan + QS_CCF_CSEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * The QStor understands 64-bit buses, and uses 64-bit fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * for DMA pointers regardless of bus width. We just have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * make sure our DMA masks are set appropriately for whatever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * bridge lies between us and the QStor, and then the DMA mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * code will ensure we only ever "see" appropriate buffer addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * If we're 32-bit limited somewhere, then our 64-bit fields will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * just end up with zeros in the upper 32-bits, without any special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * logic required outside of this routine (below).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) u32 bus_info = readl(mmio_base + QS_HID_HPHY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int dma_bits = (bus_info & QS_HPHY_64BIT) ? 64 : 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) dev_err(&pdev->dev, "%d-bit DMA enable failed\n", dma_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static int qs_ata_init_one(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) unsigned int board_idx = (unsigned int) ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct ata_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int rc, port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ata_print_version_once(&pdev->dev, DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* alloc host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* acquire resources and fill host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rc = pcim_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if ((pci_resource_flags(pdev, QS_MMIO_BAR) & IORESOURCE_MEM) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) host->iomap = pcim_iomap_table(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) for (port_no = 0; port_no < host->n_ports; ++port_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct ata_port *ap = host->ports[port_no];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned int offset = port_no * 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) void __iomem *chan = host->iomap[QS_MMIO_BAR] + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) qs_ata_setup_port(&ap->ioaddr, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ata_port_pbar_desc(ap, QS_MMIO_BAR, -1, "mmio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ata_port_pbar_desc(ap, QS_MMIO_BAR, offset, "port");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* initialize adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) qs_host_init(host, board_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &qs_ata_sht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) module_pci_driver(qs_ata_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) MODULE_AUTHOR("Mark Lord");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) MODULE_DESCRIPTION("Pacific Digital Corporation QStor SATA low-level driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) MODULE_DEVICE_TABLE(pci, qs_ata_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) MODULE_VERSION(DRV_VERSION);