integrator: rewrite the AP PCI driver
PATCH 1/1 integrator: rewrite the AP PCI driver
The PCI support for the Integrator AP has apparently never been finished and I strongly suspect that it has never worked, so let's fix it. This is a list of the more or less un-splittable changes done in this driver rewrite:
- Replace the register definitions stashed into the config file (!) with a copy if the register file from the Linux kernels arch/arm/include/asm/hardware/pci_v3.h
- Delete the unreadable gigantic macros that perform the config accesses and replace them with copyedited code from Linux arch/arm/mach-integrator/pci_v3.c
- Rewrite the rest of the setup code to use the
v3_[read|write][lwb]() accessors.
- Enable PCI by default in the AP board configuration.
- Fix checkpatch warnings and make code more conformant.
--- board/armltd/integrator/pci.c | 582 ++++++++++++++++++++++---------------- board/armltd/integrator/pci_v3.h | 200 +++++++++++++ include/configs/integratorap.h | 148 +--------- 3 files changed, 538 insertions(+), 392 deletions(-) create mode 100644 board/armltd/integrator/pci_v3.h
board/armltd/integrator/pci.c +332 -250
@@ -14,6 +14,10 @@* ARM Ltd. * Philippe Robin, <[email protected]> * +* (C) Copyright 2011 +* Linaro +* Linus Walleij <[email protected]> +* * See file CREDITS for list of people who contributed to this * project. *
@@ -32,15 +36,53 @@* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ -#include <common.h> #include <pci.h> +#include <asm/io.h> +#include "integrator-sc.h" +#include "pci_v3.h" + +#define INTEGRATOR_BOOT_ROM_BASE 0x20000000 +#define INTEGRATOR_HDR0_SDRAM_BASE 0x80000000 + +/* +* These are in the physical addresses on the CPU side, i.e. +* where we read and write stuff - you don't want to try to +* move these around +*/ +#define PHYS_PCI_MEM_BASE 0x40000000 +#define PHYS_PCI_IO_BASE 0x60000000/* PCI I/O space base */ +#define PHYS_PCI_CONFIG_BASE 0x61000000 +#define PHYS_PCI_V3_BASE 0x62000000/* V360EPC registers */ +#define SZ_256M 0x10000000 + +/* +* These are in the PCI BUS address space +* Set to 0x00000000 in the Linux kernel, 0x40000000 in Boot monitor +* we follow the example of the kernel, because that is the address +* range that devices actually use - what would they be doing at +* 0x40000000? +*/ +#define PCI_BUS_NONMEM_START 0x00000000 +#define PCI_BUS_NONMEM_SIZE SZ_256M + +#define PCI_BUS_PREMEM_START (PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE) +#define PCI_BUS_PREMEM_SIZE SZ_256M + +#if PCI_BUS_NONMEM_START &0x000fffff +#error PCI_BUS_NONMEM_START must be megabyte aligned +#endif +#if PCI_BUS_PREMEM_START &0x000fffff +#error PCI_BUS_PREMEM_START must be megabyte aligned +#endif /* * Initialize PCI Devices, report devices found. */ #ifndef CONFIG_PCI_PNP +#define PCI_ENET0_IOADDR 0x60000000 /* First card in PCI I/O space */ +#define PCI_ENET0_MEMADDR 0x40000000 /* First card in PCI memory space */ static struct pci_config_table pci_integrator_config_table[] = { { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID, pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
@@ -51,163 +93,187 @@ static struct pci_config_table pci_integrator_config_table[] = {#endif /* CONFIG_PCI_PNP */ /* V3 access routines */ -#define _V3Write16 (o,v) (*(volatile unsigned short *)(PCI_V3_BASE + (unsigned int)(o)) = (unsigned short)(v)) -#define _V3Read16 (o) (*(volatile unsigned short *)(PCI_V3_BASE + (unsigned int)(o))) - -#define _V3Write32 (o,v) (*(volatile unsigned int *)(PCI_V3_BASE + (unsigned int)(o)) = (unsigned int)(v)) -#define _V3Read32 (o) (*(volatile unsigned int *)(PCI_V3_BASE + (unsigned int)(o))) - -/* Compute address necessary to access PCI config space for the given */ -/* bus and device. */ -#define PCI_CONFIG_ADDRESS ( __bus, __devfn, __offset ) ({ \ - unsigned int __address, __devicebit; \ - unsigned short __mapaddress; \ - unsigned int __dev = PCI_DEV (__devfn);/* FIXME to check!! (slot?) */ \ - \ -if (__bus ==0 ) { \ -/* local bus segment so need a type 0 config cycle */ \ -/* build the PCI configuration "address" with one-hot in A31-A11 */ \ - __address =PCI_CONFIG_BASE ; \ - __address |= ((__devfn &0x07 ) <<8 ); \ - __address |= __offset &0xFF ; \ - __mapaddress =0x000A ;/* 101=>config cycle, 0=>A1=A0=0 */ \ - __devicebit = (1 << (__dev +11 )); \ - \ -if ((__devicebit &0xFF000000 ) !=0 ) { \ -/* high order bits are handled by the MAP register */ \ - __mapaddress |= (__devicebit >>16 ); \ - }else { \ -/* low order bits handled directly in the address */ \ - __address |= __devicebit; \ - } \ - }else {/* bus !=0 */ \ -/* not the local bus segment so need a type 1 config cycle */ \ -/* A31-A24 are don't care (so clear to 0) */ \ - __mapaddress =0x000B ;/* 101=>config cycle, 1=>A1&A0 from PCI_CFG */ \ - __address =PCI_CONFIG_BASE ; \ - __address |= ((__bus &0xFF ) <<16 );/* bits 23..16 = bus number */ \ - __address |= ((__dev &0x1F ) <<11 );/* bits 15..11 = device number */ \ - __address |= ((__devfn &0x07 ) <<8 );/* bits 10..8 = function number */ \ - __address |= __offset &0xFF ;/* bits 7..0 = register number */ \ - } \ -_V3Write16 (V3_LB_MAP1 , __mapaddress); \ - __address; \ -}) - -/* _V3OpenConfigWindow - open V3 configuration window */ -#define _V3OpenConfigWindow () { \ -/* Set up base0 to see all 512Mbytes of memory space (not */ \ -/* prefetchable), this frees up base1 for re-use by configuration*/ \ -/* memory */ \ - \ -_V3Write32 (V3_LB_BASE0 , ((INTEGRATOR_PCI_BASE &0xFFF00000 ) | \ -0x90 |V3_LB_BASE_M_ENABLE )); \ -/* Set up base1 to point into configuration space, note that MAP1 */ \ -/* register is set up by pciMakeConfigAddress(). */ \ - \ -_V3Write32 (V3_LB_BASE1 , ((CPU_PCI_CNFG_ADRS &0xFFF00000 ) | \ -0x40 |V3_LB_BASE_M_ENABLE )); \ +#define v3_writeb (o, v) __raw_writeb(v, PHYS_PCI_V3_BASE + (unsigned int)(o)) +#define v3_readb (o) (__raw_readb(PHYS_PCI_V3_BASE + (unsigned int)(o))) + +#define v3_writew (o, v) __raw_writew(v, PHYS_PCI_V3_BASE + (unsigned int)(o)) +#define v3_readw (o) (__raw_readw(PHYS_PCI_V3_BASE + (unsigned int)(o))) + +#define v3_writel (o, v) __raw_writel(v, PHYS_PCI_V3_BASE + (unsigned int)(o)) +#define v3_readl (o) (__raw_readl(PHYS_PCI_V3_BASE + (unsigned int)(o))) + +static unsigned long v3_open_config_window (pci_dev_t bdf,int offset) +{ +unsigned int address, mapaddress; +unsigned int busnr =PCI_BUS (bdf); +unsigned int devfn =PCI_FUNC (bdf); + +/* +* Trap out illegal values +*/ +if (offset >255 ) +BUG (); +if (busnr >255 ) +BUG (); +if (devfn >255 ) +BUG (); + +if (busnr ==0 ) { +/* +* Linux calls the thing U-Boot calls "DEV" "SLOT" +* instead, but it's the same 5 bits +*/ +int slot =PCI_DEV (bdf); + +/* +* local bus segment so need a type 0 config cycle +* +* build the PCI configuration "address" with one-hot in +* A31-A11 +* +* mapaddress: +* 3:1 = config cycle (101) +* 0 = PCI A1 & A0 are 0 (0) +*/ + address =PCI_FUNC (bdf) <<8 ; + mapaddress =V3_LB_MAP_TYPE_CONFIG ; + +if (slot >12 ) +/* +* high order bits are handled by the MAP register +*/ + mapaddress |=1 << (slot -5 ); +else +/* +* low order bits handled directly in the address +*/ + address |=1 << (slot +11 ); + }else { +/* +* not the local bus segment so need a type 1 config cycle +* +* address: +* 23:16 = bus number +* 15:11 = slot number (7:3 of devfn) +* 10:8 = func number (2:0 of devfn) +* +* mapaddress: +* 3:1 = config cycle (101) +* 0 = PCI A1 & A0 from host bus (1) +*/ + mapaddress =V3_LB_MAP_TYPE_CONFIG |V3_LB_MAP_AD_LOW_EN ; + address = (busnr <<16 ) | (devfn <<8 ); + } + +/* +* Set up base0 to see all 512Mbytes of memory space (not +* prefetchable), this frees up base1 for re-use by +* configuration memory +*/ +v3_writel (V3_LB_BASE0 ,v3_addr_to_lb_base (PHYS_PCI_MEM_BASE ) | +V3_LB_BASE_ADR_SIZE_512MB |V3_LB_BASE_ENABLE ); + +/* +* Set up base1/map1 to point into configuration space. +*/ +v3_writel (V3_LB_BASE1 ,v3_addr_to_lb_base (PHYS_PCI_CONFIG_BASE ) | +V3_LB_BASE_ADR_SIZE_16MB |V3_LB_BASE_ENABLE ); +v3_writew (V3_LB_MAP1 , mapaddress); + +return PHYS_PCI_CONFIG_BASE + address + offset; } -/* _V3CloseConfigWindow - close V3 configuration window */ -#define _V3CloseConfigWindow () { \ -/* Reassign base1 for use by prefetchable PCI memory */ \ -_V3Write32 (V3_LB_BASE1 , (((INTEGRATOR_PCI_BASE +0x10000000 ) &0xFFF00000 ) \ - |0x84 |V3_LB_BASE_M_ENABLE )); \ -_V3Write16 (V3_LB_MAP1 , \ - (((INTEGRATOR_PCI_BASE +0x10000000 ) &0xFFF00000 ) >>16 ) |0x0006 ); \ - \ -/* And shrink base0 back to a 256M window (NOTE: MAP0 already correct) */ \ - \ -_V3Write32 (V3_LB_BASE0 , ((INTEGRATOR_PCI_BASE &0xFFF00000 ) | \ -0x80 |V3_LB_BASE_M_ENABLE )); \ +static void v3_close_config_window (void ) +{ +/* +* Reassign base1 for use by prefetchable PCI memory +*/ +v3_writel (V3_LB_BASE1 ,v3_addr_to_lb_base (PHYS_PCI_MEM_BASE +SZ_256M ) | +V3_LB_BASE_ADR_SIZE_256MB |V3_LB_BASE_PREFETCH | +V3_LB_BASE_ENABLE ); +v3_writew (V3_LB_MAP1 ,v3_addr_to_lb_map (PCI_BUS_PREMEM_START ) | +V3_LB_MAP_TYPE_MEM_MULTIPLE ); + +/* +* And shrink base0 back to a 256M window (NOTE: MAP0 already correct) +*/ +v3_writel (V3_LB_BASE0 ,v3_addr_to_lb_base (PHYS_PCI_MEM_BASE ) | +V3_LB_BASE_ADR_SIZE_256MB |V3_LB_BASE_ENABLE ); } -static int pci_integrator_read_byte (struct pci_controller *hose,pci_dev_t dev, -int offset,unsigned char *val) +static int pci_integrator_read_byte (struct pci_controller *hose,pci_dev_t bdf, +int offset,unsigned char *val) { -_V3OpenConfigWindow (); - *val = *(volatile unsigned char *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset); -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); + *val =__raw_readb (addr); +v3_close_config_window ();return 0 ; } -static int pci_integrator_read__word (struct pci_controller *hose, -pci_dev_t dev,int offset, -unsigned short *val) +static int pci_integrator_read__word (struct pci_controller *hose, +pci_dev_t bdf,int offset, +unsigned short *val) { -_V3OpenConfigWindow (); - *val = *(volatile unsigned short *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset); -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); + *val =__raw_readw (addr); +v3_close_config_window ();return 0 ; } -static int pci_integrator_read_dword (struct pci_controller *hose, -pci_dev_t dev,int offset, -unsigned int *val) +static int pci_integrator_read_dword (struct pci_controller *hose, +pci_dev_t bdf,int offset, +unsigned int *val) { -_V3OpenConfigWindow (); - *val = *(volatile unsigned short *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset); - *val |= (*(volatile unsigned int *) -PCI_CONFIG_ADDRESS (PCI_BUS (dev),PCI_FUNC (dev), - (offset +2 ))) <<16 ; -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); + *val =__raw_readl (addr); +v3_close_config_window ();return 0 ; } -static int pci_integrator_write_byte (struct pci_controller *hose, -pci_dev_t dev,int offset, -unsigned char val) +static int pci_integrator_write_byte (struct pci_controller *hose, +pci_dev_t bdf,int offset, +unsigned char val) { -_V3OpenConfigWindow (); - *(volatile unsigned char *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset) = val; -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); +__raw_writeb ((u8 )val, addr); +__raw_readb (addr); +v3_close_config_window ();return 0 ; } -static int pci_integrator_write_word (struct pci_controller *hose, -pci_dev_t dev,int offset, -unsigned short val) +static int pci_integrator_write_word (struct pci_controller *hose, +pci_dev_t bdf,int offset, +unsigned short val) { -_V3OpenConfigWindow (); - *(volatile unsigned short *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset) = val; -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); +__raw_writew ((u8 )val, addr); +__raw_readw (addr); +v3_close_config_window ();return 0 ; } -static int pci_integrator_write_dword (struct pci_controller *hose, -pci_dev_t dev,int offset, -unsigned int val) +static int pci_integrator_write_dword (struct pci_controller *hose, +pci_dev_t bdf,int offset, +unsigned int val) { -_V3OpenConfigWindow (); - *(volatile unsigned short *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - offset) = (val &0xFFFF ); - *(volatile unsigned short *)PCI_CONFIG_ADDRESS (PCI_BUS (dev), -PCI_FUNC (dev), - (offset +2 )) = ((val >>16 ) &0xFFFF ); -_V3CloseConfigWindow (); +unsigned long addr; + addr =v3_open_config_window (bdf, offset); +__raw_writel ((u8 )val, addr); +__raw_readl (addr); +v3_close_config_window ();return 0 ; } -/****************************** -* PCI initialisation -******************************/ struct pci_controller integrator_hose = {#ifndef CONFIG_PCI_PNP
@@ -215,182 +281,198 @@ struct pci_controller integrator_hose = {#endif }; -void pci_init_board (void ) +void pci_init_board (void ) {volatile int i, j;struct pci_controller *hose = &integrator_hose; +u16 val;/* setting this register will take the V3 out of reset */ - - *(volatile unsigned int *) (INTEGRATOR_SC_PCIENABLE ) =1 ; +__raw_writel (SC_PCI_PCIEN ,SC_PCI );/* wait a few usecs to settle the device and the PCI bus */ for (i =0 ; i <100 ; i++) j = i +1 ; -/* Now write the Base I/O Address Word to V3_BASE + 0x6C */ - - *(volatile unsigned short *) (V3_BASE +V3_LB_IO_BASE ) = - (unsigned short ) (V3_BASE >>16 ); +/* Now write the Base I/O Address Word to PHYS_PCI_V3_BASE + 0x6E */ +v3_writew (V3_LB_IO_BASE , (PHYS_PCI_V3_BASE >>16 )); +/* Wait for the mailbox to settle */ do { - *(volatile unsigned char *) (V3_BASE +V3_MAIL_DATA ) =0xAA ; - *(volatile unsigned char *) (V3_BASE +V3_MAIL_DATA +4 ) = -0x55 ; - }while (*(volatile unsigned char *) (V3_BASE +V3_MAIL_DATA ) !=0xAA - || *(volatile unsigned char *) (V3_BASE +V3_MAIL_DATA + -4 ) !=0x55 ); +v3_writeb (V3_MAIL_DATA ,0xAA ); +v3_writeb (V3_MAIL_DATA +4 ,0x55 ); + }while (v3_readb (V3_MAIL_DATA ) !=0xAA || +v3_readb (V3_MAIL_DATA +4 ) !=0x55 );/* Make sure that V3 register access is not locked, if it is, unlock it */ +if (v3_readw (V3_SYSTEM ) &V3_SYSTEM_M_LOCK ) +v3_writew (V3_SYSTEM ,0xA05F ); -if ((*(volatile unsigned short *) (V3_BASE +V3_SYSTEM ) & -V3_SYSTEM_M_LOCK ) - ==V3_SYSTEM_M_LOCK ) - *(volatile unsigned short *) (V3_BASE +V3_SYSTEM ) =0xA05F ; - -/* Ensure that the slave accesses from PCI are disabled while we */ -/* setup windows */ - - *(volatile unsigned short *) (V3_BASE +V3_PCI_CMD ) &= - ~(V3_COMMAND_M_MEM_EN |V3_COMMAND_M_IO_EN ); +/* +* Ensure that the slave accesses from PCI are disabled while we +* setup memory windows +*/ + val =v3_readw (V3_PCI_CMD ); + val &= ~(V3_COMMAND_M_MEM_EN |V3_COMMAND_M_IO_EN ); +v3_writew (V3_PCI_CMD , val);/* Clear RST_OUT to 0; keep the PCI bus in reset until we've finished */ - - *(volatile unsigned short *) (V3_BASE +V3_SYSTEM ) &= - ~V3_SYSTEM_M_RST_OUT ; + val =v3_readw (V3_SYSTEM ); + val &= ~V3_SYSTEM_M_RST_OUT ; +v3_writew (V3_SYSTEM , val);/* Make all accesses from PCI space retry until we're ready for them */ + val =v3_readw (V3_PCI_CFG ); + val |=V3_PCI_CFG_M_RETRY_EN ; +v3_writew (V3_PCI_CFG , val); - *(volatile unsigned short *) (V3_BASE +V3_PCI_CFG ) |= -V3_PCI_CFG_M_RETRY_EN ; - -/* Set up any V3 PCI Configuration Registers that we absolutely have to */ -/* LB_CFG controls Local Bus protocol. */ -/* Enable LocalBus byte strobes for READ accesses too. */ -/* set bit 7 BE_IMODE and bit 6 BE_OMODE */ - - *(volatile unsigned short *) (V3_BASE +V3_LB_CFG ) |=0x0C0 ; - -/* PCI_CMD controls overall PCI operation. */ -/* Enable PCI bus master. */ - - *(volatile unsigned short *) (V3_BASE +V3_PCI_CMD ) |=0x04 ; +/* +* Set up any V3 PCI Configuration Registers that we absolutely have to. +* LB_CFG controls Local Bus protocol. +* Enable LocalBus byte strobes for READ accesses too. +* set bit 7 BE_IMODE and bit 6 BE_OMODE +*/ + val =v3_readw (V3_LB_CFG ); + val |=0x0C0 ; +v3_writew (V3_LB_CFG , val); -/* PCI_MAP0 controls where the PCI to CPU memory window is on Local Bus */ +/* PCI_CMD controls overall PCI operation. Enable PCI bus master. */ + val =v3_readw (V3_PCI_CMD ); + val |=V3_COMMAND_M_MASTER_EN ; +v3_writew (V3_PCI_CMD , val); - *(volatile unsigned int *) (V3_BASE +V3_PCI_MAP0 ) = - (INTEGRATOR_BOOT_ROM_BASE ) | (V3_PCI_MAP_M_ADR_SIZE_512M | -V3_PCI_MAP_M_REG_EN | -V3_PCI_MAP_M_ENABLE ); +/* +* PCI_MAP0 controls where the PCI to CPU memory window is on +* Local Bus +*/ +v3_writel (V3_PCI_MAP0 , + (INTEGRATOR_BOOT_ROM_BASE ) | (V3_PCI_MAP_M_ADR_SIZE_512MB | +V3_PCI_MAP_M_REG_EN | +V3_PCI_MAP_M_ENABLE ));/* PCI_BASE0 is the PCI address of the start of the window */ - - *(volatile unsigned int *) (V3_BASE +V3_PCI_BASE0 ) = -INTEGRATOR_BOOT_ROM_BASE ; +v3_writel (V3_PCI_BASE0 ,INTEGRATOR_BOOT_ROM_BASE );/* PCI_MAP1 is LOCAL address of the start of the window */ - - *(volatile unsigned int *) (V3_BASE +V3_PCI_MAP1 ) = - (INTEGRATOR_HDR0_SDRAM_BASE ) | (V3_PCI_MAP_M_ADR_SIZE_1024M | -V3_PCI_MAP_M_REG_EN | -V3_PCI_MAP_M_ENABLE ); +v3_writel (V3_PCI_MAP1 , + (INTEGRATOR_HDR0_SDRAM_BASE ) | (V3_PCI_MAP_M_ADR_SIZE_1GB | +V3_PCI_MAP_M_REG_EN | +V3_PCI_MAP_M_ENABLE ));/* PCI_BASE1 is the PCI address of the start of the window */ +v3_writel (V3_PCI_BASE1 ,INTEGRATOR_HDR0_SDRAM_BASE ); - *(volatile unsigned int *) (V3_BASE +V3_PCI_BASE1 ) = -INTEGRATOR_HDR0_SDRAM_BASE ; - -/* Set up the windows from local bus memory into PCI configuration, */ -/* I/O and Memory. */ -/* PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this. */ - - *(volatile unsigned short *) (V3_BASE +V3_LB_BASE2 ) = - ((CPU_PCI_IO_ADRS >>24 ) <<8 ) |V3_LB_BASE_M_ENABLE ; - *(volatile unsigned short *) (V3_BASE +V3_LB_MAP2 ) =0 ; +/* +* Set up memory the windows from local bus memory into PCI +* configuration, I/O and Memory regions. +* PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this. +*/ +v3_writew (V3_LB_BASE2 , +v3_addr_to_lb_map (PHYS_PCI_IO_BASE ) |V3_LB_BASE_ENABLE ); +v3_writew (V3_LB_MAP2 ,0 );/* PCI Configuration, use LB_BASE1/LB_MAP1. */ -/* PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1 */ -/* Map first 256Mbytes as non-prefetchable via BASE0/MAP0 */ -/* (INTEGRATOR_PCI_BASE == PCI_MEM_BASE) */ - - *(volatile unsigned int *) (V3_BASE +V3_LB_BASE0 ) = -INTEGRATOR_PCI_BASE | (0x80 |V3_LB_BASE_M_ENABLE ); - - *(volatile unsigned short *) (V3_BASE +V3_LB_MAP0 ) = - ((INTEGRATOR_PCI_BASE >>20 ) <<0x4 ) |0x0006 ; +/* +* PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1 +* Map first 256Mbytes as non-prefetchable via BASE0/MAP0 +*/ +v3_writel (V3_LB_BASE0 ,v3_addr_to_lb_base (PHYS_PCI_MEM_BASE ) | +V3_LB_BASE_ADR_SIZE_256MB |V3_LB_BASE_ENABLE ); +v3_writew (V3_LB_MAP0 , +v3_addr_to_lb_map (PCI_BUS_NONMEM_START ) |V3_LB_MAP_TYPE_MEM );/* Map second 256 Mbytes as prefetchable via BASE1/MAP1 */ +v3_writel (V3_LB_BASE1 ,v3_addr_to_lb_base (PHYS_PCI_MEM_BASE +SZ_256M ) | +V3_LB_BASE_ADR_SIZE_256MB |V3_LB_BASE_PREFETCH | +V3_LB_BASE_ENABLE ); +v3_writew (V3_LB_MAP1 ,v3_addr_to_lb_map (PCI_BUS_PREMEM_START ) | +V3_LB_MAP_TYPE_MEM_MULTIPLE ); + +/* Dump PCI to local address space mappings */ +debug ("LB_BASE0 = %08x\n" ,v3_readl (V3_LB_BASE0 )); +debug ("LB_MAP0 = %04x\n" ,v3_readw (V3_LB_MAP0 )); +debug ("LB_BASE1 = %08x\n" ,v3_readl (V3_LB_BASE1 )); +debug ("LB_MAP1 = %04x\n" ,v3_readw (V3_LB_MAP1 )); +debug ("LB_BASE2 = %04x\n" ,v3_readw (V3_LB_BASE2 )); +debug ("LB_MAP2 = %04x\n" ,v3_readw (V3_LB_MAP2 )); +debug ("LB_IO_BASE = %04x\n" ,v3_readw (V3_LB_IO_BASE )); - *(volatile unsigned int *) (V3_BASE +V3_LB_BASE1 ) = -INTEGRATOR_PCI_BASE | (0x84 |V3_LB_BASE_M_ENABLE ); - - *(volatile unsigned short *) (V3_BASE +V3_LB_MAP1 ) = - (((INTEGRATOR_PCI_BASE +0x10000000 ) >>20 ) <<4 ) |0x0006 ; - -/* Allow accesses to PCI Configuration space */ -/* and set up A1, A0 for type 1 config cycles */ - - *(volatile unsigned short *) (V3_BASE +V3_PCI_CFG ) = - ((*(volatile unsigned short *) (V3_BASE +V3_PCI_CFG )) & - ~(V3_PCI_CFG_M_RETRY_EN |V3_PCI_CFG_M_AD_LOW1 )) | -V3_PCI_CFG_M_AD_LOW0 ; - -/* now we can allow in PCI MEMORY accesses */ - - *(volatile unsigned short *) (V3_BASE +V3_PCI_CMD ) = - (*(volatile unsigned short *) (V3_BASE +V3_PCI_CMD )) | -V3_COMMAND_M_MEM_EN ; +/* +* Allow accesses to PCI Configuration space and set up A1, A0 for +* type 1 config cycles +*/ + val =v3_readw (V3_PCI_CFG ); + val &= ~(V3_PCI_CFG_M_RETRY_EN |V3_PCI_CFG_M_AD_LOW1 ); + val |=V3_PCI_CFG_M_AD_LOW0 ; +v3_writew (V3_PCI_CFG , val); -/* Set RST_OUT to take the PCI bus is out of reset, PCI devices can */ -/* initialise and lock the V3 system register so that no one else */ -/* can play with it */ +/* now we can allow incoming PCI MEMORY accesses */ + val =v3_readw (V3_PCI_CMD ); + val |=V3_COMMAND_M_MEM_EN ; +v3_writew (V3_PCI_CMD , val); - *(volatile unsigned short *) (V3_BASE +V3_SYSTEM ) = - (*(volatile unsigned short *) (V3_BASE +V3_SYSTEM )) | -V3_SYSTEM_M_RST_OUT ; +/* +* Set RST_OUT to take the PCI bus is out of reset, PCI devices can +* now initialise. +*/ + val =v3_readw (V3_SYSTEM ); + val |=V3_SYSTEM_M_RST_OUT ; +v3_writew (V3_SYSTEM , val); - *(volatile unsigned short *) (V3_BASE +V3_SYSTEM ) = - (*(volatile unsigned short *) (V3_BASE +V3_SYSTEM )) | -V3_SYSTEM_M_LOCK ; +/* Lock the V3 system register so that no one else can play with it */ + val =v3_readw (V3_SYSTEM ); + val |=V3_SYSTEM_M_LOCK ; +v3_writew (V3_SYSTEM , val);/* -* Register the hose +* Configure and register the PCI hose */ hose->first_busno =0 ; hose->last_busno =0xff ; -/* System memory space */ -pci_set_region (hose->regions +0 , -0x00000000 ,0x40000000 ,0x01000000 , -PCI_REGION_MEM |PCI_REGION_SYS_MEMORY ); +/* System memory space, window 0 256 MB non-prefetchable */ +pci_set_region (hose->regions +0 , +PCI_BUS_NONMEM_START ,PHYS_PCI_MEM_BASE , +SZ_256M , +PCI_REGION_MEM ); -/* PCI Memory - config space */ -pci_set_region (hose->regions +1 , -0x00000000 ,0x62000000 ,0x01000000 ,PCI_REGION_MEM ); - -/* PCI V3 regs */ -pci_set_region (hose->regions +2 , -0x00000000 ,0x61000000 ,0x00080000 ,PCI_REGION_MEM ); +/* System memory space, window 1 256 MB prefetchable */ +pci_set_region (hose->regions +1 , +PCI_BUS_PREMEM_START ,PHYS_PCI_MEM_BASE +SZ_256M , +SZ_256M , +PCI_REGION_MEM | +PCI_REGION_PREFETCH );/* PCI I/O space */ -pci_set_region (hose->regions +3 , -0x00000000 ,0x60000000 ,0x00010000 ,PCI_REGION_IO ); +pci_set_region (hose->regions +2 , +0x00000000 ,PHYS_PCI_IO_BASE ,0x01000000 , +PCI_REGION_IO ); + +/* PCI Memory - config space */ +pci_set_region (hose->regions +3 , +0x00000000 ,PHYS_PCI_CONFIG_BASE ,0x01000000 , +PCI_REGION_MEM ); +/* PCI V3 regs */ +pci_set_region (hose->regions +4 , +0x00000000 ,PHYS_PCI_V3_BASE ,0x01000000 , +PCI_REGION_MEM ); -pci_set_ops (hose, - pci_integrator_read_byte, - pci_integrator_read__word, - pci_integrator_read_dword, - pci_integrator_write_byte, - pci_integrator_write_word, pci_integrator_write_dword); + hose->region_count =5 ; - hose->region_count =4 ; +pci_set_ops (hose, + pci_integrator_read_byte, + pci_integrator_read__word, + pci_integrator_read_dword, + pci_integrator_write_byte, + pci_integrator_write_word, + pci_integrator_write_dword); -pci_register_hose (hose); +pci_register_hose (hose); -pciauto_config_init (hose); -pciauto_config_device (hose,0 ); +pciauto_config_init (hose); +pciauto_config_device (hose,0 ); - hose->last_busno =pci_hose_scan (hose); + hose->last_busno =pci_hose_scan (hose); }
board/armltd/integrator/pci_v3.h new file +200 -0
200 lines not on this page · raw message
include/configs/integratorap.h +6 -142
165 lines not on this page · raw message
Signature · 1 line
1.7.7.6
PATCH 1/1 integrator: rewrite the AP PCI driver
Hi Linus,
Le 30/01/2012 19:36, Linus Walleij a ?crit :
Quoted 20 lines
The PCI support for the Integrator AP has apparently never been finished and I strongly suspect that it has never worked, so let's fix it. This is a list of the more or less un-splittable changes done in this driver rewrite:
- Replace the register definitions stashed into the config file (!) with a copy if the register file from the Linux kernels
arch/arm/include/asm/hardware/pci_v3.h- Delete the unreadable gigantic macros that perform the config accesses and replace them with copyedited code from Linux
arch/arm/mach-integrator/pci_v3.c- Rewrite the rest of the setup code to use the
v3_[read|write][lwb]() accessors.- Enable PCI by default in the AP board configuration.
- Fix checkpatch warnings and make code more conformant.
Quoted 8 lines
Tested-by Will Deacon<[email protected]>Signed-off-by Linus Walleij<[email protected]>--- board/armltd/integrator/pci.c | 582 ++++++++++++++++++++++---------------- board/armltd/integrator/pci_v3.h | 200 +++++++++++++ include/configs/integratorap.h | 148 +--------- 3 files changed, 538 insertions(+), 392 deletions(-)create mode 100644
board/armltd/integrator/pci_v3.h
Considering it is a bugfix that only touches boards maintained by yourself:
Applied to u-boot-arm/master, thanks.
Note: for some reason this patch appears twice in patchwork, with identical content and only different submission dates. I have rejected
http://patchwork.ozlabs.org/patch/138700/ and accepted
http://patchwork.ozlabs.org/patch/138700/ as rejected.
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 integrator: rewrite the AP PCI driver
Le 18/02/2012 16:26, Albert ARIBAUD a ?crit :
Quoted 4 lines
Note: for some reason this patch appears twice in patchwork, with identical content and only different submission dates. I have rejected
http://patchwork.ozlabs.org/patch/138700/ and accepted
http://patchwork.ozlabs.org/patch/138700/ as rejected.
... and accepted http://patchwork.ozlabs.org/patch/138669/, of course.
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 integrator: rewrite the AP PCI driver
Hi again Linus,
Le 18/02/2012 16:27, Albert ARIBAUD a ?crit :
Quoted 8 lines
Le 18/02/2012 16:26, Albert ARIBAUD a ?crit :
Quoted 4 lines
Note: for some reason this patch appears twice in patchwork, with identical content and only different submission dates. I have rejected
http://patchwork.ozlabs.org/patch/138700/ and accepted
http://patchwork.ozlabs.org/patch/138700/ as rejected.... and accepted http://patchwork.ozlabs.org/patch/138669/, of course.
However, I see the following diagnostics now for integratorap_cm920t and integratorap_cm926ejs:
Quoted 2 lines
pci.c: In function 'pci_init_board':
pci.c:474: warning: implicit declaration of function 'pciauto_config_init'
FWIW, I use ELDK4.2.
Amicalement,
Signature · 1 line
Albert.
PATCH 1/1 integrator: rewrite the AP PCI driver
Le 18/02/2012 6:50 PM, Albert ARIBAUD <[email protected]> a ?crit:
Quoted 9 lines
Le 18/02/2012 16:27, Albert ARIBAUD a ?crit :
Quoted 8 lines
Le 18/02/2012 16:26, Albert ARIBAUD a ?crit :
Quoted 4 lines
Note: for some reason this patch appears twice in patchwork, with identical content and only different submission dates. I have rejected
http://patchwork.ozlabs.org/patch/138700/ and accepted
http://patchwork.ozlabs.org/patch/138700/ as rejected.... and accepted http://patchwork.ozlabs.org/patch/138669/, of course.
OK sorry about the confusion, some hiccup when sending off the patch mail.
Quoted 5 lines
However, I see the following diagnostics now for
integratorap_cm920tandintegratorap_cm926ejs:Quoted 2 lines
pci.c: In function 'pci_init_board':
pci.c:474: warning: implicit declaration of function 'pciauto_config_init'
Hm, I never saw that but I will try to reproduce it. Seems like some generic problem that just got exposed by enabling CONFIG_PCI.
Yours,
Linus Walleij