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

📄 pci.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Outbound window 1 (PCIX/PCIE memory window) */	/* 32 bit Address Space */	__raw_writel(0x0, IOP13XX_ATUX_OUMWTVR1);	/* PA[35:32] */	__raw_writel(IOP13XX_ATUX_OUMBAR_ENABLE |			IOP13XX_PCIX_MEM_PHYS_OFFSET >> 32,			IOP13XX_ATUX_OUMBAR1);	/* Setup the I/O Bar	 * A[35-16] in 31-12	 */	__raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,		IOP13XX_ATUX_OIOBAR);	__raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);	/* clear startup errors */	iop13xx_atux_pci_status(1);	/* OIOBAR function number	 */	reg_val = __raw_readl(IOP13XX_ATUX_OIOBAR);	reg_val &= ~0x7;	reg_val |= func;	__raw_writel(reg_val, IOP13XX_ATUX_OIOBAR);	/* OUMBAR function numbers	 */	reg_val = __raw_readl(IOP13XX_ATUX_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_ATUX_OUMBAR0);	reg_val = __raw_readl(IOP13XX_ATUX_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_ATUX_OUMBAR1);	reg_val = __raw_readl(IOP13XX_ATUX_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_ATUX_OUMBAR2);	reg_val = __raw_readl(IOP13XX_ATUX_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_ATUX_OUMBAR3);	/* Enable inbound and outbound cycles	 */	reg_val = __raw_readw(IOP13XX_ATUX_ATUCMD);	reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |		        PCI_COMMAND_PARITY | PCI_COMMAND_SERR;	__raw_writew(reg_val, IOP13XX_ATUX_ATUCMD);	reg_val = __raw_readl(IOP13XX_ATUX_ATUCR);	reg_val |= IOP13XX_ATUX_ATUCR_OUT_EN;	__raw_writel(reg_val, IOP13XX_ATUX_ATUCR);}void __init iop13xx_atux_disable(void){	u32 reg_val;	__raw_writew(0x0, IOP13XX_ATUX_ATUCMD);	__raw_writel(0x0, IOP13XX_ATUX_ATUCR);	/* wait for cycles to quiesce */	while (__raw_readl(IOP13XX_ATUX_PCSR) & (IOP13XX_ATUX_PCSR_OUT_Q_BUSY |				     IOP13XX_ATUX_PCSR_IN_Q_BUSY))		cpu_relax();	/* BAR 0 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUX_IAUBAR0);	__raw_writel(0x0, IOP13XX_ATUX_IABAR0);	__raw_writel(0x0, IOP13XX_ATUX_IAUTVR0);	__raw_writel(0x0, IOP13XX_ATUX_IATVR0);	__raw_writel(0x0, IOP13XX_ATUX_IALR0);	reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0);	reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0);	/* BAR 1 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);	__raw_writel(0x0, IOP13XX_ATUX_IABAR1);	__raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);	__raw_writel(0x0, IOP13XX_ATUX_IATVR1);	__raw_writel(0x0, IOP13XX_ATUX_IALR1);	reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1);	reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1);	/* BAR 2 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUX_IAUBAR2);	__raw_writel(0x0, IOP13XX_ATUX_IABAR2);	__raw_writel(0x0, IOP13XX_ATUX_IAUTVR2);	__raw_writel(0x0, IOP13XX_ATUX_IATVR2);	__raw_writel(0x0, IOP13XX_ATUX_IALR2);	reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2);	reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2);	/* BAR 3 ( Disabled ) */	__raw_writel(0x0, IOP13XX_ATUX_IAUBAR3);	__raw_writel(0x0, IOP13XX_ATUX_IABAR3);	__raw_writel(0x0, IOP13XX_ATUX_IAUTVR3);	__raw_writel(0x0, IOP13XX_ATUX_IATVR3);	__raw_writel(0x0, IOP13XX_ATUX_IALR3);	reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3);	reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;	__raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3);	/* Setup the I/O Bar	* A[35-16] in 31-12	*/	__raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,			IOP13XX_ATUX_OIOBAR);	__raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);}void __init iop13xx_set_atu_mmr_bases(void){	/* Based on ESSR0, determine the ATU X/E offsets */	switch(__raw_readl(IOP13XX_ESSR0) &		(IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX)) {	/* both asserted */	case 0:		iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;		iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;		break;	/* IOP13XX_CONTROLLER_ONLY = deasserted	 * IOP13XX_INTERFACE_SEL_PCIX = asserted	 */	case IOP13XX_CONTROLLER_ONLY:		iop13xx_atux_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;		iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;		break;	/* IOP13XX_CONTROLLER_ONLY = asserted	 * IOP13XX_INTERFACE_SEL_PCIX = deasserted	 */	case IOP13XX_INTERFACE_SEL_PCIX:		iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;		iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;		break;	/* both deasserted */	case IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX:		iop13xx_atux_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;		iop13xx_atue_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;		break;	default:		BUG();	}}void __init iop13xx_atu_select(struct hw_pci *plat_pci){	int i;	/* set system defaults	 * note: if "iop13xx_init_atu=" is specified this autodetect	 * sequence will be bypassed	 */	if (init_atu == IOP13XX_INIT_ATU_DEFAULT) {		/* check for single/dual interface */		if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) {			/* ATUE must be present check the device id			 * to see if ATUX is present.			 */			init_atu |= IOP13XX_INIT_ATU_ATUE;			switch (__raw_readw(IOP13XX_ATUE_DID) & 0xf0) {			case 0x70:			case 0x80:			case 0xc0:				init_atu |= IOP13XX_INIT_ATU_ATUX;				break;			}		} else {			/* ATUX must be present check the device id			 * to see if ATUE is present.			 */			init_atu |= IOP13XX_INIT_ATU_ATUX;			switch (__raw_readw(IOP13XX_ATUX_DID) & 0xf0) {			case 0x70:			case 0x80:			case 0xc0:				init_atu |= IOP13XX_INIT_ATU_ATUE;				break;			}		}		/* check central resource and root complex capability */		if (init_atu & IOP13XX_INIT_ATU_ATUX)			if (!(__raw_readl(IOP13XX_ATUX_PCSR) &				IOP13XX_ATUX_PCSR_CENTRAL_RES))				init_atu &= ~IOP13XX_INIT_ATU_ATUX;		if (init_atu & IOP13XX_INIT_ATU_ATUE)			if (__raw_readl(IOP13XX_ATUE_PCSR) &				IOP13XX_ATUE_PCSR_END_POINT)				init_atu &= ~IOP13XX_INIT_ATU_ATUE;	}	for (i = 0; i < 2; i++) {		if((init_atu & (1 << i)) == (1 << i))			plat_pci->nr_controllers++;	}}void __init iop13xx_pci_init(void){	/* clear pre-existing south bridge errors */	__raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR);	/* Setup the Min Address for PCI memory... */	iop13xx_pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA;	/* if Linux is given control of an ATU	 * clear out its prior configuration,	 * otherwise do not touch the registers	 */	if (init_atu & IOP13XX_INIT_ATU_ATUE) {		iop13xx_atue_disable();		iop13xx_atue_setup();	}	if (init_atu & IOP13XX_INIT_ATU_ATUX) {		iop13xx_atux_disable();		iop13xx_atux_setup();	}	hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS,			"imprecise external abort");}/* initialize the pci memory space.  handle any combination of * atue and atux enabled/disabled */int iop13xx_pci_setup(int nr, struct pci_sys_data *sys){	struct resource *res;	int which_atu;	u32 pcixsr, pcsr;	if (nr > 1)		return 0;	res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);	if (!res)		panic("PCI: unable to alloc resources");	/* 'nr' assumptions:	 * ATUX is always 0	 * ATUE is 1 when ATUX is also enabled	 * ATUE is 0 when ATUX is disabled	 */	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)		return 0;	switch(which_atu) {	case IOP13XX_INIT_ATU_ATUX:		pcixsr = __raw_readl(IOP13XX_ATUX_PCIXSR);		pcixsr &= ~0xffff;		pcixsr |= sys->busnr << IOP13XX_ATUX_PCIXSR_BUS_NUM |			  0 << IOP13XX_ATUX_PCIXSR_DEV_NUM |			  iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX)				  << IOP13XX_ATUX_PCIXSR_FUNC_NUM;		__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);		res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;		res[0].end   = IOP13XX_PCIX_UPPER_IO_PA;		res[0].name  = "IQ81340 ATUX PCI I/O Space";		res[0].flags = IORESOURCE_IO;		res[1].start = IOP13XX_PCIX_LOWER_MEM_RA;		res[1].end   = IOP13XX_PCIX_UPPER_MEM_RA;		res[1].name  = "IQ81340 ATUX PCI Memory Space";		res[1].flags = IORESOURCE_MEM;		sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;		sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;		break;	case IOP13XX_INIT_ATU_ATUE:		/* Note: the function number field in the PCSR is ro */		pcsr = __raw_readl(IOP13XX_ATUE_PCSR);		pcsr &= ~(0xfff8 << 16);		pcsr |= sys->busnr << IOP13XX_ATUE_PCSR_BUS_NUM |				0 << IOP13XX_ATUE_PCSR_DEV_NUM;		__raw_writel(pcsr, IOP13XX_ATUE_PCSR);		res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;		res[0].end   = IOP13XX_PCIE_UPPER_IO_PA;		res[0].name  = "IQ81340 ATUE PCI I/O Space";		res[0].flags = IORESOURCE_IO;		res[1].start = IOP13XX_PCIE_LOWER_MEM_RA;		res[1].end   = IOP13XX_PCIE_UPPER_MEM_RA;		res[1].name  = "IQ81340 ATUE PCI Memory Space";		res[1].flags = IORESOURCE_MEM;		sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;		sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;		sys->map_irq = iop13xx_pcie_map_irq;		break;	default:		return 0;	}	request_resource(&ioport_resource, &res[0]);	request_resource(&iomem_resource, &res[1]);	sys->resource[0] = &res[0];	sys->resource[1] = &res[1];	sys->resource[2] = NULL;	return 1;}u16 iop13xx_dev_id(void){	if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)		return __raw_readw(IOP13XX_ATUE_DID);	else		return __raw_readw(IOP13XX_ATUX_DID);}static int __init iop13xx_init_atu_setup(char *str){        init_atu = IOP13XX_INIT_ATU_NONE;        if (str) {                while (*str != '\0') {                        switch (*str) {                        case 'x':                        case 'X':                                init_atu |= IOP13XX_INIT_ATU_ATUX;                                init_atu &= ~IOP13XX_INIT_ATU_NONE;                                break;                        case 'e':                        case 'E':                                init_atu |= IOP13XX_INIT_ATU_ATUE;                                init_atu &= ~IOP13XX_INIT_ATU_NONE;                                break;                        case ',':                        case '=':                                break;                        default:                                PRINTK("\"iop13xx_init_atu\" malformed at "                                            "character: \'%c\'", *str);                                *(str + 1) = '\0';                                init_atu = IOP13XX_INIT_ATU_DEFAULT;                        }                        str++;                }        }        return 1;}__setup("iop13xx_init_atu", iop13xx_init_atu_setup);

⌨️ 快捷键说明

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