brintos

brintos / linux-shallow public Read only

0
0
Text · 13.0 KiB · fafea2b Raw
535 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * pata_cmd64x.c 	- CMD64x PATA for new ATA layer4 *			  (C) 2005 Red Hat Inc5 *			  Alan Cox <alan@lxorguk.ukuu.org.uk>6 *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz7 *			  (C) 2012 MontaVista Software, LLC <source@mvista.com>8 *9 * Based upon10 * linux/drivers/ide/pci/cmd64x.c		Version 1.30	Sept 10, 200211 *12 * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.13 *           Note, this driver is not used at all on other systems because14 *           there the "BIOS" has done all of the following already.15 *           Due to massive hardware bugs, UltraDMA is only supported16 *           on the 646U2 and not on the 646U.17 *18 * Copyright (C) 1998		Eddie C. Dost  (ecd@skynet.be)19 * Copyright (C) 1998		David S. Miller (davem@redhat.com)20 *21 * Copyright (C) 1999-2002	Andre Hedrick <andre@linux-ide.org>22 *23 * TODO24 *	Testing work25 */26 27#include <linux/kernel.h>28#include <linux/module.h>29#include <linux/pci.h>30#include <linux/blkdev.h>31#include <linux/delay.h>32#include <scsi/scsi_host.h>33#include <linux/libata.h>34 35#define DRV_NAME "pata_cmd64x"36#define DRV_VERSION "0.2.18"37 38/*39 * CMD64x specific registers definition.40 */41 42enum {43	CFR 		= 0x50,44		CFR_INTR_CH0  = 0x04,45	CNTRL		= 0x51,46		CNTRL_CH0     = 0x04,47		CNTRL_CH1     = 0x08,48	CMDTIM 		= 0x52,49	ARTTIM0 	= 0x53,50	DRWTIM0 	= 0x54,51	ARTTIM1 	= 0x55,52	DRWTIM1 	= 0x56,53	ARTTIM23 	= 0x57,54		ARTTIM23_DIS_RA2  = 0x04,55		ARTTIM23_DIS_RA3  = 0x08,56		ARTTIM23_INTR_CH1 = 0x10,57	DRWTIM2 	= 0x58,58	BRST 		= 0x59,59	DRWTIM3 	= 0x5b,60	BMIDECR0	= 0x70,61	MRDMODE		= 0x71,62		MRDMODE_INTR_CH0 = 0x04,63		MRDMODE_INTR_CH1 = 0x08,64	BMIDESR0	= 0x72,65	UDIDETCR0	= 0x73,66	DTPR0		= 0x74,67	BMIDECR1	= 0x78,68	BMIDECSR	= 0x79,69	UDIDETCR1	= 0x7B,70	DTPR1		= 0x7C71};72 73static int cmd648_cable_detect(struct ata_port *ap)74{75	struct pci_dev *pdev = to_pci_dev(ap->host->dev);76	u8 r;77 78	/* Check cable detect bits */79	pci_read_config_byte(pdev, BMIDECSR, &r);80	if (r & (1 << ap->port_no))81		return ATA_CBL_PATA80;82	return ATA_CBL_PATA40;83}84 85/**86 *	cmd64x_set_timing	-	set PIO and MWDMA timing87 *	@ap: ATA interface88 *	@adev: ATA device89 *	@mode: mode90 *91 *	Called to do the PIO and MWDMA mode setup.92 */93 94static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 mode)95{96	struct pci_dev *pdev = to_pci_dev(ap->host->dev);97	struct ata_timing t;98	const unsigned long T = 1000000 / 33;99	const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };100 101	u8 reg;102 103	/* Port layout is not logical so use a table */104	const u8 arttim_port[2][2] = {105		{ ARTTIM0, ARTTIM1 },106		{ ARTTIM23, ARTTIM23 }107	};108	const u8 drwtim_port[2][2] = {109		{ DRWTIM0, DRWTIM1 },110		{ DRWTIM2, DRWTIM3 }111	};112 113	int arttim = arttim_port[ap->port_no][adev->devno];114	int drwtim = drwtim_port[ap->port_no][adev->devno];115 116	/* ata_timing_compute is smart and will produce timings for MWDMA117	   that don't violate the drives PIO capabilities. */118	if (ata_timing_compute(adev, mode, &t, T, 0) < 0) {119		ata_dev_err(adev, DRV_NAME ": mode computation failed.\n");120		return;121	}122	if (ap->port_no) {123		/* Slave has shared address setup */124		struct ata_device *pair = ata_dev_pair(adev);125 126		if (pair) {127			struct ata_timing tp;128			ata_timing_compute(pair, pair->pio_mode, &tp, T, 0);129			ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);130		}131	}132 133	ata_dev_dbg(adev, DRV_NAME ": active %d recovery %d setup %d.\n",134		t.active, t.recover, t.setup);135	if (t.recover > 16) {136		t.active += t.recover - 16;137		t.recover = 16;138	}139	if (t.active > 16)140		t.active = 16;141 142	/* Now convert the clocks into values we can actually stuff into143	   the chip */144 145	if (t.recover == 16)146		t.recover = 0;147	else if (t.recover > 1)148		t.recover--;149	else150		t.recover = 15;151 152	if (t.setup > 4)153		t.setup = 0xC0;154	else155		t.setup = setup_data[t.setup];156 157	t.active &= 0x0F;	/* 0 = 16 */158 159	/* Load setup timing */160	pci_read_config_byte(pdev, arttim, &reg);161	reg &= 0x3F;162	reg |= t.setup;163	pci_write_config_byte(pdev, arttim, reg);164 165	/* Load active/recovery */166	pci_write_config_byte(pdev, drwtim, (t.active << 4) | t.recover);167}168 169/**170 *	cmd64x_set_piomode	-	set initial PIO mode data171 *	@ap: ATA interface172 *	@adev: ATA device173 *174 *	Used when configuring the devices ot set the PIO timings. All the175 *	actual work is done by the PIO/MWDMA setting helper176 */177 178static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)179{180	cmd64x_set_timing(ap, adev, adev->pio_mode);181}182 183/**184 *	cmd64x_set_dmamode	-	set initial DMA mode data185 *	@ap: ATA interface186 *	@adev: ATA device187 *188 *	Called to do the DMA mode setup.189 */190 191static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)192{193	static const u8 udma_data[] = {194		0x30, 0x20, 0x10, 0x20, 0x10, 0x00195	};196 197	struct pci_dev *pdev = to_pci_dev(ap->host->dev);198	u8 regU, regD;199 200	int pciU = UDIDETCR0 + 8 * ap->port_no;201	int pciD = BMIDESR0 + 8 * ap->port_no;202	int shift = 2 * adev->devno;203 204	pci_read_config_byte(pdev, pciD, &regD);205	pci_read_config_byte(pdev, pciU, &regU);206 207	/* DMA bits off */208	regD &= ~(0x20 << adev->devno);209	/* DMA control bits */210	regU &= ~(0x30 << shift);211	/* DMA timing bits */212	regU &= ~(0x05 << adev->devno);213 214	if (adev->dma_mode >= XFER_UDMA_0) {215		/* Merge the timing value */216		regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;217		/* Merge the control bits */218		regU |= 1 << adev->devno; /* UDMA on */219		if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */220			regU |= 4 << adev->devno;221	} else {222		regU &= ~ (1 << adev->devno);	/* UDMA off */223		cmd64x_set_timing(ap, adev, adev->dma_mode);224	}225 226	regD |= 0x20 << adev->devno;227 228	pci_write_config_byte(pdev, pciU, regU);229	pci_write_config_byte(pdev, pciD, regD);230}231 232/**233 *	cmd64x_sff_irq_check	-	check IDE interrupt234 *	@ap: ATA interface235 *236 *	Check IDE interrupt in CFR/ARTTIM23 registers.237 */238 239static bool cmd64x_sff_irq_check(struct ata_port *ap)240{241	struct pci_dev *pdev = to_pci_dev(ap->host->dev);242	int irq_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;243	int irq_reg  = ap->port_no ? ARTTIM23 : CFR;244	u8 irq_stat;245 246	/* NOTE: reading the register should clear the interrupt */247	pci_read_config_byte(pdev, irq_reg, &irq_stat);248 249	return irq_stat & irq_mask;250}251 252/**253 *	cmd64x_sff_irq_clear	-	clear IDE interrupt254 *	@ap: ATA interface255 *256 *	Clear IDE interrupt in CFR/ARTTIM23 and DMA status registers.257 */258 259static void cmd64x_sff_irq_clear(struct ata_port *ap)260{261	struct pci_dev *pdev = to_pci_dev(ap->host->dev);262	int irq_reg = ap->port_no ? ARTTIM23 : CFR;263	u8 irq_stat;264 265	ata_bmdma_irq_clear(ap);266 267	/* Reading the register should be enough to clear the interrupt */268	pci_read_config_byte(pdev, irq_reg, &irq_stat);269}270 271/**272 *	cmd648_sff_irq_check	-	check IDE interrupt273 *	@ap: ATA interface274 *275 *	Check IDE interrupt in MRDMODE register.276 */277 278static bool cmd648_sff_irq_check(struct ata_port *ap)279{280	struct pci_dev *pdev = to_pci_dev(ap->host->dev);281	unsigned long base = pci_resource_start(pdev, 4);282	int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;283	u8 mrdmode = inb(base + 1);284 285	return mrdmode & irq_mask;286}287 288/**289 *	cmd648_sff_irq_clear	-	clear IDE interrupt290 *	@ap: ATA interface291 *292 *	Clear IDE interrupt in MRDMODE and DMA status registers.293 */294 295static void cmd648_sff_irq_clear(struct ata_port *ap)296{297	struct pci_dev *pdev = to_pci_dev(ap->host->dev);298	unsigned long base = pci_resource_start(pdev, 4);299	int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;300	u8 mrdmode;301 302	ata_bmdma_irq_clear(ap);303 304	/* Clear this port's interrupt bit (leaving the other port alone) */305	mrdmode  = inb(base + 1);306	mrdmode &= ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1);307	outb(mrdmode | irq_mask, base + 1);308}309 310/**311 *	cmd646r1_bmdma_stop	-	DMA stop callback312 *	@qc: Command in progress313 *314 *	Stub for now while investigating the r1 quirk in the old driver.315 */316 317static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)318{319	ata_bmdma_stop(qc);320}321 322static const struct scsi_host_template cmd64x_sht = {323	ATA_BMDMA_SHT(DRV_NAME),324};325 326static const struct ata_port_operations cmd64x_base_ops = {327	.inherits	= &ata_bmdma_port_ops,328	.set_piomode	= cmd64x_set_piomode,329	.set_dmamode	= cmd64x_set_dmamode,330};331 332static struct ata_port_operations cmd64x_port_ops = {333	.inherits	= &cmd64x_base_ops,334	.sff_irq_check	= cmd64x_sff_irq_check,335	.sff_irq_clear	= cmd64x_sff_irq_clear,336	.cable_detect	= ata_cable_40wire,337};338 339static struct ata_port_operations cmd646r1_port_ops = {340	.inherits	= &cmd64x_base_ops,341	.sff_irq_check	= cmd64x_sff_irq_check,342	.sff_irq_clear	= cmd64x_sff_irq_clear,343	.bmdma_stop	= cmd646r1_bmdma_stop,344	.cable_detect	= ata_cable_40wire,345};346 347static struct ata_port_operations cmd646r3_port_ops = {348	.inherits	= &cmd64x_base_ops,349	.sff_irq_check	= cmd648_sff_irq_check,350	.sff_irq_clear	= cmd648_sff_irq_clear,351	.cable_detect	= ata_cable_40wire,352};353 354static struct ata_port_operations cmd648_port_ops = {355	.inherits	= &cmd64x_base_ops,356	.sff_irq_check	= cmd648_sff_irq_check,357	.sff_irq_clear	= cmd648_sff_irq_clear,358	.cable_detect	= cmd648_cable_detect,359};360 361static void cmd64x_fixup(struct pci_dev *pdev)362{363	u8 mrdmode;364 365	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);366	pci_read_config_byte(pdev, MRDMODE, &mrdmode);367	mrdmode &= ~0x30;	/* IRQ set up */368	mrdmode |= 0x02;	/* Memory read line enable */369	pci_write_config_byte(pdev, MRDMODE, mrdmode);370 371	/* PPC specific fixup copied from old driver */372#ifdef CONFIG_PPC373	pci_write_config_byte(pdev, UDIDETCR0, 0xF0);374#endif375}376 377static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)378{379	static const struct ata_port_info cmd_info[7] = {380		{	/* CMD 643 - no UDMA */381			.flags = ATA_FLAG_SLAVE_POSS,382			.pio_mask = ATA_PIO4,383			.mwdma_mask = ATA_MWDMA2,384			.port_ops = &cmd64x_port_ops385		},386		{	/* CMD 646 with broken UDMA */387			.flags = ATA_FLAG_SLAVE_POSS,388			.pio_mask = ATA_PIO4,389			.mwdma_mask = ATA_MWDMA2,390			.port_ops = &cmd64x_port_ops391		},392		{	/* CMD 646U with broken UDMA */393			.flags = ATA_FLAG_SLAVE_POSS,394			.pio_mask = ATA_PIO4,395			.mwdma_mask = ATA_MWDMA2,396			.port_ops = &cmd646r3_port_ops397		},398		{	/* CMD 646U2 with working UDMA */399			.flags = ATA_FLAG_SLAVE_POSS,400			.pio_mask = ATA_PIO4,401			.mwdma_mask = ATA_MWDMA2,402			.udma_mask = ATA_UDMA2,403			.port_ops = &cmd646r3_port_ops404		},405		{	/* CMD 646 rev 1  */406			.flags = ATA_FLAG_SLAVE_POSS,407			.pio_mask = ATA_PIO4,408			.mwdma_mask = ATA_MWDMA2,409			.port_ops = &cmd646r1_port_ops410		},411		{	/* CMD 648 */412			.flags = ATA_FLAG_SLAVE_POSS,413			.pio_mask = ATA_PIO4,414			.mwdma_mask = ATA_MWDMA2,415			.udma_mask = ATA_UDMA4,416			.port_ops = &cmd648_port_ops417		},418		{	/* CMD 649 */419			.flags = ATA_FLAG_SLAVE_POSS,420			.pio_mask = ATA_PIO4,421			.mwdma_mask = ATA_MWDMA2,422			.udma_mask = ATA_UDMA5,423			.port_ops = &cmd648_port_ops424		}425	};426	const struct ata_port_info *ppi[] = {427		&cmd_info[id->driver_data],428		&cmd_info[id->driver_data],429		NULL430	};431	u8 reg;432	int rc;433	struct pci_dev *bridge = pdev->bus->self;434	/* mobility split bridges don't report enabled ports correctly */435	int port_ok = !(bridge && bridge->vendor ==436			PCI_VENDOR_ID_MOBILITY_ELECTRONICS);437	/* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */438	int cntrl_ch0_ok = (id->driver_data != 0);439 440	rc = pcim_enable_device(pdev);441	if (rc)442		return rc;443 444	if (id->driver_data == 0)	/* 643 */445		ata_pci_bmdma_clear_simplex(pdev);446 447	if (pdev->device == PCI_DEVICE_ID_CMD_646)448		switch (pdev->revision) {449		/* UDMA works since rev 5 */450		default:451			ppi[0] = &cmd_info[3];452			ppi[1] = &cmd_info[3];453			break;454		/* Interrupts in MRDMODE since rev 3 */455		case 3:456		case 4:457			ppi[0] = &cmd_info[2];458			ppi[1] = &cmd_info[2];459			break;460		/* Rev 1 with other problems? */461		case 1:462			ppi[0] = &cmd_info[4];463			ppi[1] = &cmd_info[4];464			fallthrough;465		/* Early revs have no CNTRL_CH0 */466		case 2:467		case 0:468			cntrl_ch0_ok = 0;469			break;470		}471 472	cmd64x_fixup(pdev);473 474	/* check for enabled ports */475	pci_read_config_byte(pdev, CNTRL, &reg);476	if (!port_ok)477		dev_notice(&pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n");478	if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) {479		dev_notice(&pdev->dev, "Primary port is disabled\n");480		ppi[0] = &ata_dummy_port_info;481 482	}483	if (port_ok && !(reg & CNTRL_CH1)) {484		dev_notice(&pdev->dev, "Secondary port is disabled\n");485		ppi[1] = &ata_dummy_port_info;486	}487 488	return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);489}490 491#ifdef CONFIG_PM_SLEEP492static int cmd64x_reinit_one(struct pci_dev *pdev)493{494	struct ata_host *host = pci_get_drvdata(pdev);495	int rc;496 497	rc = ata_pci_device_do_resume(pdev);498	if (rc)499		return rc;500 501	cmd64x_fixup(pdev);502 503	ata_host_resume(host);504	return 0;505}506#endif507 508static const struct pci_device_id cmd64x[] = {509	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },510	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },511	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 5 },512	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 6 },513 514	{ },515};516 517static struct pci_driver cmd64x_pci_driver = {518	.name 		= DRV_NAME,519	.id_table	= cmd64x,520	.probe 		= cmd64x_init_one,521	.remove		= ata_pci_remove_one,522#ifdef CONFIG_PM_SLEEP523	.suspend	= ata_pci_device_suspend,524	.resume		= cmd64x_reinit_one,525#endif526};527 528module_pci_driver(cmd64x_pci_driver);529 530MODULE_AUTHOR("Alan Cox");531MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers");532MODULE_LICENSE("GPL");533MODULE_DEVICE_TABLE(pci, cmd64x);534MODULE_VERSION(DRV_VERSION);535