From ad776f66af1cf5ec2b6a350e786cc127ae364da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Wed, 13 Nov 2013 11:34:35 +0000 Subject: [PATCH] updated with some PCI code lend from the Linux BSP for Coldfire boards --- include/pci.h | 5 ++- sources/pci.c | 105 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/include/pci.h b/include/pci.h index e14ce25..0c42262 100644 --- a/include/pci.h +++ b/include/pci.h @@ -237,7 +237,10 @@ extern struct pci_rd *pci_get_resource(int32_t handle); extern int32_t pci_hook_interrupt(int32_t handle, void *interrupt_handler, void *parameter); extern int32_t pci_unhook_interrupt(int32_t handle); - +#define PCI_MK_CONF_ADDR(bus, device, function) (MCF_PCI_PCICAR_E | \ + ((bus) << 16) | \ + ((device << 8) | \ + (function)) #define PCI_HANDLE(bus, slot, function) (0 | ((bus & 0xff) << 8 | (slot & 0x1f) << 3 | (function & 7))) #define PCI_BUS_FROM_HANDLE(h) (((h) & 0xff00) >> 8) diff --git a/sources/pci.c b/sources/pci.c index b2ded9c..4c22deb 100644 --- a/sources/pci.c +++ b/sources/pci.c @@ -98,9 +98,7 @@ void chip_errata_135(void) __asm__ __volatile( " .extern __MBAR\n\t" - " bra .start\n\t" " .align 16\n\t" /* force function start to 16-byte boundary */ - ".start:\n\t" " clr.l d0\n\t" " move.l d0,__MBAR+0xF0C\n\t" /* Must use direct addressing. write to EPORT module */ /* xlbus -> slavebus -> eport, writing '0' to register */ @@ -158,44 +156,71 @@ static char *device_class(int classcode) uint32_t pci_read_config_longword(int32_t handle, int offset) { uint32_t value; - uint16_t bus = PCI_BUS_FROM_HANDLE(handle); - uint16_t device = PCI_DEVICE_FROM_HANDLE(handle); - uint16_t function = PCI_FUNCTION_FROM_HANDLE(handle); /* initiate PCI configuration access to device */ MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ - MCF_PCI_PCICAR_BUSNUM(bus) | - MCF_PCI_PCICAR_DEVNUM(device) | /* device number, devices 0 - 9 are reserved */ - MCF_PCI_PCICAR_FUNCNUM(function) | /* function number */ + MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ MCF_PCI_PCICAR_DWORD(offset / 4); - pci_config_wait(); + __asm__ __volatile__("nop"); /* this is what the Linux BSP does */ value = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */ + __asm__ __volatile__("tpf"); /* this is what the Linux BSP does */ + /* finish PCI configuration access special cycle (allow regular PCI accesses) */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - pci_config_wait(); - - chip_errata_135(); return value; } uint16_t pci_read_config_word(int32_t handle, int offset) { - uint32_t value; + uint16_t value; - value = pci_read_config_longword(handle, offset); - return value >> ((1 - offset % 2) * 16) & 0xffff; + /* + * initiate PCI configuration space access to device + */ + MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration space special cycle */ + MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DWORD(offset / 4); + + __asm__ __volatile("nop"); /* this is what Linux BSP does */ + + value = * (volatile uint16_t *) PCI_IO_OFFSET + (offset & 2); + + __asm__ __volatile("tpf"); + + /* finish PCI configuration access special cycle */ + MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + + return value; } uint8_t pci_read_config_byte(int32_t handle, int offset) { - uint32_t value; + uint8_t value; + + /* initiate PCI configuration access to device */ + MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ + MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ + MCF_PCI_PCICAR_DWORD(offset / 4); - value = pci_read_config_longword(handle, offset); - return value >> ((3 - offset % 4) * 8) & 0xff; + __asm__ __volatile__("nop"); + + value = * (volatile uint8_t *) PCI_IO_OFFSET + (offset & 3); + + __asm__ __volatile__("tpf"); + + MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + + return value; } /* @@ -205,26 +230,23 @@ uint8_t pci_read_config_byte(int32_t handle, int offset) */ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value) { - uint16_t bus = PCI_BUS_FROM_HANDLE(handle); - uint16_t device = PCI_DEVICE_FROM_HANDLE(handle); - uint16_t function = PCI_FUNCTION_FROM_HANDLE(handle); - /* initiate PCI configuration access to device */ MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ - MCF_PCI_PCICAR_BUSNUM(bus) | - MCF_PCI_PCICAR_DEVNUM(device) | /* device number, devices 0 - 9 are reserved */ - MCF_PCI_PCICAR_FUNCNUM(function) | /* function number */ - MCF_PCI_PCICAR_DWORD(offset / 4); + MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ + MCF_PCI_PCICAR_DWORD(offset / 4); - pci_config_wait(); + __asm__ __volatile__("tpf"); * (volatile uint32_t *) PCI_IO_OFFSET = value; /* access device */ - pci_config_wait(); + __asm__ __volatile__("tpf"); /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - pci_config_wait(); + + chip_errata_135(); return PCI_SUCCESSFUL; } @@ -234,22 +256,19 @@ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value) */ int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value) { - uint16_t bus = PCI_BUS_FROM_HANDLE(handle); - uint16_t device = PCI_DEVICE_FROM_HANDLE(handle); - uint16_t function = PCI_FUNCTION_FROM_HANDLE(handle); - /* initiate PCI configuration access to device */ MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ - MCF_PCI_PCICAR_BUSNUM(bus) | - MCF_PCI_PCICAR_DEVNUM(device) | - MCF_PCI_PCICAR_FUNCNUM(function) | + MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | MCF_PCI_PCICAR_DWORD(offset / 4); - pci_config_wait(); + __asm__ __volatile__("tpf"); - * (volatile uint16_t *) (PCI_IO_OFFSET + offset % 2) = value; + * (volatile uint16_t *) (PCI_IO_OFFSET + (offset & 2)) = value; - pci_config_wait(); + __asm__ __volatile__("tpf"); + /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; @@ -267,13 +286,15 @@ int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value) MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | MCF_PCI_PCICAR_DWORD(offset / 4); - pci_config_wait(); + __asm__ __volatile__("tpf"); - * (volatile uint8_t *) (PCI_IO_OFFSET + offset % 4) = value; + * (volatile uint8_t *) (PCI_IO_OFFSET + (offset & 3)) = value; + + __asm__ __volatile__("tpf"); - pci_config_wait(); /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + chip_errata_135(); return PCI_SUCCESSFUL; }