⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci-v320usc.c

📁 linux-2.4.29操作系统的源码
💻 C
字号:
/****************************************************************************//* * pci.c: V3 Hurricane specific PCI support. * * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com) * Copyright (C) 2001, Lineo Inc., <davidm@moreton.com.au> *               SH3 port. *//****************************************************************************/#include <linux/config.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/types.h>#include <linux/init.h>#include <linux/autoconf.h>#include <asm/byteorder.h>#include <asm/pci.h>#include <asm/system.h>#include <asm/irq.h>#include <asm/byteorder.h>#include <asm/io.h>#include "pci-v320usc.h"/****************************************************************************/#ifdef CONFIG_PCI/****************************************************************************/#ifndef CONFIG_PCMCIA#define V320USC_MEM_SPACE	0xB8000000 /* V320 sees this as AC000000 ! */#define V320USC_IO_SPACE	0xB4000000#define V320USC_CONF_SPACE	0xB4000000#else#define V320USC_MEM_SPACE	0xab000000#define V320USC_IO_SPACE	0xaa000000#define V320USC_CONF_SPACE	0xaa000000#endif#define	V320USC_BASE		0xb1fd0000#ifdef __LITTLE_ENDIAN#define reg08(x)	(V320USC_BASE + (V320USC_##x))#define reg16(x)	(V320USC_BASE + (V320USC_##x))#else#define reg08(x)	(V320USC_BASE + ((V320USC_##x)^3))#define reg16(x)	(V320USC_BASE + ((V320USC_##x)^2))#endif#define reg32(x)	(V320USC_BASE + (V320USC_##x))#define v320usc_inb(addr)			readb(reg08(addr)#define v320usc_outb(value, addr)	writeb(value, reg08(addr))#define v320usc_inw(addr)			readw(reg16(addr))#define v320usc_outw(value, addr)	writew(value, reg16(addr))#define v320usc_inl(addr)			readl(reg32(addr))#define v320usc_outl(value, addr)	writel(value, reg32(addr))/****************************************************************************//* Set the LB_PCI_BASE0 register to allow PCI Memory cycles to be used */static void set_io_cycles(void){	u32 tempscratch;	v320usc_outl(		(v320usc_inl(LB_PCI_BASE0) &		~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))		| LB_PCI_BASEX_IO, LB_PCI_BASE0);	/* do a read of the register to flush the posting buffer */	tempscratch = v320usc_inl(LB_PCI_BASE0);}/* Set the LB_PCI_BASE0 register to allow PCI Config cycles to be used */static void set_config_cycles(int alow){	u32 tempscratch;	tempscratch = v320usc_inl(LB_PCI_BASE0);	v320usc_outl((tempscratch & 		~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))		| LB_PCI_BASEX_CONFIG | alow, LB_PCI_BASE0);	/* do a read of the register to flush the posting buffer */	tempscratch = v320usc_inl(LB_PCI_BASE0);}static int mkaddr (unsigned char bus,		unsigned char devfn,		unsigned char where){	int addr, alow;	if (bus) {		addr =  ((bus    & 0xff) << 0x10) | 			((devfn & 0xff) << 0x08) |			 (where  & 0xff);		/* set alow for type 1 configuration cycle */		alow = 1;	} else {		int device, function;		if (devfn >= PCI_DEVFN(12, 0))			return -1;		device = PCI_SLOT(devfn);		function = PCI_FUNC(devfn);		/* This next line assumes that the PCI backplane connects  */		/* the IDSEL line for each slot to a Address line with a   */		/* small value resistor.  Note: The PCI spec. suggests     */		/* several options here.  This code assumes the following  */		/* IDSEL to Address line mapping.                          */		/* Slot  Address Line */		/*  0  - AD11 */		/*  1  - AD12 */		/*  2  - AD13 */		/*  3  - AD14 */		/*  4  - AD15 */		/* 0x800 is AD11 set, shift left by the slot number (device) */		addr = (0x800 << device) | (function << 8) | where;				/* set alow for type 0 configuration cycle */		alow = 0;	}	set_config_cycles(alow);	return addr;}static int v320usc_pcibios_read_config_byte (						struct pci_dev *dev,						int where,						u8 *val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	save_and_cli(flags);	/* Clear status bits */	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else {		// *val = readb(V320USC_CONF_SPACE + addr);		*val = * (unsigned char *) (V320USC_CONF_SPACE + addr);		/* Check for master abort */		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {			v320usc_outw(0xffff, PCI_STAT_W);			// printk("Master abort byte\n");			*val = 0xff;		}	}	set_io_cycles();	restore_flags(flags);	return retVal;}static int v320usc_pcibios_read_config_word (						struct pci_dev *dev,						int where,						u16 *val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	if (where & 1)		return PCIBIOS_BAD_REGISTER_NUMBER;	save_and_cli(flags);	/* Clear status bits */	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else {		*val = readw(V320USC_CONF_SPACE + addr);		/* Check for master abort */		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {			v320usc_outw(0xffff, PCI_STAT_W);			// printk("Master abort word\n");			*val = 0xffff;		}	}	set_io_cycles();	restore_flags(flags);	return retVal;}static int v320usc_pcibios_read_config_dword (						struct pci_dev *dev,						int where,						u32 *val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	if (where & 3)		return PCIBIOS_BAD_REGISTER_NUMBER;	save_and_cli(flags);	/* Clear status bits */	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else {		*val = readl(V320USC_CONF_SPACE + addr);		/* Check for master abort */		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {			v320usc_outw(0xffff, PCI_STAT_W);			// printk("Master abort long\n");			*val = 0xffffffff;		}	}	set_io_cycles();	restore_flags(flags);	return retVal;}static int v320usc_pcibios_write_config_byte (						struct pci_dev *dev,						int where,						u8 val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	save_and_cli(flags);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else		writeb(val, V320USC_CONF_SPACE + addr);	/* wait for write FIFO to empty */	v320usc_inw(PCI_STAT_W);	set_io_cycles();	restore_flags(flags);	return retVal;}static int v320usc_pcibios_write_config_word (						struct pci_dev *dev,						int where,						u16 val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	if (where & 1)		return PCIBIOS_BAD_REGISTER_NUMBER;	save_and_cli(flags);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else		writew(val, V320USC_CONF_SPACE + addr);	/* wait for write FIFO to empty */	v320usc_inw(PCI_STAT_W);	set_io_cycles();	restore_flags(flags);	return retVal;}static int v320usc_pcibios_write_config_dword (						struct pci_dev *dev,						int where,						u32 val){	int retVal = PCIBIOS_SUCCESSFUL;	unsigned long flags;	int addr;	if (where & 3)		return PCIBIOS_BAD_REGISTER_NUMBER;	save_and_cli(flags);	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)		retVal = -1;	else		writel(val, V320USC_CONF_SPACE + addr);	/* wait for write FIFO to empty */	v320usc_inw(PCI_STAT_W);	set_io_cycles();	restore_flags(flags);	return retVal;}struct pci_ops pci_config_ops = {	v320usc_pcibios_read_config_byte,	v320usc_pcibios_read_config_word,	v320usc_pcibios_read_config_dword,	v320usc_pcibios_write_config_byte,	v320usc_pcibios_write_config_word,	v320usc_pcibios_write_config_dword};/****************************************************************************//* Everything hangs off this */static struct pci_bus *pci_root_bus;static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin){	return PCI_SLOT(dev->devfn);}static int __init map_keywest_irq(struct pci_dev *dev, u8 slot, u8 pin){	if (pin >= 1 && pin <= 4)		return(PINT_IRQ_BASE + 2 + pin - 1);	return(-1);}char *pcibios_setup(char *str){	return(str);}void __initpcibios_fixup_pbus_ranges(struct pci_bus *bus,			  struct pbus_set_ranges_data *ranges){	ranges->io_start -= bus->resource[0]->start;	ranges->io_end -= bus->resource[0]->start;	ranges->mem_start -= bus->resource[1]->start;	ranges->mem_end -= bus->resource[1]->start;}void __init pcibios_init(void){	char *mode;	if (sh_mv.mv_init_pci != NULL)		sh_mv.mv_init_pci();	if (v320usc_inw(PCI_VENDOR) != V3USC_PCI_VENDOR) {		printk("V320USC: PCI bridge chip not found\n");		return;	}	switch (v320usc_inw(PCI_DEVICE)) {	case V3USC_PCI_DEVICE_MIPS_9: mode = "MIPS 9-bit"; break;	case V3USC_PCI_DEVICE_MIPS_5: mode = "MIPS 5-bit"; break;	case V3USC_PCI_DEVICE_SH3:    mode = "SH-3"; break;	case V3USC_PCI_DEVICE_SH4:    mode = "SH-4"; break;	default:                      mode = "unknown !"; break;	}	printk("V3 Semiconductor V320USC bridge in %s mode\n", mode);	/*	 * RST_OUT de asserted	 */	v320usc_outb(0x80, SYSTEM);	/*	 * 16x8 latency time, GRANT, Normal arbitration, RAM Disable,	 * CLK_OUT Disable, SYNC_RDY, BREQ_NEG	 */	v320usc_outl(0x10120001, LB_BUS_CFG);	/*	 * System error enable, PCI bus master, Memory & IO Access enable	 */	v320usc_outw(0x0047, PCI_CMD_W);	v320usc_outw(0xf100, PCI_STAT_W); /* clear any errors */	/*	 * 32x8 clocks as Latency Timer	 */	v320usc_outl(0x00008800, PCI_HDR_CFG);	v320usc_outl(0x00005761, DRAM_BLK0);	v320usc_outl(0x02005761, DRAM_BLK1);	v320usc_outl(0x00000000, DRAM_BLK2);	v320usc_outl(0x00000000, DRAM_BLK3);	v320usc_outl(0x00000942, DRAM_CFG);	v320usc_outl(0x80030066, PCI_BUS_CFG);	v320usc_outl(v320usc_inl(INT_STAT), INT_STAT); /* clear any ints */	v320usc_outl(0x00000000, INT_CFG0);	v320usc_outl(0x00000000, INT_CFG1);	v320usc_outl(0x00000000, INT_CFG2);	v320usc_outl(0x00000000, INT_CFG3);#if 0	v320usc_outl(0x0c000000, PCI_I2O_BASE);	v320usc_outl(0x0c010053, PCI_I2O_MAP);#endif	v320usc_outl(0x0c000001, PCI_MEM_BASE);	v320usc_outl(0x00010063, PCI_MEM_MAP);	v320usc_outl(0x00000000, LB_PCU_BASE); /* Disable PCU on SuperH */#if 0	v320usc_outl(0x00000081, PCI_PCU_BASE);#endif#ifndef CONFIG_PCMCIA	v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */	v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */#else	v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */	v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */#endif	/*	 * do the scan	 */	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);	pci_assign_unassigned_resources();	pci_fixup_irqs(no_swizzle, map_keywest_irq);#ifndef CONFIG_PCMCIA	v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */	v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */#else	v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */	v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */#endif	/*	 * Lock the system registers	 */	v320usc_outb(0x60, SYSTEM);	/*	 * Map all the PCI IO space	 */	mach_port_map(PCIBIOS_MIN_IO, (64*1024) - PCIBIOS_MIN_IO,			V320USC_IO_SPACE+PCIBIOS_MIN_IO, 0);}void __init pcibios_fixup_bus(struct pci_bus *bus){	printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__);}static void __init pci_fixup_ide_bases(struct pci_dev *d){	int i;	/*	 * PCI IDE controllers use non-standard I/O port decoding, respect it.	 */	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)		return;	printk("PCI: IDE base address fixup for %s\n", d->slot_name);	for(i=0; i<4; i++) {		struct resource *r = &d->resource[i];		if ((r->start & ~0x80) == 0x374) {			r->start |= 2;			r->end = r->start;		}	}}/* Add future fixups here... */struct pci_fixup pcibios_fixups[] = {	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },	{ 0 }};/****************************************************************************/#endif /* CONFIG_PCI */

⌨️ 快捷键说明

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