pdc202xx_new.c

来自「linux 内核源代码」· C语言 代码 · 共 602 行 · 第 1/2 页

C
602
字号
	DBG("scr1[%02X]\n", scr1);	outb(scr1 | 0x40, dma_base + 0x03);	/* Let the counter run for 10 ms. */	mdelay(10);	end_count = read_counter(dma_base);	do_gettimeofday(&end_time);	/* Stop the test mode */	outb(0x01, dma_base + 0x01);	scr1 = inb(dma_base + 0x03);	DBG("scr1[%02X]\n", scr1);	outb(scr1 & ~0x40, dma_base + 0x03);	/*	 * Calculate the input clock in Hz	 * (the clock counter is 30 bit wide and counts down)	 */	usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +		(end_time.tv_usec - start_time.tv_usec);	pll_input = ((start_count - end_count) & 0x3fffffff) / 10 *		(10000000 / usec_elapsed);	DBG("start[%ld] end[%ld]\n", start_count, end_count);	return pll_input;}#ifdef CONFIG_PPC_PMACstatic void __devinit apple_kiwi_init(struct pci_dev *pdev){	struct device_node *np = pci_device_to_OF_node(pdev);	u8 conf;	if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))		return;	if (pdev->revision >= 0x03) {		/* Setup chip magic config stuff (from darwin) */		pci_read_config_byte (pdev, 0x40, &conf);		pci_write_config_byte(pdev, 0x40, (conf | 0x01));	}}#endif /* CONFIG_PPC_PMAC */static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name){	unsigned long dma_base = pci_resource_start(dev, 4);	unsigned long sec_dma_base = dma_base + 0x08;	long pll_input, pll_output, ratio;	int f, r;	u8 pll_ctl0, pll_ctl1;	if (dma_base == 0)		return -EFAULT;#ifdef CONFIG_PPC_PMAC	apple_kiwi_init(dev);#endif	/* Calculate the required PLL output frequency */	switch(max_dma_rate(dev)) {		case 4: /* it's 133 MHz for Ultra133 chips */			pll_output = 133333333;			break;		case 3: /* and  100 MHz for Ultra100 chips */		default:			pll_output = 100000000;			break;	}	/*	 * Detect PLL input clock.	 * On some systems, where PCI bus is running at non-standard clock rate	 * (e.g. 25 or 40 MHz), we have to adjust the cycle time.	 * PDC20268 and newer chips employ PLL circuit to help correct timing	 * registers setting.	 */	pll_input = detect_pll_input_clock(dma_base);	printk("%s: PLL input clock is %ld kHz\n", name, pll_input / 1000);	/* Sanity check */	if (unlikely(pll_input < 5000000L || pll_input > 70000000L)) {		printk(KERN_ERR "%s: Bad PLL input clock %ld Hz, giving up!\n",		       name, pll_input);		goto out;	}#ifdef DEBUG	DBG("pll_output is %ld Hz\n", pll_output);	/* Show the current clock value of PLL control register	 * (maybe already configured by the BIOS)	 */	outb(0x02, sec_dma_base + 0x01);	pll_ctl0 = inb(sec_dma_base + 0x03);	outb(0x03, sec_dma_base + 0x01);	pll_ctl1 = inb(sec_dma_base + 0x03);	DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1);#endif	/*	 * Calculate the ratio of F, R and NO	 * POUT = (F + 2) / (( R + 2) * NO)	 */	ratio = pll_output / (pll_input / 1000);	if (ratio < 8600L) { /* 8.6x */		/* Using NO = 0x01, R = 0x0d */		r = 0x0d;	} else if (ratio < 12900L) { /* 12.9x */		/* Using NO = 0x01, R = 0x08 */		r = 0x08;	} else if (ratio < 16100L) { /* 16.1x */		/* Using NO = 0x01, R = 0x06 */		r = 0x06;	} else if (ratio < 64000L) { /* 64x */		r = 0x00;	} else {		/* Invalid ratio */		printk(KERN_ERR "%s: Bad ratio %ld, giving up!\n", name, ratio);		goto out;	}	f = (ratio * (r + 2)) / 1000 - 2;	DBG("F[%d] R[%d] ratio*1000[%ld]\n", f, r, ratio);	if (unlikely(f < 0 || f > 127)) {		/* Invalid F */		printk(KERN_ERR "%s: F[%d] invalid!\n", name, f);		goto out;	}	pll_ctl0 = (u8) f;	pll_ctl1 = (u8) r;	DBG("Writing pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1);	outb(0x02,     sec_dma_base + 0x01);	outb(pll_ctl0, sec_dma_base + 0x03);	outb(0x03,     sec_dma_base + 0x01);	outb(pll_ctl1, sec_dma_base + 0x03);	/* Wait the PLL circuit to be stable */	mdelay(30);#ifdef DEBUG	/*	 *  Show the current clock value of PLL control register	 */	outb(0x02, sec_dma_base + 0x01);	pll_ctl0 = inb(sec_dma_base + 0x03);	outb(0x03, sec_dma_base + 0x01);	pll_ctl1 = inb(sec_dma_base + 0x03);	DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1);#endif out:	return dev->irq;}static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif){	hwif->set_pio_mode = &pdcnew_set_pio_mode;	hwif->set_dma_mode = &pdcnew_set_mode;	hwif->quirkproc = &pdcnew_quirkproc;	hwif->resetproc = &pdcnew_reset;	if (hwif->dma_base == 0)		return;	if (hwif->cbl != ATA_CBL_PATA40_SHORT)		hwif->cbl = pdcnew_cable_detect(hwif);}static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev){	struct pci_dev *dev2;	dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 1,						PCI_FUNC(dev->devfn)));	if (dev2 &&	    dev2->vendor == dev->vendor &&	    dev2->device == dev->device) {		if (dev2->irq != dev->irq) {			dev2->irq = dev->irq;			printk(KERN_INFO "PDC20270: PCI config space "					 "interrupt fixed\n");		}		return dev2;	}	return NULL;}#define DECLARE_PDCNEW_DEV(name_str, udma) \	{ \		.name		= name_str, \		.init_chipset	= init_chipset_pdcnew, \		.init_hwif	= init_hwif_pdc202new, \		.host_flags	= IDE_HFLAG_POST_SET_MODE | \				  IDE_HFLAG_ERROR_STOPS_FIFO | \				  IDE_HFLAG_OFF_BOARD, \		.pio_mask	= ATA_PIO4, \		.mwdma_mask	= ATA_MWDMA2, \		.udma_mask	= udma, \	}static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {	/* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),	/* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),	/* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),	/* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6),	/* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6),	/* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6),	/* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6),};/** *	pdc202new_init_one	-	called when a pdc202xx is found *	@dev: the pdc202new device *	@id: the matching pci id * *	Called when the PCI registration layer (or the IDE initialization) *	finds a device matching our IDE device tables. */ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id){	const struct ide_port_info *d;	struct pci_dev *bridge = dev->bus->self;	u8 idx = id->driver_data;	d = &pdcnew_chipsets[idx];	if (idx == 2 && bridge &&	    bridge->vendor == PCI_VENDOR_ID_DEC &&	    bridge->device == PCI_DEVICE_ID_DEC_21150) {		struct pci_dev *dev2;		if (PCI_SLOT(dev->devfn) & 2)			return -ENODEV;		dev2 = pdc20270_get_dev2(dev);		if (dev2) {			int ret = ide_setup_pci_devices(dev, dev2, d);			if (ret < 0)				pci_dev_put(dev2);			return ret;		}	}	if (idx == 5 && bridge &&	    bridge->vendor == PCI_VENDOR_ID_INTEL &&	    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||	     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {		printk(KERN_INFO "PDC20276: attached to I2O RAID controller, "				 "skipping\n");		return -ENODEV;	}	return ide_setup_pci_device(dev, d);}static const struct pci_device_id pdc202new_pci_tbl[] = {	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), 0 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), 1 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), 2 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), 3 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), 4 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), 5 },	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), 6 },	{ 0, },};MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl);static struct pci_driver driver = {	.name		= "Promise_IDE",	.id_table	= pdc202new_pci_tbl,	.probe		= pdc202new_init_one,};static int __init pdc202new_ide_init(void){	return ide_pci_register_driver(&driver);}module_init(pdc202new_ide_init);MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?