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

📄 pci.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				PRINTK("\t\t\tPCI-E error: ATUE_PIE_MSK %#08x",					__raw_readl(IOP13XX_ATUE_PIE_MSK));				BUG();			}			if(clear)				__raw_writel(status, IOP13XX_ATUE_PIE_STS);		}	}	return err;}static intiop13xx_pcie_map_irq(struct pci_dev *dev, u8 idsel, u8 pin){	WARN_ON(idsel != 0);	switch (pin) {	case 1: return ATUE_INTA;	case 2: return ATUE_INTB;	case 3: return ATUE_INTC;	case 4: return ATUE_INTD;	default: return -1;	}}static u32 iop13xx_atue_read(unsigned long addr){	u32 val;	__raw_writel(addr, IOP13XX_ATUE_OCCAR);	val = __raw_readl(IOP13XX_ATUE_OCCDR);	rmb();	return val;}/* The read routines must check the error status of the last configuration * cycle.  If there was an error, the routine returns all hex f's. */static intiop13xx_atue_read_config(struct pci_bus *bus, unsigned int devfn, int where,		int size, u32 *value){	u32 val;	unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);	/* Hide device numbers > 0 on the local PCI-E bus (Type 0 access) */	if (!PCI_SLOT(devfn) || (addr & 1)) {		val = iop13xx_atue_read(addr) >> ((where & 3) * 8);		if( iop13xx_atue_pci_status(1) || is_atue_occdr_error() ) {			__raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3,				IOP13XX_XBG_BECSR);			val = 0xffffffff;		}		PRINTK("addr=%#0lx, val=%#010x", addr, val);	} else		val = 0xffffffff;	*value = val;	return PCIBIOS_SUCCESSFUL;}static intiop13xx_atue_write_config(struct pci_bus *bus, unsigned int devfn, int where,		int size, u32 value){	unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);	u32 val;	if (size != 4) {		val = iop13xx_atue_read(addr);		if (!iop13xx_atue_pci_status(1) == 0)			return PCIBIOS_SUCCESSFUL;		where = (where & 3) * 8;		if (size == 1)			val &= ~(0xff << where);		else			val &= ~(0xffff << where);		__raw_writel(val | value << where, IOP13XX_ATUE_OCCDR);	} else {		__raw_writel(addr, IOP13XX_ATUE_OCCAR);		__raw_writel(value, IOP13XX_ATUE_OCCDR);	}	return PCIBIOS_SUCCESSFUL;}static struct pci_ops iop13xx_atue_ops = {	.read	= iop13xx_atue_read_config,	.write	= iop13xx_atue_write_config,};/* When a PCI device does not exist during config cycles, the XScale gets a * bus error instead of returning 0xffffffff.  We can't rely on the ATU status * bits to tell us that it was indeed a configuration cycle that caused this * error especially in the case when the ATUE link is down.  Instead we rely * on data from the south XSI bridge to validate the abort */intiop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs){	PRINTK("Data abort: address = 0x%08lx "		    "fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx",		addr, fsr, regs->ARM_pc, regs->ARM_lr);	PRINTK("IOP13XX_XBG_BECSR: %#10x", __raw_readl(IOP13XX_XBG_BECSR));	PRINTK("IOP13XX_XBG_BERAR: %#10x", __raw_readl(IOP13XX_XBG_BERAR));	PRINTK("IOP13XX_XBG_BERUAR: %#10x", __raw_readl(IOP13XX_XBG_BERUAR));	/*  If it was an imprecise abort, then we need to correct the	 *  return address to be _after_ the instruction.	 */	if (fsr & (1 << 10))		regs->ARM_pc += 4;	if (is_atue_occdr_error() || is_atux_occdr_error())		return 0;	else		return 1;}/* Scan an IOP13XX PCI bus.  nr selects which ATU we use. */struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys){	int which_atu;	struct pci_bus *bus = NULL;	switch (init_atu) {	case IOP13XX_INIT_ATU_ATUX:		which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX;		break;	case IOP13XX_INIT_ATU_ATUE:		which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE;		break;	case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE):		which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX;		break;	default:		which_atu = 0;	}	if (!which_atu) {		BUG();		return NULL;	}	switch (which_atu) {	case IOP13XX_INIT_ATU_ATUX:		if (time_after_eq(jiffies + msecs_to_jiffies(1000),				  atux_trhfa_timeout))  /* ensure not wrap */			while(time_before(jiffies, atux_trhfa_timeout))				udelay(100);		bus = pci_bus_atux = pci_scan_bus(sys->busnr,						  &iop13xx_atux_ops,						  sys);		break;	case IOP13XX_INIT_ATU_ATUE:		bus = pci_bus_atue = pci_scan_bus(sys->busnr,						  &iop13xx_atue_ops,						  sys);		break;	}	return bus;}/* This function is called from iop13xx_pci_init() after assigning valid * values to iop13xx_atue_pmmr_offset.  This is the location for common * setup of ATUE for all IOP13XX implementations. */void __init iop13xx_atue_setup(void){	int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUE);	u32 reg_val;#ifdef CONFIG_PCI_MSI	/* BAR 0 (inbound msi window) */	__raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);	__raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUE_IALR0);	__raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUE_IATVR0);	__raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUE_IABAR0);#endif	/* BAR 1 (1:1 mapping with Physical RAM) */	/* Set limit and enable */	__raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,			IOP13XX_ATUE_IALR1);	__raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);	/* Set base at the top of the reserved address space */	__raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |			PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUE_IABAR1);	/* 1:1 mapping with physical ram	 * (leave big endian byte swap disabled)	 */	 __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);	 __raw_writel(PHYS_OFFSET, IOP13XX_ATUE_IATVR1);	/* Outbound window 1 (PCIX/PCIE memory window) */	/* 32 bit Address Space */	__raw_writel(0x0, IOP13XX_ATUE_OUMWTVR1);	/* PA[35:32] */	__raw_writel(IOP13XX_ATUE_OUMBAR_ENABLE |			(IOP13XX_PCIE_MEM_PHYS_OFFSET >> 32),			IOP13XX_ATUE_OUMBAR1);	/* Setup the I/O Bar	 * A[35-16] in 31-12	 */	__raw_writel(((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000),		IOP13XX_ATUE_OIOBAR);	__raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);	/* clear startup errors */	iop13xx_atue_pci_status(1);	/* OIOBAR function number	 */	reg_val = __raw_readl(IOP13XX_ATUE_OIOBAR);	reg_val &= ~0x7;	reg_val |= func;	__raw_writel(reg_val, IOP13XX_ATUE_OIOBAR);	/* OUMBAR function numbers	 */	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);	reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<			IOP13XX_ATU_OUMBAR_FUNC_NUM);	reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);	reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<			IOP13XX_ATU_OUMBAR_FUNC_NUM);	reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);	reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<			IOP13XX_ATU_OUMBAR_FUNC_NUM);	reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);	reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<			IOP13XX_ATU_OUMBAR_FUNC_NUM);	reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);	/* Enable inbound and outbound cycles	 */	reg_val = __raw_readw(IOP13XX_ATUE_ATUCMD);	reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |			PCI_COMMAND_PARITY | PCI_COMMAND_SERR;	__raw_writew(reg_val, IOP13XX_ATUE_ATUCMD);	reg_val = __raw_readl(IOP13XX_ATUE_ATUCR);	reg_val |= IOP13XX_ATUE_ATUCR_OUT_EN |			IOP13XX_ATUE_ATUCR_IVM;	__raw_writel(reg_val, IOP13XX_ATUE_ATUCR);}void __init iop13xx_atue_disable(void){	u32 reg_val;	__raw_writew(0x0, IOP13XX_ATUE_ATUCMD);	__raw_writel(IOP13XX_ATUE_ATUCR_IVM, IOP13XX_ATUE_ATUCR);	/* wait for cycles to quiesce */	while (__raw_readl(IOP13XX_ATUE_PCSR) & (IOP13XX_ATUE_PCSR_OUT_Q_BUSY |					     IOP13XX_ATUE_PCSR_IN_Q_BUSY |					     IOP13XX_ATUE_PCSR_LLRB_BUSY))		cpu_relax();	/* BAR 0 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUE_IAUBAR0);	__raw_writel(0x0, IOP13XX_ATUE_IABAR0);	__raw_writel(0x0, IOP13XX_ATUE_IAUTVR0);	__raw_writel(0x0, IOP13XX_ATUE_IATVR0);	__raw_writel(0x0, IOP13XX_ATUE_IALR0);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);	reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);	/* BAR 1 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);	__raw_writel(0x0, IOP13XX_ATUE_IABAR1);	__raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);	__raw_writel(0x0, IOP13XX_ATUE_IATVR1);	__raw_writel(0x0, IOP13XX_ATUE_IALR1);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);	reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);	/* BAR 2 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUE_IAUBAR2);	__raw_writel(0x0, IOP13XX_ATUE_IABAR2);	__raw_writel(0x0, IOP13XX_ATUE_IAUTVR2);	__raw_writel(0x0, IOP13XX_ATUE_IATVR2);	__raw_writel(0x0, IOP13XX_ATUE_IALR2);	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);	reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);	/* BAR 3 ( Disabled ) */	reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);	reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);	/* Setup the I/O Bar	 * A[35-16] in 31-12	 */	__raw_writel((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000,			IOP13XX_ATUE_OIOBAR);	__raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);}/* This function is called from iop13xx_pci_init() after assigning valid * values to iop13xx_atux_pmmr_offset.  This is the location for common * setup of ATUX for all IOP13XX implementations. */void __init iop13xx_atux_setup(void){	u32 reg_val;	int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX);	/* Take PCI-X bus out of reset if bootloader hasn't already.	 * According to spec, we should wait for 2^25 PCI clocks to meet	 * the PCI timing parameter Trhfa (RST# high to first access).	 * This is rarely necessary and often ignored.	 */	reg_val = __raw_readl(IOP13XX_ATUX_PCSR);	if (reg_val & IOP13XX_ATUX_PCSR_P_RSTOUT) {		int msec = (reg_val >> IOP13XX_ATUX_PCSR_FREQ_OFFSET) & 0x7;		msec = 1000 / (8-msec); /* bits 100=133MHz, 111=>33MHz */		__raw_writel(reg_val & ~IOP13XX_ATUX_PCSR_P_RSTOUT,				IOP13XX_ATUX_PCSR);		atux_trhfa_timeout = jiffies + msecs_to_jiffies(msec);	}	else		atux_trhfa_timeout = jiffies;#ifdef CONFIG_PCI_MSI	/* BAR 0 (inbound msi window) */	__raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);	__raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUX_IALR0);	__raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUX_IATVR0);	__raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUX_IABAR0);#endif	/* BAR 1 (1:1 mapping with Physical RAM) */	/* Set limit and enable */	__raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,			IOP13XX_ATUX_IALR1);	__raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);	/* Set base at the top of the reserved address space */	__raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |			PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUX_IABAR1);	/* 1:1 mapping with physical ram	 * (leave big endian byte swap disabled)	 */	__raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);	__raw_writel(PHYS_OFFSET, IOP13XX_ATUX_IATVR1);

⌨️ 快捷键说明

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