xref: /openbmc/linux/arch/mips/pci/pci-rt2880.c (revision 657c45b3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Ralink RT288x SoC PCI register definitions
4  *
5  *  Copyright (C) 2009 John Crispin <john@phrozen.org>
6  *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
7  *
8  *  Parts of this file are based on Ralink's 2.6.21 BSP
9  */
10 
11 #include <linux/delay.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/io.h>
15 #include <linux/init.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/platform_device.h>
18 
19 #include <asm/mach-ralink/rt288x.h>
20 
21 #define RT2880_PCI_BASE		0x00440000
22 #define RT288X_CPU_IRQ_PCI	4
23 
24 #define RT2880_PCI_MEM_BASE	0x20000000
25 #define RT2880_PCI_MEM_SIZE	0x10000000
26 #define RT2880_PCI_IO_BASE	0x00460000
27 #define RT2880_PCI_IO_SIZE	0x00010000
28 
29 #define RT2880_PCI_REG_PCICFG_ADDR	0x00
30 #define RT2880_PCI_REG_PCIMSK_ADDR	0x0c
31 #define RT2880_PCI_REG_BAR0SETUP_ADDR	0x10
32 #define RT2880_PCI_REG_IMBASEBAR0_ADDR	0x18
33 #define RT2880_PCI_REG_CONFIG_ADDR	0x20
34 #define RT2880_PCI_REG_CONFIG_DATA	0x24
35 #define RT2880_PCI_REG_MEMBASE		0x28
36 #define RT2880_PCI_REG_IOBASE		0x2c
37 #define RT2880_PCI_REG_ID		0x30
38 #define RT2880_PCI_REG_CLASS		0x34
39 #define RT2880_PCI_REG_SUBID		0x38
40 #define RT2880_PCI_REG_ARBCTL		0x80
41 
42 static void __iomem *rt2880_pci_base;
43 
rt2880_pci_reg_read(u32 reg)44 static u32 rt2880_pci_reg_read(u32 reg)
45 {
46 	return readl(rt2880_pci_base + reg);
47 }
48 
rt2880_pci_reg_write(u32 val,u32 reg)49 static void rt2880_pci_reg_write(u32 val, u32 reg)
50 {
51 	writel(val, rt2880_pci_base + reg);
52 }
53 
rt2880_pci_get_cfgaddr(unsigned int bus,unsigned int slot,unsigned int func,unsigned int where)54 static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
55 					 unsigned int func, unsigned int where)
56 {
57 	return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
58 		0x80000000);
59 }
60 
rt2880_pci_config_read(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)61 static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
62 				  int where, int size, u32 *val)
63 {
64 	u32 address;
65 	u32 data;
66 
67 	address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
68 					 PCI_FUNC(devfn), where);
69 
70 	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
71 	data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
72 
73 	switch (size) {
74 	case 1:
75 		*val = (data >> ((where & 3) << 3)) & 0xff;
76 		break;
77 	case 2:
78 		*val = (data >> ((where & 3) << 3)) & 0xffff;
79 		break;
80 	case 4:
81 		*val = data;
82 		break;
83 	}
84 
85 	return PCIBIOS_SUCCESSFUL;
86 }
87 
rt2880_pci_config_write(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 val)88 static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
89 				   int where, int size, u32 val)
90 {
91 	u32 address;
92 	u32 data;
93 
94 	address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
95 					 PCI_FUNC(devfn), where);
96 
97 	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
98 	data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
99 
100 	switch (size) {
101 	case 1:
102 		data = (data & ~(0xff << ((where & 3) << 3))) |
103 		       (val << ((where & 3) << 3));
104 		break;
105 	case 2:
106 		data = (data & ~(0xffff << ((where & 3) << 3))) |
107 		       (val << ((where & 3) << 3));
108 		break;
109 	case 4:
110 		data = val;
111 		break;
112 	}
113 
114 	rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
115 
116 	return PCIBIOS_SUCCESSFUL;
117 }
118 
119 static struct pci_ops rt2880_pci_ops = {
120 	.read	= rt2880_pci_config_read,
121 	.write	= rt2880_pci_config_write,
122 };
123 
124 static struct resource rt2880_pci_mem_resource = {
125 	.name	= "PCI MEM space",
126 	.start	= RT2880_PCI_MEM_BASE,
127 	.end	= RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
128 	.flags	= IORESOURCE_MEM,
129 };
130 
131 static struct resource rt2880_pci_io_resource = {
132 	.name	= "PCI IO space",
133 	.start	= RT2880_PCI_IO_BASE,
134 	.end	= RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
135 	.flags	= IORESOURCE_IO,
136 };
137 
138 static struct pci_controller rt2880_pci_controller = {
139 	.pci_ops	= &rt2880_pci_ops,
140 	.mem_resource	= &rt2880_pci_mem_resource,
141 	.io_resource	= &rt2880_pci_io_resource,
142 };
143 
rt2880_pci_read_u32(unsigned long reg)144 static inline u32 rt2880_pci_read_u32(unsigned long reg)
145 {
146 	u32 address;
147 	u32 ret;
148 
149 	address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
150 
151 	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
152 	ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
153 
154 	return ret;
155 }
156 
rt2880_pci_write_u32(unsigned long reg,u32 val)157 static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
158 {
159 	u32 address;
160 
161 	address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
162 
163 	rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
164 	rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
165 }
166 
pcibios_map_irq(const struct pci_dev * dev,u8 slot,u8 pin)167 int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
168 {
169 	int irq = -1;
170 
171 	if (dev->bus->number != 0)
172 		return irq;
173 
174 	switch (PCI_SLOT(dev->devfn)) {
175 	case 0x00:
176 		break;
177 	case 0x11:
178 		irq = RT288X_CPU_IRQ_PCI;
179 		break;
180 	default:
181 		pr_err("%s:%s[%d] trying to alloc unknown pci irq\n",
182 		       __FILE__, __func__, __LINE__);
183 		BUG();
184 		break;
185 	}
186 
187 	return irq;
188 }
189 
rt288x_pci_probe(struct platform_device * pdev)190 static int rt288x_pci_probe(struct platform_device *pdev)
191 {
192 	void __iomem *io_map_base;
193 
194 	rt2880_pci_base = ioremap(RT2880_PCI_BASE, PAGE_SIZE);
195 
196 	io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
197 	rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
198 	set_io_port_base((unsigned long) io_map_base);
199 
200 	ioport_resource.start = RT2880_PCI_IO_BASE;
201 	ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
202 
203 	rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
204 	udelay(1);
205 
206 	rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
207 	rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
208 	rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
209 	rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
210 	rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
211 	rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
212 	rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
213 	rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
214 	rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);
215 
216 	rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
217 	(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
218 
219 	rt2880_pci_controller.of_node = pdev->dev.of_node;
220 
221 	register_pci_controller(&rt2880_pci_controller);
222 	return 0;
223 }
224 
pcibios_plat_dev_init(struct pci_dev * dev)225 int pcibios_plat_dev_init(struct pci_dev *dev)
226 {
227 	static bool slot0_init;
228 
229 	/*
230 	 * Nobody seems to initialize slot 0, but this platform requires it, so
231 	 * do it once when some other slot is being enabled. The PCI subsystem
232 	 * should configure other slots properly, so no need to do anything
233 	 * special for those.
234 	 */
235 	if (!slot0_init && dev->bus->number == 0) {
236 		u16 cmd;
237 		u32 bar0;
238 
239 		slot0_init = true;
240 
241 		pci_bus_write_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0,
242 					   0x08000000);
243 		pci_bus_read_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0,
244 					  &bar0);
245 
246 		pci_bus_read_config_word(dev->bus, 0, PCI_COMMAND, &cmd);
247 		cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
248 		pci_bus_write_config_word(dev->bus, 0, PCI_COMMAND, cmd);
249 	}
250 
251 	return 0;
252 }
253 
254 static const struct of_device_id rt288x_pci_match[] = {
255 	{ .compatible = "ralink,rt288x-pci" },
256 	{},
257 };
258 
259 static struct platform_driver rt288x_pci_driver = {
260 	.probe = rt288x_pci_probe,
261 	.driver = {
262 		.name = "rt288x-pci",
263 		.of_match_table = rt288x_pci_match,
264 	},
265 };
266 
pcibios_init(void)267 int __init pcibios_init(void)
268 {
269 	int ret = platform_driver_register(&rt288x_pci_driver);
270 
271 	if (ret)
272 		pr_info("rt288x-pci: Error registering platform driver!");
273 
274 	return ret;
275 }
276 
277 arch_initcall(pcibios_init);
278