xref: /openbmc/linux/arch/mips/pci/pci-ar724x.c (revision 95e9fd10)
1 /*
2  *  Atheros AR724X PCI host controller driver
3  *
4  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5  *  Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify it
8  *  under the terms of the GNU General Public License version 2 as published
9  *  by the Free Software Foundation.
10  */
11 
12 #include <linux/irq.h>
13 #include <linux/pci.h>
14 #include <asm/mach-ath79/ath79.h>
15 #include <asm/mach-ath79/ar71xx_regs.h>
16 #include <asm/mach-ath79/pci.h>
17 
18 #define AR724X_PCI_CFG_BASE	0x14000000
19 #define AR724X_PCI_CFG_SIZE	0x1000
20 #define AR724X_PCI_CTRL_BASE	(AR71XX_APB_BASE + 0x000f0000)
21 #define AR724X_PCI_CTRL_SIZE	0x100
22 
23 #define AR724X_PCI_MEM_BASE	0x10000000
24 #define AR724X_PCI_MEM_SIZE	0x08000000
25 
26 #define AR724X_PCI_REG_RESET		0x18
27 #define AR724X_PCI_REG_INT_STATUS	0x4c
28 #define AR724X_PCI_REG_INT_MASK		0x50
29 
30 #define AR724X_PCI_RESET_LINK_UP	BIT(0)
31 
32 #define AR724X_PCI_INT_DEV0		BIT(14)
33 
34 #define AR724X_PCI_IRQ_COUNT		1
35 
36 #define AR7240_BAR0_WAR_VALUE	0xffff
37 
38 static DEFINE_SPINLOCK(ar724x_pci_lock);
39 static void __iomem *ar724x_pci_devcfg_base;
40 static void __iomem *ar724x_pci_ctrl_base;
41 
42 static u32 ar724x_pci_bar0_value;
43 static bool ar724x_pci_bar0_is_cached;
44 static bool ar724x_pci_link_up;
45 
46 static inline bool ar724x_pci_check_link(void)
47 {
48 	u32 reset;
49 
50 	reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
51 	return reset & AR724X_PCI_RESET_LINK_UP;
52 }
53 
54 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
55 			    int size, uint32_t *value)
56 {
57 	unsigned long flags;
58 	void __iomem *base;
59 	u32 data;
60 
61 	if (!ar724x_pci_link_up)
62 		return PCIBIOS_DEVICE_NOT_FOUND;
63 
64 	if (devfn)
65 		return PCIBIOS_DEVICE_NOT_FOUND;
66 
67 	base = ar724x_pci_devcfg_base;
68 
69 	spin_lock_irqsave(&ar724x_pci_lock, flags);
70 	data = __raw_readl(base + (where & ~3));
71 
72 	switch (size) {
73 	case 1:
74 		if (where & 1)
75 			data >>= 8;
76 		if (where & 2)
77 			data >>= 16;
78 		data &= 0xff;
79 		break;
80 	case 2:
81 		if (where & 2)
82 			data >>= 16;
83 		data &= 0xffff;
84 		break;
85 	case 4:
86 		break;
87 	default:
88 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
89 
90 		return PCIBIOS_BAD_REGISTER_NUMBER;
91 	}
92 
93 	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
94 
95 	if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
96 	    ar724x_pci_bar0_is_cached) {
97 		/* use the cached value */
98 		*value = ar724x_pci_bar0_value;
99 	} else {
100 		*value = data;
101 	}
102 
103 	return PCIBIOS_SUCCESSFUL;
104 }
105 
106 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
107 			     int size, uint32_t value)
108 {
109 	unsigned long flags;
110 	void __iomem *base;
111 	u32 data;
112 	int s;
113 
114 	if (!ar724x_pci_link_up)
115 		return PCIBIOS_DEVICE_NOT_FOUND;
116 
117 	if (devfn)
118 		return PCIBIOS_DEVICE_NOT_FOUND;
119 
120 	if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
121 		if (value != 0xffffffff) {
122 			/*
123 			 * WAR for a hw issue. If the BAR0 register of the
124 			 * device is set to the proper base address, the
125 			 * memory space of the device is not accessible.
126 			 *
127 			 * Cache the intended value so it can be read back,
128 			 * and write a SoC specific constant value to the
129 			 * BAR0 register in order to make the device memory
130 			 * accessible.
131 			 */
132 			ar724x_pci_bar0_is_cached = true;
133 			ar724x_pci_bar0_value = value;
134 
135 			value = AR7240_BAR0_WAR_VALUE;
136 		} else {
137 			ar724x_pci_bar0_is_cached = false;
138 		}
139 	}
140 
141 	base = ar724x_pci_devcfg_base;
142 
143 	spin_lock_irqsave(&ar724x_pci_lock, flags);
144 	data = __raw_readl(base + (where & ~3));
145 
146 	switch (size) {
147 	case 1:
148 		s = ((where & 3) * 8);
149 		data &= ~(0xff << s);
150 		data |= ((value & 0xff) << s);
151 		break;
152 	case 2:
153 		s = ((where & 2) * 8);
154 		data &= ~(0xffff << s);
155 		data |= ((value & 0xffff) << s);
156 		break;
157 	case 4:
158 		data = value;
159 		break;
160 	default:
161 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
162 
163 		return PCIBIOS_BAD_REGISTER_NUMBER;
164 	}
165 
166 	__raw_writel(data, base + (where & ~3));
167 	/* flush write */
168 	__raw_readl(base + (where & ~3));
169 	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
170 
171 	return PCIBIOS_SUCCESSFUL;
172 }
173 
174 static struct pci_ops ar724x_pci_ops = {
175 	.read	= ar724x_pci_read,
176 	.write	= ar724x_pci_write,
177 };
178 
179 static struct resource ar724x_io_resource = {
180 	.name   = "PCI IO space",
181 	.start  = 0,
182 	.end    = 0,
183 	.flags  = IORESOURCE_IO,
184 };
185 
186 static struct resource ar724x_mem_resource = {
187 	.name   = "PCI memory space",
188 	.start  = AR724X_PCI_MEM_BASE,
189 	.end    = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
190 	.flags  = IORESOURCE_MEM,
191 };
192 
193 static struct pci_controller ar724x_pci_controller = {
194 	.pci_ops        = &ar724x_pci_ops,
195 	.io_resource    = &ar724x_io_resource,
196 	.mem_resource	= &ar724x_mem_resource,
197 };
198 
199 static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
200 {
201 	void __iomem *base;
202 	u32 pending;
203 
204 	base = ar724x_pci_ctrl_base;
205 
206 	pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
207 		  __raw_readl(base + AR724X_PCI_REG_INT_MASK);
208 
209 	if (pending & AR724X_PCI_INT_DEV0)
210 		generic_handle_irq(ATH79_PCI_IRQ(0));
211 
212 	else
213 		spurious_interrupt();
214 }
215 
216 static void ar724x_pci_irq_unmask(struct irq_data *d)
217 {
218 	void __iomem *base;
219 	u32 t;
220 
221 	base = ar724x_pci_ctrl_base;
222 
223 	switch (d->irq) {
224 	case ATH79_PCI_IRQ(0):
225 		t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
226 		__raw_writel(t | AR724X_PCI_INT_DEV0,
227 			     base + AR724X_PCI_REG_INT_MASK);
228 		/* flush write */
229 		__raw_readl(base + AR724X_PCI_REG_INT_MASK);
230 	}
231 }
232 
233 static void ar724x_pci_irq_mask(struct irq_data *d)
234 {
235 	void __iomem *base;
236 	u32 t;
237 
238 	base = ar724x_pci_ctrl_base;
239 
240 	switch (d->irq) {
241 	case ATH79_PCI_IRQ(0):
242 		t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
243 		__raw_writel(t & ~AR724X_PCI_INT_DEV0,
244 			     base + AR724X_PCI_REG_INT_MASK);
245 
246 		/* flush write */
247 		__raw_readl(base + AR724X_PCI_REG_INT_MASK);
248 
249 		t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
250 		__raw_writel(t | AR724X_PCI_INT_DEV0,
251 			     base + AR724X_PCI_REG_INT_STATUS);
252 
253 		/* flush write */
254 		__raw_readl(base + AR724X_PCI_REG_INT_STATUS);
255 	}
256 }
257 
258 static struct irq_chip ar724x_pci_irq_chip = {
259 	.name		= "AR724X PCI ",
260 	.irq_mask	= ar724x_pci_irq_mask,
261 	.irq_unmask	= ar724x_pci_irq_unmask,
262 	.irq_mask_ack	= ar724x_pci_irq_mask,
263 };
264 
265 static void __init ar724x_pci_irq_init(int irq)
266 {
267 	void __iomem *base;
268 	int i;
269 
270 	base = ar724x_pci_ctrl_base;
271 
272 	__raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
273 	__raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
274 
275 	BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
276 
277 	for (i = ATH79_PCI_IRQ_BASE;
278 	     i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
279 		irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
280 					 handle_level_irq);
281 
282 	irq_set_chained_handler(irq, ar724x_pci_irq_handler);
283 }
284 
285 int __init ar724x_pcibios_init(int irq)
286 {
287 	int ret;
288 
289 	ret = -ENOMEM;
290 
291 	ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
292 					 AR724X_PCI_CFG_SIZE);
293 	if (ar724x_pci_devcfg_base == NULL)
294 		goto err;
295 
296 	ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
297 				       AR724X_PCI_CTRL_SIZE);
298 	if (ar724x_pci_ctrl_base == NULL)
299 		goto err_unmap_devcfg;
300 
301 	ar724x_pci_link_up = ar724x_pci_check_link();
302 	if (!ar724x_pci_link_up)
303 		pr_warn("ar724x: PCIe link is down\n");
304 
305 	ar724x_pci_irq_init(irq);
306 	register_pci_controller(&ar724x_pci_controller);
307 
308 	return PCIBIOS_SUCCESSFUL;
309 
310 err_unmap_devcfg:
311 	iounmap(ar724x_pci_devcfg_base);
312 err:
313 	return ret;
314 }
315