Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/pci/ops-bcm63xx.c
26439 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 2008 Maxime Bizon <[email protected]>
7
*/
8
9
#include <linux/types.h>
10
#include <linux/pci.h>
11
#include <linux/kernel.h>
12
#include <linux/delay.h>
13
#include <linux/io.h>
14
15
#include "pci-bcm63xx.h"
16
17
/*
18
* swizzle 32bits data to return only the needed part
19
*/
20
static int postprocess_read(u32 data, int where, unsigned int size)
21
{
22
u32 ret;
23
24
ret = 0;
25
switch (size) {
26
case 1:
27
ret = (data >> ((where & 3) << 3)) & 0xff;
28
break;
29
case 2:
30
ret = (data >> ((where & 3) << 3)) & 0xffff;
31
break;
32
case 4:
33
ret = data;
34
break;
35
}
36
return ret;
37
}
38
39
static int preprocess_write(u32 orig_data, u32 val, int where,
40
unsigned int size)
41
{
42
u32 ret;
43
44
ret = 0;
45
switch (size) {
46
case 1:
47
ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
48
(val << ((where & 3) << 3));
49
break;
50
case 2:
51
ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
52
(val << ((where & 3) << 3));
53
break;
54
case 4:
55
ret = val;
56
break;
57
}
58
return ret;
59
}
60
61
/*
62
* setup hardware for a configuration cycle with given parameters
63
*/
64
static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
65
unsigned int devfn, int where)
66
{
67
unsigned int slot, func, reg;
68
u32 val;
69
70
slot = PCI_SLOT(devfn);
71
func = PCI_FUNC(devfn);
72
reg = where >> 2;
73
74
/* sanity check */
75
if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
76
return 1;
77
78
if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
79
return 1;
80
81
if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
82
return 1;
83
84
/* ok, setup config access */
85
val = (reg << MPI_L2PCFG_REG_SHIFT);
86
val |= (func << MPI_L2PCFG_FUNC_SHIFT);
87
val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
88
val |= MPI_L2PCFG_CFG_USEREG_MASK;
89
val |= MPI_L2PCFG_CFG_SEL_MASK;
90
/* type 0 cycle for local bus, type 1 cycle for anything else */
91
if (type != 0) {
92
/* FIXME: how to specify bus ??? */
93
val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
94
}
95
bcm_mpi_writel(val, MPI_L2PCFG_REG);
96
97
return 0;
98
}
99
100
static int bcm63xx_do_cfg_read(int type, unsigned int busn,
101
unsigned int devfn, int where, int size,
102
u32 *val)
103
{
104
u32 data;
105
106
/* two phase cycle, first we write address, then read data at
107
* another location, caller already has a spinlock so no need
108
* to add one here */
109
if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
110
return PCIBIOS_DEVICE_NOT_FOUND;
111
iob();
112
data = le32_to_cpu(__raw_readl(pci_iospace_start));
113
/* restore IO space normal behaviour */
114
bcm_mpi_writel(0, MPI_L2PCFG_REG);
115
116
*val = postprocess_read(data, where, size);
117
118
return PCIBIOS_SUCCESSFUL;
119
}
120
121
static int bcm63xx_do_cfg_write(int type, unsigned int busn,
122
unsigned int devfn, int where, int size,
123
u32 val)
124
{
125
u32 data;
126
127
/* two phase cycle, first we write address, then write data to
128
* another location, caller already has a spinlock so no need
129
* to add one here */
130
if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
131
return PCIBIOS_DEVICE_NOT_FOUND;
132
iob();
133
134
data = le32_to_cpu(__raw_readl(pci_iospace_start));
135
data = preprocess_write(data, val, where, size);
136
137
__raw_writel(cpu_to_le32(data), pci_iospace_start);
138
wmb();
139
/* no way to know the access is done, we have to wait */
140
udelay(500);
141
/* restore IO space normal behaviour */
142
bcm_mpi_writel(0, MPI_L2PCFG_REG);
143
144
return PCIBIOS_SUCCESSFUL;
145
}
146
147
static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
148
int where, int size, u32 *val)
149
{
150
int type;
151
152
type = bus->parent ? 1 : 0;
153
154
if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
155
return PCIBIOS_DEVICE_NOT_FOUND;
156
157
return bcm63xx_do_cfg_read(type, bus->number, devfn,
158
where, size, val);
159
}
160
161
static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
162
int where, int size, u32 val)
163
{
164
int type;
165
166
type = bus->parent ? 1 : 0;
167
168
if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
169
return PCIBIOS_DEVICE_NOT_FOUND;
170
171
return bcm63xx_do_cfg_write(type, bus->number, devfn,
172
where, size, val);
173
}
174
175
struct pci_ops bcm63xx_pci_ops = {
176
.read = bcm63xx_pci_read,
177
.write = bcm63xx_pci_write
178
};
179
180
#ifdef CONFIG_CARDBUS
181
/*
182
* emulate configuration read access on a cardbus bridge
183
*/
184
#define FAKE_CB_BRIDGE_SLOT 0x1e
185
186
static int fake_cb_bridge_bus_number = -1;
187
188
static struct {
189
u16 pci_command;
190
u8 cb_latency;
191
u8 subordinate_busn;
192
u8 cardbus_busn;
193
u8 pci_busn;
194
int bus_assigned;
195
u16 bridge_control;
196
197
u32 mem_base0;
198
u32 mem_limit0;
199
u32 mem_base1;
200
u32 mem_limit1;
201
202
u32 io_base0;
203
u32 io_limit0;
204
u32 io_base1;
205
u32 io_limit1;
206
} fake_cb_bridge_regs;
207
208
static int fake_cb_bridge_read(int where, int size, u32 *val)
209
{
210
unsigned int reg;
211
u32 data;
212
213
data = 0;
214
reg = where >> 2;
215
switch (reg) {
216
case (PCI_VENDOR_ID >> 2):
217
case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
218
/* create dummy vendor/device id from our cpu id */
219
data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
220
break;
221
222
case (PCI_COMMAND >> 2):
223
data = (PCI_STATUS_DEVSEL_SLOW << 16);
224
data |= fake_cb_bridge_regs.pci_command;
225
break;
226
227
case (PCI_CLASS_REVISION >> 2):
228
data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
229
break;
230
231
case (PCI_CACHE_LINE_SIZE >> 2):
232
data = (PCI_HEADER_TYPE_CARDBUS << 16);
233
break;
234
235
case (PCI_INTERRUPT_LINE >> 2):
236
/* bridge control */
237
data = (fake_cb_bridge_regs.bridge_control << 16);
238
/* pin:intA line:0xff */
239
data |= (0x1 << 8) | 0xff;
240
break;
241
242
case (PCI_CB_PRIMARY_BUS >> 2):
243
data = (fake_cb_bridge_regs.cb_latency << 24);
244
data |= (fake_cb_bridge_regs.subordinate_busn << 16);
245
data |= (fake_cb_bridge_regs.cardbus_busn << 8);
246
data |= fake_cb_bridge_regs.pci_busn;
247
break;
248
249
case (PCI_CB_MEMORY_BASE_0 >> 2):
250
data = fake_cb_bridge_regs.mem_base0;
251
break;
252
253
case (PCI_CB_MEMORY_LIMIT_0 >> 2):
254
data = fake_cb_bridge_regs.mem_limit0;
255
break;
256
257
case (PCI_CB_MEMORY_BASE_1 >> 2):
258
data = fake_cb_bridge_regs.mem_base1;
259
break;
260
261
case (PCI_CB_MEMORY_LIMIT_1 >> 2):
262
data = fake_cb_bridge_regs.mem_limit1;
263
break;
264
265
case (PCI_CB_IO_BASE_0 >> 2):
266
/* | 1 for 32bits io support */
267
data = fake_cb_bridge_regs.io_base0 | 0x1;
268
break;
269
270
case (PCI_CB_IO_LIMIT_0 >> 2):
271
data = fake_cb_bridge_regs.io_limit0;
272
break;
273
274
case (PCI_CB_IO_BASE_1 >> 2):
275
/* | 1 for 32bits io support */
276
data = fake_cb_bridge_regs.io_base1 | 0x1;
277
break;
278
279
case (PCI_CB_IO_LIMIT_1 >> 2):
280
data = fake_cb_bridge_regs.io_limit1;
281
break;
282
}
283
284
*val = postprocess_read(data, where, size);
285
return PCIBIOS_SUCCESSFUL;
286
}
287
288
/*
289
* emulate configuration write access on a cardbus bridge
290
*/
291
static int fake_cb_bridge_write(int where, int size, u32 val)
292
{
293
unsigned int reg;
294
u32 data, tmp;
295
int ret;
296
297
ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
298
if (ret != PCIBIOS_SUCCESSFUL)
299
return ret;
300
301
data = preprocess_write(data, val, where, size);
302
303
reg = where >> 2;
304
switch (reg) {
305
case (PCI_COMMAND >> 2):
306
fake_cb_bridge_regs.pci_command = (data & 0xffff);
307
break;
308
309
case (PCI_CB_PRIMARY_BUS >> 2):
310
fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
311
fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
312
fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
313
fake_cb_bridge_regs.pci_busn = data & 0xff;
314
if (fake_cb_bridge_regs.cardbus_busn)
315
fake_cb_bridge_regs.bus_assigned = 1;
316
break;
317
318
case (PCI_INTERRUPT_LINE >> 2):
319
tmp = (data >> 16) & 0xffff;
320
/* disable memory prefetch support */
321
tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
322
tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
323
fake_cb_bridge_regs.bridge_control = tmp;
324
break;
325
326
case (PCI_CB_MEMORY_BASE_0 >> 2):
327
fake_cb_bridge_regs.mem_base0 = data;
328
break;
329
330
case (PCI_CB_MEMORY_LIMIT_0 >> 2):
331
fake_cb_bridge_regs.mem_limit0 = data;
332
break;
333
334
case (PCI_CB_MEMORY_BASE_1 >> 2):
335
fake_cb_bridge_regs.mem_base1 = data;
336
break;
337
338
case (PCI_CB_MEMORY_LIMIT_1 >> 2):
339
fake_cb_bridge_regs.mem_limit1 = data;
340
break;
341
342
case (PCI_CB_IO_BASE_0 >> 2):
343
fake_cb_bridge_regs.io_base0 = data;
344
break;
345
346
case (PCI_CB_IO_LIMIT_0 >> 2):
347
fake_cb_bridge_regs.io_limit0 = data;
348
break;
349
350
case (PCI_CB_IO_BASE_1 >> 2):
351
fake_cb_bridge_regs.io_base1 = data;
352
break;
353
354
case (PCI_CB_IO_LIMIT_1 >> 2):
355
fake_cb_bridge_regs.io_limit1 = data;
356
break;
357
}
358
359
return PCIBIOS_SUCCESSFUL;
360
}
361
362
static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
363
int where, int size, u32 *val)
364
{
365
/* snoop access to slot 0x1e on root bus, we fake a cardbus
366
* bridge at this location */
367
if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
368
fake_cb_bridge_bus_number = bus->number;
369
return fake_cb_bridge_read(where, size, val);
370
}
371
372
/* a configuration cycle for the device behind the cardbus
373
* bridge is actually done as a type 0 cycle on the primary
374
* bus. This means that only one device can be on the cardbus
375
* bus */
376
if (fake_cb_bridge_regs.bus_assigned &&
377
bus->number == fake_cb_bridge_regs.cardbus_busn &&
378
PCI_SLOT(devfn) == 0)
379
return bcm63xx_do_cfg_read(0, 0,
380
PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
381
where, size, val);
382
383
return PCIBIOS_DEVICE_NOT_FOUND;
384
}
385
386
static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
387
int where, int size, u32 val)
388
{
389
if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
390
fake_cb_bridge_bus_number = bus->number;
391
return fake_cb_bridge_write(where, size, val);
392
}
393
394
if (fake_cb_bridge_regs.bus_assigned &&
395
bus->number == fake_cb_bridge_regs.cardbus_busn &&
396
PCI_SLOT(devfn) == 0)
397
return bcm63xx_do_cfg_write(0, 0,
398
PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
399
where, size, val);
400
401
return PCIBIOS_DEVICE_NOT_FOUND;
402
}
403
404
struct pci_ops bcm63xx_cb_ops = {
405
.read = bcm63xx_cb_read,
406
.write = bcm63xx_cb_write,
407
};
408
409
/*
410
* only one IO window, so it cannot be shared by PCI and cardbus, use
411
* fixup to choose and detect unhandled configuration
412
*/
413
static void bcm63xx_fixup(struct pci_dev *dev)
414
{
415
static int io_window = -1;
416
int found, new_io_window;
417
struct resource *r;
418
u32 val;
419
420
/* look for any io resource */
421
found = 0;
422
pci_dev_for_each_resource(dev, r) {
423
if (resource_type(r) == IORESOURCE_IO) {
424
found = 1;
425
break;
426
}
427
}
428
if (!found)
429
return;
430
431
/* skip our fake bus with only cardbus bridge on it */
432
if (dev->bus->number == fake_cb_bridge_bus_number)
433
return;
434
435
/* find on which bus the device is */
436
if (fake_cb_bridge_regs.bus_assigned &&
437
dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
438
PCI_SLOT(dev->devfn) == 0)
439
new_io_window = 1;
440
else
441
new_io_window = 0;
442
443
if (new_io_window == io_window)
444
return;
445
446
if (io_window != -1) {
447
printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
448
"need IO, which hardware cannot do\n");
449
return;
450
}
451
452
printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
453
(new_io_window == 0) ? "PCI" : "cardbus");
454
455
val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
456
if (io_window)
457
val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
458
else
459
val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
460
bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
461
462
io_window = new_io_window;
463
}
464
465
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
466
#endif
467
468
static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
469
{
470
switch (bus->number) {
471
case PCIE_BUS_BRIDGE:
472
return PCI_SLOT(devfn) == 0;
473
case PCIE_BUS_DEVICE:
474
if (PCI_SLOT(devfn) == 0)
475
return bcm_pcie_readl(PCIE_DLSTATUS_REG)
476
& DLSTATUS_PHYLINKUP;
477
fallthrough;
478
default:
479
return false;
480
}
481
}
482
483
static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
484
int where, int size, u32 *val)
485
{
486
u32 data;
487
u32 reg = where & ~3;
488
489
if (!bcm63xx_pcie_can_access(bus, devfn))
490
return PCIBIOS_DEVICE_NOT_FOUND;
491
492
if (bus->number == PCIE_BUS_DEVICE)
493
reg += PCIE_DEVICE_OFFSET;
494
495
data = bcm_pcie_readl(reg);
496
497
*val = postprocess_read(data, where, size);
498
499
return PCIBIOS_SUCCESSFUL;
500
501
}
502
503
static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
504
int where, int size, u32 val)
505
{
506
u32 data;
507
u32 reg = where & ~3;
508
509
if (!bcm63xx_pcie_can_access(bus, devfn))
510
return PCIBIOS_DEVICE_NOT_FOUND;
511
512
if (bus->number == PCIE_BUS_DEVICE)
513
reg += PCIE_DEVICE_OFFSET;
514
515
516
data = bcm_pcie_readl(reg);
517
518
data = preprocess_write(data, val, where, size);
519
bcm_pcie_writel(data, reg);
520
521
return PCIBIOS_SUCCESSFUL;
522
}
523
524
525
struct pci_ops bcm63xx_pcie_ops = {
526
.read = bcm63xx_pcie_read,
527
.write = bcm63xx_pcie_write
528
};
529
530