Lines Matching +full:host +full:- +full:port

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * sata_qstor.c - Pacific Digital Corporation QStor SATA
11 * as Documentation/driver-api/libata.rst
39 QS_HCF_CNFG3 = 0x0003, /* host configuration offset */
40 QS_HID_HPHY = 0x0004, /* host physical interface info */
42 QS_HST_SFF = 0x0100, /* host status fifo offset */
46 QS_HPHY_64BIT = (1 << 1), /* 64-bit bus detected */
50 /* per-channel register offsets */
53 QS_CFC_HUFT = 0x0800, /* host upstream fifo threshold */
54 QS_CFC_HDFT = 0x0804, /* host downstream fifo threshold */
57 QS_CCT_CTR0 = 0x0900, /* chan control-0 offset */
58 QS_CCT_CTR1 = 0x0901, /* chan control-1 offset */
68 /* pkt sub-field headers */
69 QS_HCB_HDR = 0x01, /* Host Control Block header */
83 board_2068_idx = 0, /* QStor 4-port SATA/RAID */
102 static void qs_host_stop(struct ata_host *host);
161 static void __iomem *qs_mmio_base(struct ata_host *host) in qs_mmio_base() argument
163 return host->iomap[QS_MMIO_BAR]; in qs_mmio_base()
173 u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); in qs_enter_reg_mode()
174 struct qs_port_priv *pp = ap->private_data; in qs_enter_reg_mode()
176 pp->state = qs_state_mmio; in qs_enter_reg_mode()
183 u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); in qs_reset_channel_logic()
192 u8 __iomem *mmio_base = qs_mmio_base(ap->host); in qs_freeze()
194 writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ in qs_freeze()
200 u8 __iomem *mmio_base = qs_mmio_base(ap->host); in qs_thaw()
203 writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */ in qs_thaw()
208 struct ata_port *ap = link->ap; in qs_prereset()
217 return -EINVAL; in qs_scr_read()
218 *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8)); in qs_scr_read()
231 return -EINVAL; in qs_scr_write()
232 writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8)); in qs_scr_write()
239 struct ata_port *ap = qc->ap; in qs_fill_sg()
240 struct qs_port_priv *pp = ap->private_data; in qs_fill_sg()
241 u8 *prd = pp->pkt + QS_CPB_BYTES; in qs_fill_sg()
244 for_each_sg(qc->sg, sg, qc->n_elem, si) { in qs_fill_sg()
262 struct qs_port_priv *pp = qc->ap->private_data; in qs_qc_prep()
263 u8 dflags = QS_DF_PORD, *buf = pp->pkt; in qs_qc_prep()
268 qs_enter_reg_mode(qc->ap); in qs_qc_prep()
269 if (qc->tf.protocol != ATA_PROT_DMA) in qs_qc_prep()
274 if ((qc->tf.flags & ATA_TFLAG_WRITE)) in qs_qc_prep()
276 if ((qc->tf.flags & ATA_TFLAG_LBA48)) in qs_qc_prep()
279 /* host control block (HCB) */ in qs_qc_prep()
282 *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes); in qs_qc_prep()
284 addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; in qs_qc_prep()
292 ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); in qs_qc_prep()
299 struct ata_port *ap = qc->ap; in qs_packet_start()
300 u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); in qs_packet_start()
310 struct qs_port_priv *pp = qc->ap->private_data; in qs_qc_issue()
312 switch (qc->tf.protocol) { in qs_qc_issue()
314 pp->state = qs_state_pkt; in qs_qc_issue()
326 pp->state = qs_state_mmio; in qs_qc_issue()
332 qc->err_mask |= ac_err_mask(status); in qs_do_or_die()
334 if (!qc->err_mask) { in qs_do_or_die()
337 struct ata_port *ap = qc->ap; in qs_do_or_die()
338 struct ata_eh_info *ehi = &ap->link.eh_info; in qs_do_or_die()
343 if (qc->err_mask == AC_ERR_DEV) in qs_do_or_die()
350 static inline unsigned int qs_intr_pkt(struct ata_host *host) in qs_intr_pkt() argument
354 u8 __iomem *mmio_base = qs_mmio_base(host); in qs_intr_pkt()
364 u8 sHST = sff1 & 0x3f; /* host status */ in qs_intr_pkt()
366 struct ata_port *ap = host->ports[port_no]; in qs_intr_pkt()
367 struct qs_port_priv *pp = ap->private_data; in qs_intr_pkt()
370 dev_dbg(host->dev, "SFF=%08x%08x: sHST=%d sDST=%02x\n", in qs_intr_pkt()
373 if (!pp || pp->state != qs_state_pkt) in qs_intr_pkt()
375 qc = ata_qc_from_tag(ap, ap->link.active_tag); in qs_intr_pkt()
376 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { in qs_intr_pkt()
380 qs_enter_reg_mode(qc->ap); in qs_intr_pkt()
392 static inline unsigned int qs_intr_mmio(struct ata_host *host) in qs_intr_mmio() argument
396 for (port_no = 0; port_no < host->n_ports; ++port_no) { in qs_intr_mmio()
397 struct ata_port *ap = host->ports[port_no]; in qs_intr_mmio()
398 struct qs_port_priv *pp = ap->private_data; in qs_intr_mmio()
401 qc = ata_qc_from_tag(ap, ap->link.active_tag); in qs_intr_mmio()
417 if (!pp || pp->state != qs_state_mmio) in qs_intr_mmio()
419 if (!(qc->tf.flags & ATA_TFLAG_POLLING)) in qs_intr_mmio()
427 struct ata_host *host = dev_instance; in qs_intr() local
431 spin_lock_irqsave(&host->lock, flags); in qs_intr()
432 handled = qs_intr_pkt(host) | qs_intr_mmio(host); in qs_intr()
433 spin_unlock_irqrestore(&host->lock, flags); in qs_intr()
438 static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base) in qs_ata_setup_port() argument
440 port->cmd_addr = in qs_ata_setup_port()
441 port->data_addr = base + 0x400; in qs_ata_setup_port()
442 port->error_addr = in qs_ata_setup_port()
443 port->feature_addr = base + 0x408; /* hob_feature = 0x409 */ in qs_ata_setup_port()
444 port->nsect_addr = base + 0x410; /* hob_nsect = 0x411 */ in qs_ata_setup_port()
445 port->lbal_addr = base + 0x418; /* hob_lbal = 0x419 */ in qs_ata_setup_port()
446 port->lbam_addr = base + 0x420; /* hob_lbam = 0x421 */ in qs_ata_setup_port()
447 port->lbah_addr = base + 0x428; /* hob_lbah = 0x429 */ in qs_ata_setup_port()
448 port->device_addr = base + 0x430; in qs_ata_setup_port()
449 port->status_addr = in qs_ata_setup_port()
450 port->command_addr = base + 0x438; in qs_ata_setup_port()
451 port->altstatus_addr = in qs_ata_setup_port()
452 port->ctl_addr = base + 0x440; in qs_ata_setup_port()
453 port->scr_addr = base + 0xc00; in qs_ata_setup_port()
458 struct device *dev = ap->host->dev; in qs_port_start()
460 void __iomem *mmio_base = qs_mmio_base(ap->host); in qs_port_start()
461 void __iomem *chan = mmio_base + (ap->port_no * 0x4000); in qs_port_start()
466 return -ENOMEM; in qs_port_start()
467 pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, in qs_port_start()
469 if (!pp->pkt) in qs_port_start()
470 return -ENOMEM; in qs_port_start()
471 ap->private_data = pp; in qs_port_start()
474 addr = (u64)pp->pkt_dma; in qs_port_start()
480 static void qs_host_stop(struct ata_host *host) in qs_host_stop() argument
482 void __iomem *mmio_base = qs_mmio_base(host); in qs_host_stop()
484 writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ in qs_host_stop()
488 static void qs_host_init(struct ata_host *host, unsigned int chip_id) in qs_host_init() argument
490 void __iomem *mmio_base = host->iomap[QS_MMIO_BAR]; in qs_host_init()
493 writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ in qs_host_init()
497 for (port_no = 0; port_no < host->n_ports; ++port_no) { in qs_host_init()
505 for (port_no = 0; port_no < host->n_ports; ++port_no) { in qs_host_init()
515 writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */ in qs_host_init()
519 * The QStor understands 64-bit buses, and uses 64-bit fields
524 * If we're 32-bit limited somewhere, then our 64-bit fields will
525 * just end up with zeros in the upper 32-bits, without any special
534 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_bits)); in qs_set_dma_masks()
536 dev_err(&pdev->dev, "%d-bit DMA enable failed\n", dma_bits); in qs_set_dma_masks()
543 unsigned int board_idx = (unsigned int) ent->driver_data; in qs_ata_init_one()
545 struct ata_host *host; in qs_ata_init_one() local
548 ata_print_version_once(&pdev->dev, DRV_VERSION); in qs_ata_init_one()
550 /* alloc host */ in qs_ata_init_one()
551 host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS); in qs_ata_init_one()
552 if (!host) in qs_ata_init_one()
553 return -ENOMEM; in qs_ata_init_one()
555 /* acquire resources and fill host */ in qs_ata_init_one()
561 return -ENODEV; in qs_ata_init_one()
566 host->iomap = pcim_iomap_table(pdev); in qs_ata_init_one()
568 rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]); in qs_ata_init_one()
572 for (port_no = 0; port_no < host->n_ports; ++port_no) { in qs_ata_init_one()
573 struct ata_port *ap = host->ports[port_no]; in qs_ata_init_one()
575 void __iomem *chan = host->iomap[QS_MMIO_BAR] + offset; in qs_ata_init_one()
577 qs_ata_setup_port(&ap->ioaddr, chan); in qs_ata_init_one()
579 ata_port_pbar_desc(ap, QS_MMIO_BAR, -1, "mmio"); in qs_ata_init_one()
580 ata_port_pbar_desc(ap, QS_MMIO_BAR, offset, "port"); in qs_ata_init_one()
584 qs_host_init(host, board_idx); in qs_ata_init_one()
587 return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED, in qs_ata_init_one()
594 MODULE_DESCRIPTION("Pacific Digital Corporation QStor SATA low-level driver");