Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/pci/pci-rt2880.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Ralink RT288x SoC PCI register definitions
4
*
5
* Copyright (C) 2009 John Crispin <[email protected]>
6
* Copyright (C) 2009 Gabor Juhos <[email protected]>
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
44
static u32 rt2880_pci_reg_read(u32 reg)
45
{
46
return readl(rt2880_pci_base + reg);
47
}
48
49
static void rt2880_pci_reg_write(u32 val, u32 reg)
50
{
51
writel(val, rt2880_pci_base + reg);
52
}
53
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
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
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
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
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
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
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
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
267
static 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
279