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

📄 pci_bios.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	unsigned int base;	GT_READ(GT_PCI1M1LD_OFS, &base);	base = base << 21;	return base;}/* * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. * Inputs: N/A * Returns: PCI1 Memory 1 Bar Size. */static unsigned int pci1GetMemory1Size(void){	unsigned int top, base, size;	GT_READ(GT_PCI1M1LD_OFS, &base);	base = base << 21;	GT_READ(GT_PCI1M1HD_OFS, &top);	top = (top << 21);	size = ((top - base) & 0xfffffff);	size = size | 0x1fffff;	return (size + 1);}/* * pci_range_ck - * * Check if the pci device that are trying to access does really exists * on the evaluation board.   * * Inputs : * bus - bus number (0 for PCI 0 ; 1 for PCI 1) * dev - number of device on the specific pci bus * * Outpus : * 0 - if OK , 1 - if failure */static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev){	//DBG(KERN_INFO "p_r_c %d %d\n",bus,dev);	if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))		return 0;	// Bus/Device Number OK	return -1;		// Bus/Device Number not OK  }/* * pciXReadConfigReg  - Read from a PCI configuration register *                    - Make sure the GT is configured as a master before  *                      reading from another device on the PCI. *                   - The function takes care of Big/Little endian conversion. * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI *                        spec) *           pciDevNum: The device number needs to be addressed.                 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the  *                 cause register to make sure the data is valid * *  Configuration Address 0xCF8: * *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number *  |congif|Reserved|  Bus |Device|Function|Register|00| *  |Enable|        |Number|Number| Number | Number |  |    <=field Name * */static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device){	unsigned int DataForRegCf8;	unsigned int data;	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |			 (PCI_FUNC(device->devfn) << 8) |			 (offset & ~0x3)) | 0x80000000;	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);	/*  The casual observer might wonder why the READ is duplicated here,	   rather than immediately following the WRITE, and just have the	   swap in the "if".  That's because there is a latency problem	   with trying to read immediately after setting up the address	   register.  The "if" check gives enough time for the address	   to stabilize, so the READ can work.	 */	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		GT_READ(GT_PCI0_CFGDATA_OFS, &data);		return data;	} else {	/* The PCI is working in LE Mode so swap the Data. */		GT_READ(GT_PCI0_CFGDATA_OFS, &data);		return cpu_to_le32(data);	}}static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device){	unsigned int DataForRegCf8;	unsigned int data;	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |			 (PCI_FUNC(device->devfn) << 8) |			 (offset & ~0x3)) | 0x80000000;	/*  The casual observer might wonder why the READ is duplicated here,	   rather than immediately following the WRITE, and just have the	   swap in the "if".  That's because there is a latency problem	   with trying to read immediately after setting up the address	   register.  The "if" check gives enough time for the address	   to stabilize, so the READ can work.	 */	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		/* when configurating our own PCI 1 L-unit the access is through  		   the PCI 0 interface with reg number = reg number + 0x80 */		DataForRegCf8 |= 0x80;		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);	} else {		/* The PCI is working in LE Mode so swap the Data. */		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);	}	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		GT_READ(GT_PCI0_CFGDATA_OFS, &data);		return data;	} else {		GT_READ(GT_PCI1_CFGDATA_OFS, &data);		return cpu_to_le32(data);	}}/* * pciXWriteConfigReg - Write to a PCI configuration register *                    - Make sure the GT is configured as a master before  *                      writingto another device on the PCI. *                    - The function takes care of Big/Little endian conversion. * Inputs:   unsigned int regOffset: The register offset as it apears in the *           GT spec  *                   (or any other PCI device spec) *           pciDevNum: The device number needs to be addressed.                 * *  Configuration Address 0xCF8: * *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number *  |congif|Reserved|  Bus |Device|Function|Register|00| *  |Enable|        |Number|Number| Number | Number |  |    <=field Name * */static void pci0WriteConfigReg(unsigned int offset,			       struct pci_dev *device, unsigned int data){	unsigned int DataForRegCf8;	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |			 (PCI_FUNC(device->devfn) << 8) |			 (offset & ~0x3)) | 0x80000000;	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);	} else {		/* configuration Transaction over the pci. */		/* The PCI is working in LE Mode so swap the Data. */		GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data));	}}static void pci1WriteConfigReg(unsigned int offset,			       struct pci_dev *device, unsigned int data){	unsigned int DataForRegCf8;	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |			 (PCI_FUNC(device->devfn) << 8) |			 (offset & ~0x3)) | 0x80000000;	/*  There is a latency problem	   with trying to read immediately after setting up the address	   register.  The "if" check gives enough time for the address	   to stabilize, so the WRITE can work.	 */	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		/* when configurating our own PCI 1 L-unit the access is through  		   the PCI 0 interface with reg number = reg number + 0x80 */		DataForRegCf8 |= 0x80;		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);	} else {		/* configuration Transaction over the pci. */		/* The PCI is working in LE Mode so swap the Data. */		GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);	}	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);	} else {		/* configuration Transaction over the pci. */		GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data));	}}/* * galileo_pcibios_(read/write)_config_(dword/word/byte) - * * reads/write a dword/word/byte register from the configuration space * of a device. * * Inputs : * bus - bus number * dev - device number * offset - register offset in the configuration space * val - value to be written / read * * Outputs : * PCIBIOS_SUCCESSFUL when operation was succesfull * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned */static int galileo_pcibios_read_config_dword(struct pci_dev *device,					     int offset, u32 * val){	int dev, bus;	//DBG(KERN_INFO "rcd entry \n",offset,val);	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev)) {		*val = 0xffffffff;		return PCIBIOS_DEVICE_NOT_FOUND;	}	if (offset & 0x3)		return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus == 0)		*val = pci0ReadConfigReg(offset, device);//  if (bus == 1) *val = pci1ReadConfigReg (offset,device);	DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val);	/*	 * This is so that the upper PCI layer will get the correct return	 * value if we're not attached to anything.	 */	if ((offset == 0) && (*val == 0xffffffff)) {		return PCIBIOS_DEVICE_NOT_FOUND;	}	return PCIBIOS_SUCCESSFUL;}static int galileo_pcibios_read_config_word(struct pci_dev *device,					    int offset, u16 * val){	int dev, bus;	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev)) {		*val = 0xffff;		return PCIBIOS_DEVICE_NOT_FOUND;	}	if (offset & 0x1)		return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus == 0)		*val = (unsigned short) (pci0ReadConfigReg(offset, device) >>				         ((offset & ~0x3) * 8));//  if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));	DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val);	return PCIBIOS_SUCCESSFUL;}static int galileo_pcibios_read_config_byte(struct pci_dev *device,					    int offset, u8 * val){	int dev, bus;	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev)) {		*val = 0xff;		return PCIBIOS_DEVICE_NOT_FOUND;	}	if (bus == 0)		*val =		    (unsigned char) (pci0ReadConfigReg(offset, device) >>				     ((offset & ~0x3) * 8));//  if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));	DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val);	/*  This is so that the upper PCI layer will get the correct return value if	   we're not attached to anything.  */	if ((offset == 0xe) && (*val == 0xff)) {		u32 MasterAbort;		GT_READ(GT_INTRCAUSE_OFS, &MasterAbort);		if (MasterAbort & 0x40000) {			DBG(KERN_INFO "PCI Master Abort, ICR %x\n",			    MasterAbort);			GT_WRITE(GT_INTRCAUSE_OFS,				 (MasterAbort & 0xfffbffff));			return PCIBIOS_DEVICE_NOT_FOUND;		}	}	return PCIBIOS_SUCCESSFUL;}static int galileo_pcibios_write_config_dword(struct pci_dev *device,					      int offset, u32 val){	int dev, bus;	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev))		return PCIBIOS_DEVICE_NOT_FOUND;	if (offset & 0x3)		return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus == 0)		pci0WriteConfigReg(offset, device, val);//  if (bus == 1) pci1WriteConfigReg (offset,device,val);	DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset,	    val);	return PCIBIOS_SUCCESSFUL;}static int galileo_pcibios_write_config_word(struct pci_dev *device,					     int offset, u16 val){	int dev, bus;	unsigned long tmp;	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev))		return PCIBIOS_DEVICE_NOT_FOUND;	if (offset & 0x1)		return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus == 0)		tmp = pci0ReadConfigReg(offset, device);//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);	if ((offset % 4) == 0)		tmp = (tmp & 0xffff0000) | (val & 0xffff);	if ((offset % 4) == 2)		tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16);	if (bus == 0)		pci0WriteConfigReg(offset, device, tmp);//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);	DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset,	    val);	return PCIBIOS_SUCCESSFUL;}static int galileo_pcibios_write_config_byte(struct pci_dev *device,					     int offset, u8 val){	int dev, bus;	unsigned long tmp;	bus = device->bus->number;	dev = PCI_SLOT(device->devfn);	if (pci_range_ck(bus, dev))		return PCIBIOS_DEVICE_NOT_FOUND;	if (bus == 0)		tmp = pci0ReadConfigReg(offset, device);//  if (bus == 1) tmp = pci1ReadConfigReg (offset,device);	if ((offset % 4) == 0)		tmp = (tmp & 0xffffff00) | (val & 0xff);	if ((offset % 4) == 1)		tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8);	if ((offset % 4) == 2)		tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16);	if ((offset % 4) == 3)		tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24);	if (bus == 0)		pci0WriteConfigReg(offset, device, tmp);//  if (bus == 1) pci1WriteConfigReg (offset,device,tmp);	DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset,	    val);	return PCIBIOS_SUCCESSFUL;}static void galileo_pcibios_set_master(struct pci_dev *dev){	u16 cmd;	DBG(KERN_INFO "rr: galileo_pcibios_set_master\n");	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);	cmd |= PCI_COMMAND_MASTER;	galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);	DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd);}/*  Externally-expected functions.  Do not change function names  */int pcibios_enable_resources(struct pci_dev *dev){	u16 cmd, old_cmd;	u16 tmp;	u8 tmp1;	int idx;	struct resource *r;	DBG(KERN_INFO "rr: pcibios_enable_resources\n");	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);	old_cmd = cmd;	for (idx = 0; idx < 6; idx++) {		r = &dev->resource[idx];

⌨️ 快捷键说明

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