diff options
Diffstat (limited to 'arch/mips/pci/ops-bonito64.c')
-rw-r--r-- | arch/mips/pci/ops-bonito64.c | 88 |
1 files changed, 33 insertions, 55 deletions
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c index dc35270b65a2..f742c51acf0d 100644 --- a/arch/mips/pci/ops-bonito64.c +++ b/arch/mips/pci/ops-bonito64.c | |||
@@ -29,83 +29,60 @@ | |||
29 | #define PCI_ACCESS_READ 0 | 29 | #define PCI_ACCESS_READ 0 |
30 | #define PCI_ACCESS_WRITE 1 | 30 | #define PCI_ACCESS_WRITE 1 |
31 | 31 | ||
32 | /* | 32 | #ifdef CONFIG_LEMOTE_FULONG |
33 | * PCI configuration cycle AD bus definition | 33 | #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset)) |
34 | */ | 34 | #define ID_SEL_BEGIN 11 |
35 | /* Type 0 */ | 35 | #else |
36 | #define PCI_CFG_TYPE0_REG_SHF 0 | 36 | #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset)) |
37 | #define PCI_CFG_TYPE0_FUNC_SHF 8 | 37 | #define ID_SEL_BEGIN 10 |
38 | #endif | ||
39 | #define MAX_DEV_NUM (31 - ID_SEL_BEGIN) | ||
38 | 40 | ||
39 | /* Type 1 */ | ||
40 | #define PCI_CFG_TYPE1_REG_SHF 0 | ||
41 | #define PCI_CFG_TYPE1_FUNC_SHF 8 | ||
42 | #define PCI_CFG_TYPE1_DEV_SHF 11 | ||
43 | #define PCI_CFG_TYPE1_BUS_SHF 16 | ||
44 | 41 | ||
45 | static int bonito64_pcibios_config_access(unsigned char access_type, | 42 | static int bonito64_pcibios_config_access(unsigned char access_type, |
46 | struct pci_bus *bus, | 43 | struct pci_bus *bus, |
47 | unsigned int devfn, int where, | 44 | unsigned int devfn, int where, |
48 | u32 * data) | 45 | u32 * data) |
49 | { | 46 | { |
50 | unsigned char busnum = bus->number; | 47 | u32 busnum = bus->number; |
48 | u32 addr, type; | ||
51 | u32 dummy; | 49 | u32 dummy; |
52 | u64 pci_addr; | 50 | void *addrp; |
53 | 51 | int device = PCI_SLOT(devfn); | |
54 | /* Algorithmics Bonito64 system controller. */ | 52 | int function = PCI_FUNC(devfn); |
53 | int reg = where & ~3; | ||
55 | 54 | ||
56 | if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) { | ||
57 | /* We number bus 0 devices from 0..21 */ | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | /* Clear cause register bits */ | ||
62 | BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | | ||
63 | BONITO_PCICMD_MTABORT_CLR); | ||
64 | |||
65 | /* | ||
66 | * Setup pattern to be used as PCI "address" for | ||
67 | * Type 0 cycle | ||
68 | */ | ||
69 | if (busnum == 0) { | 55 | if (busnum == 0) { |
70 | /* IDSEL */ | 56 | /* Type 0 configuration for onboard PCI bus */ |
71 | pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10); | 57 | if (device > MAX_DEV_NUM) |
72 | } else { | 58 | return -1; |
73 | /* Bus number */ | ||
74 | pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF; | ||
75 | |||
76 | /* Device number */ | ||
77 | pci_addr |= | ||
78 | PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF; | ||
79 | } | ||
80 | |||
81 | /* Function (same for Type 0/1) */ | ||
82 | pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF; | ||
83 | |||
84 | /* Register number (same for Type 0/1) */ | ||
85 | pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; | ||
86 | 59 | ||
87 | if (busnum == 0) { | 60 | addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; |
88 | /* Type 0 */ | 61 | type = 0; |
89 | BONITO_PCIMAP_CFG = pci_addr >> 16; | ||
90 | } else { | 62 | } else { |
91 | /* Type 1 */ | 63 | /* Type 1 configuration for offboard PCI bus */ |
92 | BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; | 64 | addr = (busnum << 16) | (device << 11) | (function << 8) | reg; |
65 | type = 0x10000; | ||
93 | } | 66 | } |
94 | 67 | ||
95 | pci_addr &= 0xffff; | 68 | /* Clear aborts */ |
69 | BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR; | ||
70 | |||
71 | BONITO_PCIMAP_CFG = (addr >> 16) | type; | ||
96 | 72 | ||
97 | /* Flush Bonito register block */ | 73 | /* Flush Bonito register block */ |
98 | dummy = BONITO_PCIMAP_CFG; | 74 | dummy = BONITO_PCIMAP_CFG; |
99 | iob(); /* sync */ | 75 | mmiowb(); |
100 | 76 | ||
101 | /* Perform access */ | 77 | addrp = CFG_SPACE_REG(addr & 0xffff); |
102 | if (access_type == PCI_ACCESS_WRITE) { | 78 | if (access_type == PCI_ACCESS_WRITE) { |
103 | *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data; | 79 | writel(cpu_to_le32(*data), addrp); |
104 | 80 | #ifndef CONFIG_LEMOTE_FULONG | |
105 | /* Wait till done */ | 81 | /* Wait till done */ |
106 | while (BONITO_PCIMSTAT & 0xF); | 82 | while (BONITO_PCIMSTAT & 0xF); |
83 | #endif | ||
107 | } else { | 84 | } else { |
108 | *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr); | 85 | *data = le32_to_cpu(readl(addrp)); |
109 | } | 86 | } |
110 | 87 | ||
111 | /* Detect Master/Target abort */ | 88 | /* Detect Master/Target abort */ |
@@ -121,6 +98,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type, | |||
121 | } | 98 | } |
122 | 99 | ||
123 | return 0; | 100 | return 0; |
101 | |||
124 | } | 102 | } |
125 | 103 | ||
126 | 104 | ||