// SPDX-License-Identifier: GPL-2.0-or-later /* * Promise PATA TX2/TX4/TX2000/133 IDE driver for pdc20268 to pdc20277. * * Ported to libata by: * Albert Lee <albertcc@tw.ibm.com> IBM Corporation * * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 1999 Promise Technology, Inc. * * Author: Frank Tiernan (frankt@promise.com) * Released under terms of General Public License * * libata documentation is available via 'make {ps|pdf}docs', * as Documentation/driver-api/libata.rst * * Hardware information only available under NDA.
*/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/ktime.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_cmnd.h> #include <linux/libata.h>
/* * ATA Timing Tables based on 133MHz controller clock. * These tables are only used when the controller is in 133MHz clock. * If the controller is in 100MHz clock, the ASIC hardware will * set the timing registers automatically when "set feature" command * is issued to the device. However, if the controller clock is 133MHz, * the following tables must be used.
*/ staticconststruct pdc2027x_pio_timing {
u8 value0, value1, value2;
} pdc2027x_pio_timing_tbl[] = {
{ 0xfb, 0x2b, 0xac }, /* PIO mode 0 */
{ 0x46, 0x29, 0xa4 }, /* PIO mode 1 */
{ 0x23, 0x26, 0x64 }, /* PIO mode 2 */
{ 0x27, 0x0d, 0x35 }, /* PIO mode 3, IORDY on, Prefetch off */
{ 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */
};
MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Albert Lee");
MODULE_DESCRIPTION("libata driver module for Promise PDC20268 to PDC20277");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);
/** * port_mmio - Get the MMIO address of PDC2027x extended registers * @ap: Port * @offset: offset from mmio base
*/ staticinlinevoid __iomem *port_mmio(struct ata_port *ap, unsignedint offset)
{ return ap->host->iomap[PDC_MMIO_BAR] + ap->port_no * 0x100 + offset;
}
/** * dev_mmio - Get the MMIO address of PDC2027x extended registers * @ap: Port * @adev: device * @offset: offset from mmio base
*/ staticinlinevoid __iomem *dev_mmio(struct ata_port *ap, struct ata_device *adev, unsignedint offset)
{
u8 adj = (adev->devno) ? 0x08 : 0x00; return port_mmio(ap, offset) + adj;
}
/** * pdc2027x_cable_detect - Probe host controller cable detect info * @ap: Port for which cable detect info is desired * * Read 80c cable indicator from Promise extended register. * This register is latched when the system is reset. * * LOCKING: * None (inherited from caller).
*/ staticint pdc2027x_cable_detect(struct ata_port *ap)
{
u32 cgcr;
/** * pdc2027x_port_enabled - Check PDC ATA control register to see whether the port is enabled. * @ap: Port to check
*/ staticinlineint pdc2027x_port_enabled(struct ata_port *ap)
{ return ioread8(port_mmio(ap, PDC_ATA_CTL)) & 0x02;
}
/** * pdc2027x_prereset - prereset for PATA host controller * @link: Target link * @deadline: deadline jiffies for the operation * * Probeinit including cable detection. * * LOCKING: * None (inherited from caller).
*/
/** * pdc2027x_mode_filter - mode selection filter * @adev: ATA device * @mask: list of modes proposed * * Block UDMA on devices that cause trouble with this controller.
*/
/* Check for slave of a Maxtor at UDMA6 */
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
ATA_ID_PROD_LEN + 1); /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */ if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6)
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
return mask;
}
/** * pdc2027x_set_piomode - Initialize host controller PATA PIO timings * @ap: Port to configure * @adev: um * * Set PIO mode for device. * * LOCKING: * None (inherited from caller).
*/
/** * pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings * @ap: Port to configure * @adev: um * * Set UDMA mode for device. * * LOCKING: * None (inherited from caller).
*/ staticvoid pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{ unsignedint dma_mode = adev->dma_mode;
u32 ctcr0, ctcr1;
if ((dma_mode >= XFER_UDMA_0) &&
(dma_mode <= XFER_UDMA_6)) { /* Set the UDMA timing registers with value table for 133MHz */ unsignedint udma_mode = dma_mode & 0x07;
if (dma_mode == XFER_UDMA_2) { /* * Turn off tHOLD. * If tHOLD is '1', the hardware will add half clock for data hold time. * This code segment seems to be no effect. tHOLD will be overwritten below.
*/
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
iowrite32(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1));
}
/** * pdc2027x_set_mode - Set the timing registers back to correct values. * @link: link to configure * @r_failed: Returned device for failure * * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. * This function overwrites the possibly incorrect values set by the hardware to be correct.
*/ staticint pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed)
{ struct ata_port *ap = link->ap; struct ata_device *dev; int rc;
rc = ata_set_mode(link, r_failed); if (rc < 0) return rc;
/** * pdc2027x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command * @qc: Metadata associated with taskfile to check * * LOCKING: * None (inherited from caller). * * RETURNS: 0 when ATAPI DMA can be used * 1 otherwise
*/ staticint pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
{ struct scsi_cmnd *cmd = qc->scsicmd;
u8 *scsicmd = cmd->cmnd; int rc = 1; /* atapi dma off by default */
/* * This workaround is from Promise's GPL driver. * If ATAPI DMA is used for commands not in the * following white list, say MODE_SENSE and REQUEST_SENSE, * pdc2027x might hit the irq lost problem.
*/ switch (scsicmd[0]) { case READ_10: case WRITE_10: case READ_12: case WRITE_12: case READ_6: case WRITE_6: case 0xad: /* READ_DVD_STRUCTURE */ case 0xbe: /* READ_CD */ /* ATAPI DMA is ok */
rc = 0; break; default:
;
}
return rc;
}
/** * pdc_read_counter - Read the ctr counter * @host: target ATA host
*/
/* * The 30-bit decreasing counter are read by 2 pieces. * Incorrect value may be read when both bccrh and bccrl are changing. * Ex. When 7900 decrease to 78FF, wrong value 7800 might be read.
*/ if (retry && !(bccrh == bccrhv && bccrl >= bccrlv)) {
retry--;
dev_dbg(host->dev, "rereading counter\n"); goto retry;
}
return counter;
}
/** * pdc_adjust_pll - Adjust the PLL input clock in Hz. * * @host: target ATA host * @pll_clock: The input of PLL in HZ * @board_idx: board identifier
*/ staticvoid pdc_adjust_pll(struct ata_host *host, long pll_clock, unsignedint board_idx)
{ void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u16 pll_ctl; long pll_clock_khz = pll_clock / 1000; long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ; long ratio = pout_required / pll_clock_khz; int F, R;
dev_dbg(host->dev, "pout_required is %ld\n", pout_required);
/* Show the current clock value of PLL control register * (maybe already configured by the firmware)
*/
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
dev_dbg(host->dev, "pll_ctl[%X]\n", pll_ctl);
/* * Calculate the ratio of F, R and OD * POUT = (F + 2) / (( R + 2) * NO)
*/ if (ratio < 8600L) { /* 8.6x */ /* Using NO = 0x01, R = 0x0D */
R = 0x0d;
} elseif (ratio < 12900L) { /* 12.9x */ /* Using NO = 0x01, R = 0x08 */
R = 0x08;
} elseif (ratio < 16100L) { /* 16.1x */ /* Using NO = 0x01, R = 0x06 */
R = 0x06;
} elseif (ratio < 64000L) { /* 64x */
R = 0x00;
} else { /* Invalid ratio */
dev_err(host->dev, "Invalid ratio %ld, give up!\n", ratio); return;
}
F = (ratio * (R+2)) / 1000 - 2;
if (unlikely(F < 0 || F > 127)) { /* Invalid F */
dev_err(host->dev, "F[%d] invalid!\n", F); return;
}
/* Wait the PLL circuit to be stable */
msleep(30);
/* * Show the current clock value of PLL control register * (maybe configured by the firmware)
*/
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
dev_dbg(host->dev, "pll_ctl[%X]\n", pll_ctl);
return;
}
/** * pdc_detect_pll_input_clock - Detect the PLL input clock in Hz. * @host: target ATA host * Ex. 16949000 on 33MHz PCI bus for pdc20275. * Half of the PCI clock.
*/ staticlong pdc_detect_pll_input_clock(struct ata_host *host)
{ void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u32 scr; long start_count, end_count;
ktime_t start_time, end_time; long pll_clock, usec_elapsed;
/** * pdc_hardware_init - Initialize the hardware. * @host: target ATA host * @board_idx: board identifier
*/ staticvoid pdc_hardware_init(struct ata_host *host, unsignedint board_idx)
{ long pll_clock;
/* * Detect PLL input clock rate. * On some system, where PCI bus is running at non-standard clock rate. * Ex. 25MHz or 40MHz, we have to adjust the cycle_time. * The pdc20275 controller employs PLL circuit to help correct timing registers setting.
*/
pll_clock = pdc_detect_pll_input_clock(host);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.