0001
0002
0003
0004
0005
0006
0007 #include <linux/types.h>
0008 #include <linux/pci.h>
0009 #include <linux/kernel.h>
0010 #include <linux/delay.h>
0011 #include <linux/mm.h>
0012 #include <asm/addrspace.h>
0013 #include <linux/vmalloc.h>
0014
0015 #include <lantiq_soc.h>
0016
0017 #include "pci-lantiq.h"
0018
0019 #define LTQ_PCI_CFG_BUSNUM_SHF 16
0020 #define LTQ_PCI_CFG_DEVNUM_SHF 11
0021 #define LTQ_PCI_CFG_FUNNUM_SHF 8
0022
0023 #define PCI_ACCESS_READ 0
0024 #define PCI_ACCESS_WRITE 1
0025
0026 static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
0027 unsigned int devfn, unsigned int where, u32 *data)
0028 {
0029 unsigned long cfg_base;
0030 unsigned long flags;
0031 u32 temp;
0032
0033
0034
0035 if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
0036 || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
0037 return 1;
0038
0039 spin_lock_irqsave(&ebu_lock, flags);
0040
0041 cfg_base = (unsigned long) ltq_pci_mapped_cfg;
0042 cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
0043 LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
0044
0045
0046 if (access_type == PCI_ACCESS_WRITE) {
0047 ltq_w32(swab32(*data), ((u32 *)cfg_base));
0048 } else {
0049 *data = ltq_r32(((u32 *)(cfg_base)));
0050 *data = swab32(*data);
0051 }
0052 wmb();
0053
0054
0055 cfg_base = (unsigned long) ltq_pci_mapped_cfg;
0056 cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
0057 temp = ltq_r32(((u32 *)(cfg_base)));
0058 temp = swab32(temp);
0059 cfg_base = (unsigned long) ltq_pci_mapped_cfg;
0060 cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
0061 ltq_w32(temp, ((u32 *)cfg_base));
0062
0063 spin_unlock_irqrestore(&ebu_lock, flags);
0064
0065 if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
0066 return 1;
0067
0068 return 0;
0069 }
0070
0071 int ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
0072 int where, int size, u32 *val)
0073 {
0074 u32 data = 0;
0075
0076 if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
0077 return PCIBIOS_DEVICE_NOT_FOUND;
0078
0079 if (size == 1)
0080 *val = (data >> ((where & 3) << 3)) & 0xff;
0081 else if (size == 2)
0082 *val = (data >> ((where & 3) << 3)) & 0xffff;
0083 else
0084 *val = data;
0085
0086 return PCIBIOS_SUCCESSFUL;
0087 }
0088
0089 int ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
0090 int where, int size, u32 val)
0091 {
0092 u32 data = 0;
0093
0094 if (size == 4) {
0095 data = val;
0096 } else {
0097 if (ltq_pci_config_access(PCI_ACCESS_READ, bus,
0098 devfn, where, &data))
0099 return PCIBIOS_DEVICE_NOT_FOUND;
0100
0101 if (size == 1)
0102 data = (data & ~(0xff << ((where & 3) << 3))) |
0103 (val << ((where & 3) << 3));
0104 else if (size == 2)
0105 data = (data & ~(0xffff << ((where & 3) << 3))) |
0106 (val << ((where & 3) << 3));
0107 }
0108
0109 if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
0110 return PCIBIOS_DEVICE_NOT_FOUND;
0111
0112 return PCIBIOS_SUCCESSFUL;
0113 }