166fa1cf9756d67c2564719c51b48e144d41e6f1
[openwrt/svn-archive/archive.git] / target / linux / atheros / files-2.6.26 / arch / mips / atheros / ar5315 / pci.c
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17 #include <linux/types.h>
18 #include <linux/pci.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/mm.h>
22 #include <linux/spinlock.h>
23 #include <linux/delay.h>
24 #include <linux/irq.h>
25 #include <asm/bootinfo.h>
26 #include <asm/paccess.h>
27 #include <asm/irq_cpu.h>
28 #include <asm/io.h>
29 #include "ar531x.h"
30
31 #define AR531X_MEM_BASE 0x80800000UL
32 #define AR531X_MEM_SIZE 0x00ffffffUL
33 #define AR531X_IO_SIZE 0x00007fffUL
34 #define IDSEL_SHIFT 13
35
36 static spinlock_t ar531x_pci_lock = SPIN_LOCK_UNLOCKED;
37 static u32 cfgaddr;
38
39 static int config_access(int busno, int dev, int func, int where, int size, u32 ptr, int write)
40 {
41 u32 address; /* Address to read from */
42 u32 reg;
43 unsigned long flags;
44 int ret = -1;
45 if ((busno != 0) || ((dev != 0) && (dev != 3)) || (func > 2))
46 return ret;
47
48 spin_lock_irqsave(&ar531x_pci_lock, flags);
49
50 /* Select Configuration access */
51 reg = sysRegRead(AR5315_PCI_MISC_CONFIG);
52 reg |= AR5315_PCIMISC_CFG_SEL;
53 sysRegWrite(AR5315_PCI_MISC_CONFIG, reg);
54 (void)sysRegRead(AR5315_PCI_MISC_CONFIG);
55
56 address = (u32)cfgaddr + (1 << (IDSEL_SHIFT + dev)) + (func << 8) + where;
57
58 if (size == 1)
59 address ^= 0x3;
60 else if (size == 2)
61 address ^= 0x2;
62
63 if (write) {
64 if (size == 1)
65 ret = put_dbe(ptr, (u8 *) address);
66 else if (size == 2)
67 ret = put_dbe(ptr, (u16 *) address);
68 else if (size == 4)
69 ret = put_dbe(ptr, (u32 *) address);
70 } else {
71 if (size == 1)
72 ret = get_dbe(*((u32 *)ptr), (u8 *) address);
73 else if (size == 2)
74 ret = get_dbe(*((u32 *)ptr), (u16 *) address);
75 else if (size == 4)
76 ret = get_dbe(*((u32 *)ptr), (u32 *) address);
77 }
78
79 /* Select Memory access */
80 reg = sysRegRead(AR5315_PCI_MISC_CONFIG);
81 reg &= ~AR5315_PCIMISC_CFG_SEL;
82 sysRegWrite(AR5315_PCI_MISC_CONFIG, reg);
83 (void)sysRegRead(AR5315_PCI_MISC_CONFIG);
84
85 spin_unlock_irqrestore(&ar531x_pci_lock, flags);
86
87 if (ret) {
88 *((u32 *)ptr) = 0xffffffff;
89 return PCIBIOS_DEVICE_NOT_FOUND;
90 }
91
92 return PCIBIOS_SUCCESSFUL;
93 }
94
95 static int ar531x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value)
96 {
97 return config_access(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, (u32) value, 0);
98 }
99
100 static int ar531x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
101 {
102 return config_access(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value, 1);
103 }
104
105 struct pci_ops ar531x_pci_ops = {
106 .read = ar531x_pci_read,
107 .write = ar531x_pci_write,
108 };
109
110 static struct resource ar531x_mem_resource = {
111 .name = "AR531x PCI MEM",
112 .start = AR531X_MEM_BASE,
113 .end = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE - 1 + 0x4000000,
114 .flags = IORESOURCE_MEM,
115 };
116
117 static struct resource ar531x_io_resource = {
118 .name = "AR531x PCI I/O",
119 .start = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE,
120 .end = AR531X_MEM_BASE + AR531X_MEM_SIZE - 1,
121 .flags = IORESOURCE_IO,
122 };
123
124 struct pci_controller ar531x_pci_controller = {
125 .pci_ops = &ar531x_pci_ops,
126 .mem_resource = &ar531x_mem_resource,
127 .io_resource = &ar531x_io_resource,
128 .mem_offset = 0x00000000UL,
129 .io_offset = 0x00000000UL,
130 };
131
132 int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
133 {
134 return AR5315_IRQ_LCBUS_PCI;
135 }
136
137 int pcibios_plat_dev_init(struct pci_dev *dev)
138 {
139 u32 reg;
140
141 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 5);
142 pci_write_config_word(dev, 0x40, 0);
143
144 /* Clear any pending Abort or external Interrupts
145 * and enable interrupt processing */
146 reg = sysRegRead(AR5315_PCI_INTEN_REG);
147 reg &= ~AR5315_PCI_INT_ENABLE;
148 sysRegWrite(AR5315_PCI_INTEN_REG, reg);
149
150 reg = sysRegRead(AR5315_PCI_INT_STATUS);
151 reg |= (AR5315_PCI_ABORT_INT | AR5315_PCI_EXT_INT);
152 sysRegWrite(AR5315_PCI_INT_STATUS, reg);
153
154 reg = sysRegRead(AR5315_PCI_INT_MASK);
155 reg |= (AR5315_PCI_EXT_INT | AR5315_PCI_ABORT_INT);
156 sysRegWrite(AR5315_PCI_INT_MASK, reg);
157
158 reg = sysRegRead(AR5315_PCI_INTEN_REG);
159 reg |= AR5315_PCI_INT_ENABLE;
160 sysRegWrite(AR5315_PCI_INTEN_REG, reg);
161
162 return 0;
163 }
164
165 static void ar5315_pci_fixup(struct pci_dev *dev)
166 {
167 struct pci_bus *bus = dev->bus;
168
169 if ((PCI_SLOT(dev->devfn) != 3) || (PCI_FUNC(dev->devfn) != 0) || (bus->number != 0))
170 return;
171
172 #define _DEV bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)
173 printk("PCI: fixing up device %d,%d,%d\n", _DEV);
174 /* fix up mbars */
175 config_access(_DEV, PCI_BASE_ADDRESS_0, 4, HOST_PCI_MBAR0, 1);
176 config_access(_DEV, PCI_BASE_ADDRESS_1, 4, HOST_PCI_MBAR1, 1);
177 config_access(_DEV, PCI_BASE_ADDRESS_2, 4, HOST_PCI_MBAR2, 1);
178 config_access(_DEV, PCI_COMMAND, 4,
179 PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL|
180 PCI_COMMAND_INVALIDATE|PCI_COMMAND_PARITY|PCI_COMMAND_SERR|
181 PCI_COMMAND_FAST_BACK, 1);
182 #undef _DEV
183 }
184 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, ar5315_pci_fixup);
185
186 int __init ar5315_pci_init(void)
187 {
188 u32 reg;
189
190 if (mips_machtype != MACH_ATHEROS_AR2315)
191 return -ENODEV;
192
193 printk("AR531x PCI init... \n");
194
195 cfgaddr = (u32) ioremap_nocache(0x80000000, 1*1024*1024); /* Remap PCI config space */
196 ar531x_pci_controller.io_map_base =
197 (unsigned long) ioremap_nocache(AR531X_MEM_BASE + AR531X_MEM_SIZE, AR531X_IO_SIZE);
198 set_io_port_base(ar531x_pci_controller.io_map_base); /* PCI I/O space */
199
200 reg = sysRegRead(AR5315_RESET);
201 sysRegWrite(AR5315_RESET, reg | AR5315_RESET_PCIDMA);
202
203 udelay(10*1000);
204
205 sysRegWrite(AR5315_RESET, reg & ~AR5315_RESET_PCIDMA);
206 sysRegRead(AR5315_RESET); /* read after */
207
208 udelay(10*1000);
209
210 reg = sysRegRead(AR5315_ENDIAN_CTL);
211 reg |= AR5315_CONFIG_PCIAHB | AR5315_CONFIG_PCIAHB_BRIDGE;
212
213 sysRegWrite(AR5315_ENDIAN_CTL, reg);
214
215 reg = sysRegRead(AR5315_PCICLK);
216 reg = 4;
217 sysRegWrite(AR5315_PCICLK, reg);
218
219 reg = sysRegRead(AR5315_AHB_ARB_CTL);
220 reg |= (ARB_PCI);
221 sysRegWrite(AR5315_AHB_ARB_CTL, reg);
222
223 reg = sysRegRead(AR5315_IF_CTL);
224 reg &= ~(IF_PCI_CLK_MASK | IF_MASK);
225 reg |= (IF_PCI | IF_PCI_HOST | IF_PCI_INTR | (IF_PCI_CLK_OUTPUT_CLK << IF_PCI_CLK_SHIFT));
226
227 sysRegWrite(AR5315_IF_CTL, reg);
228
229 /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */
230 reg = sysRegRead(AR5315_PCI_MISC_CONFIG);
231 reg &= ~(AR5315_PCIMISC_RST_MODE);
232 reg |= AR5315_PCIRST_LOW;
233 sysRegWrite(AR5315_PCI_MISC_CONFIG, reg);
234
235 /* wait for 100 ms */
236 udelay(100*1000);
237
238 /* Bring the PCI out of reset */
239 reg = sysRegRead(AR5315_PCI_MISC_CONFIG);
240 reg &= ~(AR5315_PCIMISC_RST_MODE);
241 reg |= (AR5315_PCIRST_HIGH | AR5315_PCICACHE_DIS | 0x8);
242 sysRegWrite(AR5315_PCI_MISC_CONFIG, reg);
243
244 sysRegWrite(AR5315_PCI_UNCACHE_CFG,
245 0x1E | /* 1GB uncached */
246 (1 << 5) | /* Enable uncached */
247 (0x2 << 30) /* Base: 0x80000000 */
248 );
249 (void)sysRegRead(AR5315_PCI_UNCACHE_CFG); /* flush */
250
251 udelay(500*1000);
252
253 /* dirty hack - anyone with a datasheet that knows the memory map ? */
254 ioport_resource.start = 0x10000000;
255 ioport_resource.end = 0xffffffff;
256 iomem_resource.start = 0x10000000;
257 iomem_resource.end = 0xffffffff;
258
259 register_pci_controller(&ar531x_pci_controller);
260
261 printk("done\n");
262 return 0;
263 }
264
265 arch_initcall(ar5315_pci_init);