[U-Boot] [PATCH V2 1/1] IXP425: Fixing PCI access

This patch fixes the PCI handling routines of the IXP port. It seems that this hasn't been touched for quite a while and u-boot PCI handling has changed since then (but nobody update IXP).
Changes (list uncomplete): - non_prefetched_read/write now return ERROR on (master-) abort. - fixed pci configuration space access. - pci_read_config_XXX now return value 0xff even in case of error (as some callers do not check the return value) - Removed CONFIG_PCI_SCAN_SHOW, as printf is not possible at the time pci_scan is called initially - fixed some IXP initialization of memory spaces - fixed address and irq assignment to PCI devices - fixed pci_find_device - some reformatting
Note: I think boards should always define IXP425_PCI_SIMPLE_MAPPING
Patch was tested with Janz emPC-A400.
Signed-off-by: Stefan Althoefer stefan.althoefer@web.de --- I revised the patch as I found some more errors.
board/ixdp425/ixdp425.c | 9 + cpu/ixp/pci.c | 407 ++++++++++++++++++++-------------- drivers/pci/pci_indirect.c | 4 +- include/asm-arm/arch-ixp/ixp425pci.h | 14 +- 4 files changed, 260 insertions(+), 174 deletions(-)
diff --git a/board/ixdp425/ixdp425.c b/board/ixdp425/ixdp425.c index 43ac8f6..ef2f7d5 100644 --- a/board/ixdp425/ixdp425.c +++ b/board/ixdp425/ixdp425.c @@ -118,9 +118,18 @@ void pci_init_board(void)
pci_ixp_init(&hose); } + +#include <pci.h> +int pciTranslateIrq(pci_dev_t dev, int intPin) +{ + /* FIXME: This needs to be implemented by someone + who onws an IXDP425 board */ + return 0; +} #endif
int board_eth_init(bd_t *bis) { return pci_eth_init(bis); } + diff --git a/cpu/ixp/pci.c b/cpu/ixp/pci.c index 8c6b0b2..6586ba1 100644 --- a/cpu/ixp/pci.c +++ b/cpu/ixp/pci.c @@ -33,16 +33,15 @@ #include <asm/arch/ixp425.h> #include <asm/arch/ixp425pci.h>
-static void non_prefetch_read (unsigned int addr, unsigned int cmd, +static int non_prefetch_read (unsigned int addr, unsigned int cmd, unsigned int *data); -static void non_prefetch_write (unsigned int addr, unsigned int cmd, +static int non_prefetch_write (unsigned int addr, unsigned int cmd, unsigned int data); static void configure_pins (void); static void sys_pci_gpio_clock_config (void); -static void pci_bus_scan (void); -static int pci_device_exists (unsigned int deviceNo); -static void sys_pci_bar_info_get (unsigned int devnum, unsigned int bus, - unsigned int dev, unsigned int func); +void pci_bus_scan (void); +static int pci_device_exists (pci_dev_t dev); +static void sys_pci_bar_info_get (unsigned int devnum, pci_dev_t dev); static void sys_pci_device_bars_write (void); static void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr); @@ -68,15 +67,36 @@ PciBar *memBars[IXP425_PCI_MAX_BAR]; PciBar *ioBars[IXP425_PCI_MAX_BAR]; PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS];
+ +extern int pciTranslateIrq(pci_dev_t dev, int intPin); + +static int ixp4xx_config_addr(u32 *addr, pci_dev_t devfn, int where) +{ + if (!(PCI_BUS(devfn))) { + /* type 0 */ + if (PCI_DEV(devfn) > 20) + return ERROR; + *addr = BIT(32-PCI_DEV(devfn)) | ((PCI_FUNC(devfn)) << 8) + | (where & ~3); + } else { + /* type 1 */ + *addr = (PCI_BUS(devfn) << 16) | ((PCI_DEV(devfn)) << 11) + | ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1; + } + return OK; +} + int pci_read_config_dword (pci_dev_t dev, int where, unsigned int *val) { unsigned int retval; unsigned int addr;
- /*address bits 31:28 specify the device 10:8 specify the function */ - /*Set the address to be read */ - addr = BIT ((31 - dev)) | (where & ~3); - non_prefetch_read (addr, NP_CMD_CONFIGREAD, &retval); + *val = 0xffffffff; + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_read(addr, NP_CMD_CONFIGREAD, &retval) != OK ){ + return ERROR; + }
*val = retval;
@@ -90,6 +110,7 @@ int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val) unsigned int addr; unsigned int byteEnables;
+ *val = 0xffff; n = where % 4; /*byte enables are 4 bits active low, the position of each bit maps to the byte that it enables */ @@ -97,10 +118,12 @@ int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val) (~(BIT (n) | BIT ((n + 1)))) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; byteEnables = byteEnables << PCI_NP_CBE_BESL; - /*address bits 31:28 specify the device 10:8 specify the function */ - /*Set the address to be read */ - addr = BIT ((31 - dev)) | (where & ~3); - non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval); + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, + &retval) != OK ){ + return ERROR; + }
/*Pick out the word we are interested in */ *val = (retval >> (8 * n)); @@ -115,16 +138,18 @@ int pci_read_config_byte (pci_dev_t dev, int where, unsigned char *val) unsigned int byteEnables; unsigned int addr;
+ *val = 0xff; n = where % 4; /*byte enables are 4 bits, active low, the position of each bit maps to the byte that it enables */ byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; byteEnables = byteEnables << PCI_NP_CBE_BESL; - - /*address bits 31:28 specify the device, 10:8 specify the function */ - /*Set the address to be read */ - addr = BIT ((31 - dev)) | (where & ~3); - non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval); + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, + &retval) != OK ){ + return ERROR; + } /*Pick out the byte we are interested in */ *val = (retval >> (8 * n));
@@ -144,10 +169,12 @@ int pci_write_config_byte (pci_dev_t dev, int where, unsigned char val) byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; byteEnables = byteEnables << PCI_NP_CBE_BESL; ldata = val << (8 * n); - /*address bits 31:28 specify the device 10:8 specify the function */ - /*Set the address to be written */ - addr = BIT ((31 - dev)) | (where & ~3); - non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata); + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, + ldata) != OK ){ + return ERROR; + }
return (OK); } @@ -167,10 +194,12 @@ int pci_write_config_word (pci_dev_t dev, int where, unsigned short val) IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; byteEnables = byteEnables << PCI_NP_CBE_BESL; ldata = val << (8 * n); - /*address bits 31:28 specify the device 10:8 specify the function */ - /*Set the address to be written */ - addr = BIT (31 - dev) | (where & ~3); - non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata); + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, + ldata) != OK ){ + return ERROR; + }
return (OK); } @@ -179,31 +208,41 @@ int pci_write_config_dword (pci_dev_t dev, int where, unsigned int val) { unsigned int addr;
- /*address bits 31:28 specify the device 10:8 specify the function */ - /*Set the address to be written */ - addr = BIT (31 - dev) | (where & ~3); - non_prefetch_write (addr, NP_CMD_CONFIGWRITE, val); + if (ixp4xx_config_addr(&addr, dev, where & ~3)) + return ERROR; + if( non_prefetch_write(addr, NP_CMD_CONFIGWRITE, val) != OK ){ + return ERROR; + }
return (OK); }
-void non_prefetch_read (unsigned int addr, +int non_prefetch_read (unsigned int addr, unsigned int cmd, unsigned int *data) { - REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr); + unsigned int isr;
+ REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr); /*set up and execute the read */ REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd); - /*The result of the read is now in np_rdata */ REG_READ (PCI_CSR_BASE, PCI_NP_RDATA_OFFSET, *data);
- return; + /* Check for abort */ + REG_READ(PCI_CSR_BASE, PCI_ISR_OFFSET, isr); + if (isr & PCI_ISR_PFE) { + /* clear the bit */ + REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE); + return ERROR; + } + + return OK; }
-void non_prefetch_write (unsigned int addr, +int non_prefetch_write (unsigned int addr, unsigned int cmd, unsigned int data) { + unsigned int isr;
REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr); /*set up the write */ @@ -211,7 +250,15 @@ void non_prefetch_write (unsigned int addr, /*Execute the write by writing to NP_WDATA */ REG_WRITE (PCI_CSR_BASE, PCI_NP_WDATA_OFFSET, data);
- return; + /* Check for abort */ + REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, isr); + if( isr & PCI_ISR_PFE ){ + /* clear the bit */ + REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE); + return ERROR; + } + + return OK; }
/* @@ -226,7 +273,8 @@ void crp_read (unsigned int offset, unsigned int *data)
void crp_write (unsigned int offset, unsigned int data) { - /*The CRP address register bit 16 indicates that we want to do a write */ + /*The CRP address register bit 16 indicates that we want to do a + write */ REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET, PCI_CRP_WRITE | offset); REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data); @@ -257,11 +305,10 @@ void pci_ixp_init (struct pci_controller *hose)
pci_register_hose (hose);
-/* - ========================================================== - Init IXP PCI - ========================================================== -*/ + /* + * Init IXP PCI + */ + REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval); regval |= 1 << 2; REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval); @@ -304,9 +351,7 @@ void pci_ixp_init (struct pci_controller *hose) pci_write_config_word (0, PCI_CFG_COMMAND, INITIAL_PCI_CMD); REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE); -#ifdef CONFIG_PCI_SCAN_SHOW - printf ("Device bus dev func deviceID vendorID \n"); -#endif + pci_bus_scan (); }
@@ -347,76 +392,108 @@ void sys_pci_gpio_clock_config (void) WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval); }
+ void pci_bus_scan (void) { - unsigned int bus = 0, dev, func = 0; + int busno, devno, funcno; + int multifunction; + pci_dev_t dev; unsigned short data16; - unsigned int data32; - unsigned char intPin; + unsigned int data32; + unsigned char intPin; + + unsigned int vendorId; + unsigned char HeaderType;
/* Assign first device to ourselves */ - devices[0].bus = 0; - devices[0].device = 0; - devices[0].func = 0; + devices[0].device = PCI_BDF(0,0,0);
crp_read (PCI_CFG_VENDOR_ID, &data32);
devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK; devices[0].device_id = data32 >> 16; devices[0].error = FALSE; - devices[0].bar[NO_BAR].size = 0; /*dummy - required */ + devices[0].bar[NO_BAR].size = 0; /* dummy - required */
nDevices = 1;
nMBars = 0; nIOBars = 0;
- for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++) { - - /*Check whether a device is present */ - if (pci_device_exists (dev) != TRUE) { - - /*Clear error bits in ISR, write 1 to clear */ - REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE - | PCI_ISR_PFE | PCI_ISR_PPE | - PCI_ISR_AHBE); - continue; - } - - /*A device is present, add an entry to the array */ - devices[nDevices].bus = bus; - devices[nDevices].device = dev; - devices[nDevices].func = func; - - pci_read_config_word (dev, PCI_CFG_VENDOR_ID, &data16); - - devices[nDevices].vendor_id = data16; - - pci_read_config_word (dev, PCI_CFG_DEVICE_ID, &data16); - devices[nDevices].device_id = data16; - - /*The device is functioning correctly, set error to FALSE */ - devices[nDevices].error = FALSE; - - /*Figure out what BARs are on this device */ - sys_pci_bar_info_get (nDevices, bus, dev, func); - /*Figure out what INTX# line the card uses */ - pci_read_config_byte (dev, PCI_CFG_DEV_INT_PIN, &intPin); - - /*assign the appropriate irq line */ - if (intPin > PCI_IRQ_LINES) { - devices[nDevices].error = TRUE; - } else if (intPin != 0) { - /*This device uses an interrupt line */ - /*devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1]; */ - devices[nDevices].irq = intPin; + for (busno=0; busno<2; busno++) { + for (devno=0; devno<PCI_MAX_PCI_DEVICES; devno++) { + multifunction = 0; + for (funcno=0; funcno<PCI_MAX_PCI_FUNCTIONS; funcno++) { + dev = PCI_BDF(busno,devno,funcno); + + if (funcno && !multifunction) + break; + + if (pci_read_config_dword(dev, + PCI_CFG_VENDOR_ID, + &vendorId) + == ERROR ){ + if (!funcno) + break; + else + continue; + } + + if (vendorId == 0x0) { + funcno=PCI_MAX_PCI_FUNCTIONS; + continue; + } + + pci_read_config_byte(dev, PCI_HEADER_TYPE, + &HeaderType); + if (funcno == 0) { + if (HeaderType & 0x80) { + multifunction = 1; + } + } + + /* A device is present, add an entry to the + array */ + devices[nDevices].device = dev; + + pci_read_config_word (dev, PCI_CFG_VENDOR_ID, + &data16); + + devices[nDevices].vendor_id = data16; + + pci_read_config_word (dev, PCI_CFG_DEVICE_ID, + &data16); + devices[nDevices].device_id = data16; + + /* The device is functioning correctly, set + error to FALSE */ + devices[nDevices].error = FALSE; + + if ((HeaderType&~0x80)==0) { + /*Figure out what BARs are on this + device */ + sys_pci_bar_info_get (nDevices, dev); + /*Figure out what INTX# line the card + uses */ + pci_read_config_byte (dev, + PCI_CFG_DEV_INT_PIN, + &intPin); + + /*assign the appropriate irq line */ + if (intPin > PCI_IRQ_LINES) { + devices[nDevices].error = TRUE; + } else if (intPin != 0) { + /*This device uses an interrupt + line */ + devices[nDevices].irq = + pciTranslateIrq(dev,intPin); + } + } else { + /* ToDo: Handle bridges */ + } + nDevices++; + } } -#ifdef CONFIG_PCI_SCAN_SHOW - printf ("%06d %03d %03d %04d %08d %08x\n", nDevices, - devices[nDevices].vendor_id); -#endif - nDevices++; - }
calc_bars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE); @@ -426,44 +503,46 @@ void pci_bus_scan (void) | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE); }
-void sys_pci_bar_info_get (unsigned int devnum, - unsigned int bus, - unsigned int dev, unsigned int func) + +void sys_pci_bar_info_get (unsigned int devnum, pci_dev_t dev) { unsigned int data32; unsigned int tmp; unsigned int size; + int bar;
- pci_write_config_dword (devnum, - PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_QUERY); - pci_read_config_dword (devnum, PCI_CFG_BASE_ADDRESS_0, &data32); - - devices[devnum].bar[0].address = (data32 & 1); + for(bar=0; bar<=5; bar++){ + pci_write_config_dword (dev, + PCI_CFG_BASE_ADDRESS_0+(4*bar), + IXP425_PCI_BAR_QUERY); + pci_read_config_dword (dev, PCI_CFG_BASE_ADDRESS_0+(4*bar), + &data32);
- if (data32 & 1) { - /* IO space */ - tmp = data32 & ~0x3; - size = ~(tmp - 1); - devices[devnum].bar[0].size = size; + devices[devnum].bar[dev].address = (data32 & 1);
- if (nIOBars < IXP425_PCI_MAX_BAR) { - ioBars[nIOBars++] = &devices[devnum].bar[0]; - } - } else { - /* Mem space */ - tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; - size = ~(tmp - 1); - devices[devnum].bar[0].size = size; + if (data32 & 1) { + /* IO space */ + tmp = data32 & ~0x3; + size = ~(tmp - 1); + devices[devnum].bar[bar].size = size;
- if (nMBars < IXP425_PCI_MAX_BAR) { - memBars[nMBars++] = &devices[devnum].bar[0]; + if (nIOBars < IXP425_PCI_MAX_BAR) { + ioBars[nIOBars++] = &devices[devnum].bar[bar]; + } } else { - devices[devnum].error = TRUE; - } + /* Mem space */ + tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK; + size = ~(tmp - 1); + devices[devnum].bar[bar].size = size; + + if (nMBars < IXP425_PCI_MAX_BAR) { + memBars[nMBars++] = &devices[devnum].bar[bar]; + } else { + devices[devnum].error = TRUE; + }
+ } } - - devices[devnum].bar[1].size = 0; }
void sortBars (PciBar * Bars[], unsigned int nBars) @@ -497,77 +576,77 @@ void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr) }
for (i = 0; i < nBars; i++) { - Bars[i]->address |= startAddr; - startAddr += Bars[i]->size; + if( Bars[i]->size > 0 ){ + if( startAddr & ((Bars[i]->size)-1) ){ + startAddr |= ((Bars[i]->size)-1); + startAddr += 1; + } + Bars[i]->address |= startAddr; + startAddr += Bars[i]->size; + } } }
void sys_pci_device_bars_write (void) { - unsigned int i; - int addr; + unsigned int i, bar;
for (i = 1; i < nDevices; i++) { if (devices[i].error) { continue; }
- pci_write_config_dword (devices[i].device, - PCI_CFG_BASE_ADDRESS_0, - devices[i].bar[0].address); - addr = BIT (31 - devices[i].device) | - (0 << PCI_NP_AD_FUNCSL) | - (PCI_CFG_BASE_ADDRESS_0 & ~3); - pci_write_config_dword (devices[i].device, - PCI_CFG_DEV_INT_LINE, devices[i].irq); + for(bar=0; bar<5; bar++){ + pci_write_config_dword (devices[i].device, + PCI_CFG_BASE_ADDRESS_0+(4*bar), + devices[i].bar[bar].address); + } + + pci_write_config_byte (devices[i].device, + PCI_CFG_DEV_INT_LINE, devices[i].irq);
pci_write_config_word (devices[i].device, PCI_CFG_COMMAND, INITIAL_PCI_CMD); - } }
-int pci_device_exists (unsigned int deviceNo) +int pci_device_exists (pci_dev_t dev) { unsigned int vendorId; - unsigned int regval;
- pci_read_config_dword (deviceNo, PCI_CFG_VENDOR_ID, &vendorId); + if (pci_read_config_dword(dev, PCI_CFG_VENDOR_ID, + &vendorId) == ERROR) { + return FALSE; + }
- /* There are two ways to find out an empty device. - * 1. check Master Abort bit after the access. - * 2. check whether the vendor id read back is 0x0. - */ - REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, regval); - if ((vendorId != 0x0) && ((regval & PCI_ISR_PFE) == 0)) { + if ( vendorId != 0x0 ) { return TRUE; } - /*no device present, make sure that the master abort bit is reset */
- REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE); return FALSE; }
-pci_dev_t pci_find_devices (struct pci_device_id * ids, int devNo) +pci_dev_t pci_find_devices (struct pci_device_id *ids, int devNo) { - unsigned int i; + unsigned int i,k; unsigned int devdidvid; unsigned int didvid; - unsigned int vendorId, deviceId; - - vendorId = ids->vendor; - deviceId = ids->device; - didvid = ((deviceId << 16) & IXP425_PCI_TOP_WORD_OF_LONG_MASK) | - (vendorId & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);
- for (i = devNo + 1; i < nDevices; i++) { - - pci_read_config_dword (devices[i].device, PCI_CFG_VENDOR_ID, - &devdidvid); - - if (devdidvid == didvid) { - return devices[i].device; + for (i = 1; i < nDevices; i++) { + devdidvid = (devices[i].device_id << 16) + + devices[i].vendor_id; + + for (k = 0; ids[k].vendor != 0; k++) { + didvid = ((ids[k].device << 16) + & IXP425_PCI_TOP_WORD_OF_LONG_MASK); + didvid |= (ids[k].vendor + & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK); + + if (devdidvid == didvid) { + if (devNo-- == 0) + return devices[i].device; + } } } return -1; diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c index ab51f8d..cd3a6f6 100644 --- a/drivers/pci/pci_indirect.c +++ b/drivers/pci/pci_indirect.c @@ -11,7 +11,7 @@
#include <common.h>
-#if (!defined(__I386__) && !defined(CONFIG_IXDP425)) +#if (!defined(__I386__) && !defined(CONFIG_IXP425))
#include <asm/processor.h> #include <asm/io.h> @@ -133,4 +133,4 @@ void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) hose->cfg_data = (unsigned char *) cfg_data; }
-#endif /* !__I386__ && !CONFIG_IXDP425 */ +#endif /* !__I386__ && !CONFIG_IXP425 */ diff --git a/include/asm-arm/arch-ixp/ixp425pci.h b/include/asm-arm/arch-ixp/ixp425pci.h index 9ea3319..e533e90 100644 --- a/include/asm-arm/arch-ixp/ixp425pci.h +++ b/include/asm-arm/arch-ixp/ixp425pci.h @@ -52,9 +52,7 @@ typedef struct
typedef struct { - unsigned int bus; - unsigned int device; - unsigned int func; + pci_dev_t device; unsigned int irq; BOOL error; unsigned short vendor_id; @@ -74,13 +72,13 @@ typedef struct
#define IXP425_PCI_BAR_QUERY 0xffffffff
-#define IXP425_PCI_BAR_MEM_BASE 0x100000 -#define IXP425_PCI_BAR_IO_BASE 0x000000 +#define IXP425_PCI_BAR_MEM_BASE 0x48000000 +#define IXP425_PCI_BAR_IO_BASE 0x00000000 /* not supported */
/*define the maximum number of bus segments - we support a single segment*/ -#define IXP425_PCI_MAX_BUS 1 +#define IXP425_PCI_MAX_BUS 4 /*define the maximum number of cards per bus segment*/ -#define IXP425_PCI_MAX_DEV 4 +#define IXP425_PCI_MAX_DEV 8 /*define the maximum number of functions per device*/ #define IXP425_PCI_MAX_FUNC 8 /* define the maximum number of separate functions that we can @@ -153,7 +151,7 @@ typedef struct /*define the default setting of the AHB memory base reg*/ #define IXP425_PCI_AHBMEMBASE_DEFAULT 0x00010203 #define IXP425_PCI_AHBIOBASE_DEFAULT 0x0 -#define IXP425_PCI_PCIMEMBASE_DEFAULT 0x0 +#define IXP425_PCI_PCIMEMBASE_DEFAULT 0x48494a4b
/*define the default settings for the controller's BARs*/ #ifdef IXP425_PCI_SIMPLE_MAPPING

This fixes conflict existing with IXP425_PCI_SIMPLE_MAPPING. BAR0 and BAR4 were both defined 0, which prevented external bus masters from accessing first 16MByte of main memory.
This is an incrmental patch to patch posted 20081206.
Signed-off-by: Stefan Althoefer stefan.althoefer@web.de --- cpu/ixp/pci.c | 3 +-- include/asm-arm/arch-ixp/ixp425pci.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/cpu/ixp/pci.c b/cpu/ixp/pci.c index 6586ba1..e6afb7b 100644 --- a/cpu/ixp/pci.c +++ b/cpu/ixp/pci.c @@ -340,11 +340,10 @@ void pci_ixp_init (struct pci_controller *hose) REG_WRITE (PCI_CSR_BASE, PCI_PCIMEMBASE_OFFSET, IXP425_PCI_PCIMEMBASE_DEFAULT);
- crp_write (PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM); - REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval); regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS; REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval); + crp_write (PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME); udelay (1000);
diff --git a/include/asm-arm/arch-ixp/ixp425pci.h b/include/asm-arm/arch-ixp/ixp425pci.h index e533e90..2600d0d 100644 --- a/include/asm-arm/arch-ixp/ixp425pci.h +++ b/include/asm-arm/arch-ixp/ixp425pci.h @@ -159,8 +159,8 @@ typedef struct #define IXP425_PCI_BAR_1_DEFAULT 0x01000000 #define IXP425_PCI_BAR_2_DEFAULT 0x02000000 #define IXP425_PCI_BAR_3_DEFAULT 0x03000000 -#define IXP425_PCI_BAR_4_DEFAULT 0x00000000 -#define IXP425_PCI_BAR_5_DEFAULT 0x00000000 +#define IXP425_PCI_BAR_4_DEFAULT 0xff000000 +#define IXP425_PCI_BAR_5_DEFAULT 0xfffff000 #else #define IXP425_PCI_BAR_0_DEFAULT 0x40000000 #define IXP425_PCI_BAR_1_DEFAULT 0x41000000

Dear Stefan Althoefer,
In message ghetg9$bcs$1@ger.gmane.org you wrote:
This patch fixes the PCI handling routines of the IXP port. It seems that this hasn't been touched for quite a while and u-boot PCI handling has changed since then (but nobody update IXP).
Changes (list uncomplete):
- non_prefetched_read/write now return ERROR on (master-) abort.
- fixed pci configuration space access.
- pci_read_config_XXX now return value 0xff even in case of error (as some callers do not check the return value)
- Removed CONFIG_PCI_SCAN_SHOW, as printf is not possible at the time pci_scan is called initially
- fixed some IXP initialization of memory spaces
- fixed address and irq assignment to PCI devices
- fixed pci_find_device
- some reformatting
I think most (all?) of my coding style comments for theold version of this patch still apply and need to be addressed.
Note: I think boards should always define IXP425_PCI_SIMPLE_MAPPING
In this case IXP425_PCI_SIMPLE_MAPPING should be eliminated.
Best regards,
Wolfgang Denk
participants (2)
-
Stefan Althoefer
-
Wolfgang Denk