Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/broadcom/bcm2835/bcm2838_pci.c
39566 views
1
/*-
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2020 Dr Robert Harvey Crowston <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*
18
*
19
*/
20
21
/*
22
* BCM2838-compatible PCI-express controller.
23
*
24
* Broadcom likes to give the same chip lots of different names. The name of
25
* this driver is taken from the Raspberry Pi 4 Broadcom 2838 chip.
26
*/
27
28
#include <sys/param.h>
29
#include <sys/systm.h>
30
#include <sys/endian.h>
31
#include <sys/kernel.h>
32
#include <sys/module.h>
33
#include <sys/bus.h>
34
#include <sys/proc.h>
35
#include <sys/rman.h>
36
#include <sys/intr.h>
37
#include <sys/mutex.h>
38
39
#include <dev/ofw/openfirm.h>
40
#include <dev/ofw/ofw_bus.h>
41
#include <dev/ofw/ofw_bus_subr.h>
42
43
#include <dev/pci/pci_host_generic.h>
44
#include <dev/pci/pci_host_generic_fdt.h>
45
#include <dev/pci/pcivar.h>
46
#include <dev/pci/pcireg.h>
47
#include <dev/pci/pcib_private.h>
48
49
#include <machine/bus.h>
50
#include <machine/intr.h>
51
52
#include "pcib_if.h"
53
#include "msi_if.h"
54
55
#define PCI_ID_VAL3 0x43c
56
#define CLASS_SHIFT 0x10
57
#define SUBCLASS_SHIFT 0x8
58
59
#define REG_CONTROLLER_HW_REV 0x406c
60
#define REG_BRIDGE_CTRL 0x9210
61
#define BRIDGE_DISABLE_FLAG 0x1
62
#define BRIDGE_RESET_FLAG 0x2
63
#define REG_PCIE_HARD_DEBUG 0x4204
64
#define REG_DMA_CONFIG 0x4008
65
#define REG_DMA_WINDOW_LOW 0x4034
66
#define REG_DMA_WINDOW_HIGH 0x4038
67
#define REG_DMA_WINDOW_1 0x403c
68
#define REG_BRIDGE_GISB_WINDOW 0x402c
69
#define REG_BRIDGE_STATE 0x4068
70
#define REG_BRIDGE_LINK_STATE 0x00bc
71
#define REG_BUS_WINDOW_LOW 0x400c
72
#define REG_BUS_WINDOW_HIGH 0x4010
73
#define REG_CPU_WINDOW_LOW 0x4070
74
#define REG_CPU_WINDOW_START_HIGH 0x4080
75
#define REG_CPU_WINDOW_END_HIGH 0x4084
76
77
#define REG_MSI_ADDR_LOW 0x4044
78
#define REG_MSI_ADDR_HIGH 0x4048
79
#define REG_MSI_CONFIG 0x404c
80
#define REG_MSI_CLR 0x4508
81
#define REG_MSI_MASK_CLR 0x4514
82
#define REG_MSI_RAISED 0x4500
83
#define REG_MSI_EOI 0x4060
84
#define NUM_MSI 32
85
86
#define REG_EP_CONFIG_CHOICE 0x9000
87
#define REG_EP_CONFIG_DATA 0x8000
88
89
#define L1SS_ENABLE 0x00200000
90
#define CLKREQ_ENABLE 0x2
91
92
/*
93
* The system memory controller can address up to 16 GiB of physical memory
94
* (although at time of writing the largest memory size available for purchase
95
* is 8 GiB). However, the system DMA controller is capable of accessing only a
96
* limited portion of the address space. Worse, the PCI-e controller has further
97
* constraints for DMA, and those limitations are not wholly clear to the
98
* author. NetBSD and Linux allow DMA on the lower 3 GiB of the physical memory,
99
* but experimentation shows DMA performed above 960 MiB results in data
100
* corruption with this driver. The limit of 960 MiB is taken from OpenBSD, but
101
* apparently that value was chosen for satisfying a constraint of an unrelated
102
* peripheral.
103
*
104
* Whatever the true maximum address, 960 MiB works.
105
*/
106
#define DMA_HIGH_LIMIT 0x3c000000
107
#define MAX_MEMORY_LOG2 0x21
108
#define REG_VALUE_DMA_WINDOW_LOW (MAX_MEMORY_LOG2 - 0xf)
109
#define REG_VALUE_DMA_WINDOW_HIGH 0x0
110
#define DMA_WINDOW_ENABLE 0x3000
111
#define REG_VALUE_DMA_WINDOW_CONFIG \
112
(((MAX_MEMORY_LOG2 - 0xf) << 0x1b) | DMA_WINDOW_ENABLE)
113
114
#define REG_VALUE_MSI_CONFIG 0xffe06540
115
116
struct bcm_pcib_irqsrc {
117
struct intr_irqsrc isrc;
118
u_int irq;
119
bool allocated;
120
};
121
122
struct bcm_pcib_softc {
123
struct generic_pcie_fdt_softc base;
124
device_t dev;
125
bus_dma_tag_t dmat;
126
struct mtx config_mtx;
127
struct mtx msi_mtx;
128
struct resource *msi_irq_res;
129
void *msi_intr_cookie;
130
struct bcm_pcib_irqsrc *msi_isrcs;
131
pci_addr_t msi_addr;
132
};
133
134
static struct ofw_compat_data compat_data[] = {
135
{"brcm,bcm2711-pcie", 1},
136
{"brcm,bcm7211-pcie", 1},
137
{"brcm,bcm7445-pcie", 1},
138
{NULL, 0}
139
};
140
141
static int
142
bcm_pcib_probe(device_t dev)
143
{
144
145
if (!ofw_bus_status_okay(dev))
146
return (ENXIO);
147
148
if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
149
return (ENXIO);
150
151
device_set_desc(dev,
152
"BCM2838-compatible PCI-express controller");
153
return (BUS_PROBE_DEFAULT);
154
}
155
156
static bus_dma_tag_t
157
bcm_pcib_get_dma_tag(device_t dev, device_t child)
158
{
159
struct bcm_pcib_softc *sc;
160
161
sc = device_get_softc(dev);
162
return (sc->dmat);
163
}
164
165
static void
166
bcm_pcib_set_reg(struct bcm_pcib_softc *sc, uint32_t reg, uint32_t val)
167
{
168
169
bus_write_4(sc->base.base.res, reg, htole32(val));
170
}
171
172
static uint32_t
173
bcm_pcib_read_reg(struct bcm_pcib_softc *sc, uint32_t reg)
174
{
175
176
return (le32toh(bus_read_4(sc->base.base.res, reg)));
177
}
178
179
static void
180
bcm_pcib_reset_controller(struct bcm_pcib_softc *sc)
181
{
182
uint32_t val;
183
184
val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
185
val = val | BRIDGE_RESET_FLAG | BRIDGE_DISABLE_FLAG;
186
bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
187
188
DELAY(100);
189
190
val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
191
val = val & ~BRIDGE_RESET_FLAG;
192
bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
193
194
DELAY(100);
195
196
bcm_pcib_set_reg(sc, REG_PCIE_HARD_DEBUG, 0);
197
198
DELAY(100);
199
}
200
201
static void
202
bcm_pcib_enable_controller(struct bcm_pcib_softc *sc)
203
{
204
uint32_t val;
205
206
val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
207
val = val & ~BRIDGE_DISABLE_FLAG;
208
bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
209
210
DELAY(100);
211
}
212
213
static int
214
bcm_pcib_check_ranges(device_t dev)
215
{
216
struct bcm_pcib_softc *sc;
217
struct pcie_range *ranges;
218
int error = 0, i;
219
220
sc = device_get_softc(dev);
221
ranges = &sc->base.base.ranges[0];
222
223
/* The first range needs to be non-zero. */
224
if (ranges[0].size == 0) {
225
device_printf(dev, "error: first outbound memory range "
226
"(pci addr: 0x%jx, cpu addr: 0x%jx) has zero size.\n",
227
ranges[0].pci_base, ranges[0].phys_base);
228
error = ENXIO;
229
}
230
231
/*
232
* The controller can actually handle three distinct ranges, but we
233
* only implement support for one.
234
*/
235
for (i = 1; (bootverbose || error) && i < MAX_RANGES_TUPLES; ++i) {
236
if (ranges[i].size > 0)
237
device_printf(dev,
238
"note: outbound memory range %d (pci addr: 0x%jx, "
239
"cpu addr: 0x%jx, size: 0x%jx) will be ignored.\n",
240
i, ranges[i].pci_base, ranges[i].phys_base,
241
ranges[i].size);
242
}
243
244
return (error);
245
}
246
247
static const char *
248
bcm_pcib_link_state_string(uint32_t mode)
249
{
250
251
switch(mode & PCIEM_LINK_STA_SPEED) {
252
case 0:
253
return ("not up");
254
case 1:
255
return ("2.5 GT/s");
256
case 2:
257
return ("5.0 GT/s");
258
case 4:
259
return ("8.0 GT/s");
260
default:
261
return ("unknown");
262
}
263
}
264
265
static bus_addr_t
266
bcm_get_offset_and_prepare_config(struct bcm_pcib_softc *sc, u_int bus,
267
u_int slot, u_int func, u_int reg)
268
{
269
/*
270
* Config for an end point is only available through a narrow window for
271
* one end point at a time. We first tell the controller which end point
272
* we want, then access it through the window.
273
*/
274
uint32_t func_index;
275
276
if (bus == 0 && slot == 0 && func == 0)
277
/*
278
* Special case for root device; its config is always available
279
* through the zero-offset.
280
*/
281
return (reg);
282
283
/* Tell the controller to show us the config in question. */
284
func_index = PCIE_ADDR_OFFSET(bus, slot, func, 0);
285
bcm_pcib_set_reg(sc, REG_EP_CONFIG_CHOICE, func_index);
286
287
return (REG_EP_CONFIG_DATA + reg);
288
}
289
290
static bool
291
bcm_pcib_is_valid_quad(struct bcm_pcib_softc *sc, u_int bus, u_int slot,
292
u_int func, u_int reg)
293
{
294
295
if ((bus < sc->base.base.bus_start) || (bus > sc->base.base.bus_end))
296
return (false);
297
if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
298
return (false);
299
300
if (bus == 0 && slot == 0 && func == 0)
301
return (true);
302
if (bus == 0)
303
/*
304
* Probing other slots and funcs on bus 0 will lock up the
305
* memory controller.
306
*/
307
return (false);
308
309
return (true);
310
}
311
312
static uint32_t
313
bcm_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
314
int bytes)
315
{
316
struct bcm_pcib_softc *sc;
317
bus_addr_t offset;
318
uint32_t data;
319
320
sc = device_get_softc(dev);
321
if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
322
return (~0U);
323
324
mtx_lock(&sc->config_mtx);
325
offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
326
327
switch (bytes) {
328
case 1:
329
data = bus_read_1(sc->base.base.res, offset);
330
break;
331
case 2:
332
data = le16toh(bus_read_2(sc->base.base.res, offset));
333
break;
334
case 4:
335
data = le32toh(bus_read_4(sc->base.base.res, offset));
336
break;
337
default:
338
data = ~0U;
339
break;
340
}
341
342
mtx_unlock(&sc->config_mtx);
343
return (data);
344
}
345
346
static void
347
bcm_pcib_write_config(device_t dev, u_int bus, u_int slot,
348
u_int func, u_int reg, uint32_t val, int bytes)
349
{
350
struct bcm_pcib_softc *sc;
351
uint32_t offset;
352
353
sc = device_get_softc(dev);
354
if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
355
return;
356
357
mtx_lock(&sc->config_mtx);
358
offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
359
360
switch (bytes) {
361
case 1:
362
bus_write_1(sc->base.base.res, offset, val);
363
break;
364
case 2:
365
bus_write_2(sc->base.base.res, offset, htole16(val));
366
break;
367
case 4:
368
bus_write_4(sc->base.base.res, offset, htole32(val));
369
break;
370
default:
371
break;
372
}
373
374
mtx_unlock(&sc->config_mtx);
375
}
376
377
static void
378
bcm_pcib_msi_intr_process(struct bcm_pcib_softc *sc, uint32_t interrupt_bitmap,
379
struct trapframe *tf)
380
{
381
struct bcm_pcib_irqsrc *irqsrc;
382
uint32_t bit, irq;
383
384
while ((bit = ffs(interrupt_bitmap))) {
385
irq = bit - 1;
386
387
/* Acknowledge interrupt. */
388
bcm_pcib_set_reg(sc, REG_MSI_CLR, 1 << irq);
389
390
/* Send EOI. */
391
bcm_pcib_set_reg(sc, REG_MSI_EOI, 1);
392
393
/* Despatch to handler. */
394
irqsrc = &sc->msi_isrcs[irq];
395
if (intr_isrc_dispatch(&irqsrc->isrc, tf))
396
device_printf(sc->dev,
397
"note: unexpected interrupt (%d) triggered.\n",
398
irq);
399
400
/* Done with this interrupt. */
401
interrupt_bitmap = interrupt_bitmap & ~(1 << irq);
402
}
403
}
404
405
static int
406
bcm_pcib_msi_intr(void *arg)
407
{
408
struct bcm_pcib_softc *sc;
409
struct trapframe *tf;
410
uint32_t interrupt_bitmap;
411
412
sc = (struct bcm_pcib_softc *) arg;
413
tf = curthread->td_intr_frame;
414
415
while ((interrupt_bitmap = bcm_pcib_read_reg(sc, REG_MSI_RAISED)))
416
bcm_pcib_msi_intr_process(sc, interrupt_bitmap, tf);
417
418
return (FILTER_HANDLED);
419
}
420
421
static int
422
bcm_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount,
423
device_t *pic, struct intr_irqsrc **srcs)
424
{
425
struct bcm_pcib_softc *sc;
426
int first_int, i;
427
428
sc = device_get_softc(dev);
429
mtx_lock(&sc->msi_mtx);
430
431
/* Find a continguous region of free message-signalled interrupts. */
432
for (first_int = 0; first_int + count < NUM_MSI; ) {
433
for (i = first_int; i < first_int + count; ++i) {
434
if (sc->msi_isrcs[i].allocated)
435
goto next;
436
}
437
goto found;
438
next:
439
first_int = i + 1;
440
}
441
442
/* No appropriate region available. */
443
mtx_unlock(&sc->msi_mtx);
444
device_printf(dev, "warning: failed to allocate %d MSI messages.\n",
445
count);
446
return (ENXIO);
447
448
found:
449
/* Mark the messages as in use. */
450
for (i = 0; i < count; ++i) {
451
sc->msi_isrcs[i + first_int].allocated = true;
452
srcs[i] = &(sc->msi_isrcs[i + first_int].isrc);
453
}
454
455
mtx_unlock(&sc->msi_mtx);
456
*pic = device_get_parent(dev);
457
458
return (0);
459
}
460
461
static int
462
bcm_pcib_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
463
uint64_t *addr, uint32_t *data)
464
{
465
struct bcm_pcib_softc *sc;
466
struct bcm_pcib_irqsrc *msi_msg;
467
468
sc = device_get_softc(dev);
469
msi_msg = (struct bcm_pcib_irqsrc *) isrc;
470
471
*addr = sc->msi_addr;
472
*data = (REG_VALUE_MSI_CONFIG & 0xffff) | msi_msg->irq;
473
return (0);
474
}
475
476
static int
477
bcm_pcib_release_msi(device_t dev, device_t child, int count,
478
struct intr_irqsrc **isrc)
479
{
480
struct bcm_pcib_softc *sc;
481
struct bcm_pcib_irqsrc *msi_isrc;
482
int i;
483
484
sc = device_get_softc(dev);
485
mtx_lock(&sc->msi_mtx);
486
487
for (i = 0; i < count; i++) {
488
msi_isrc = (struct bcm_pcib_irqsrc *) isrc[i];
489
msi_isrc->allocated = false;
490
}
491
492
mtx_unlock(&sc->msi_mtx);
493
return (0);
494
}
495
496
static int
497
bcm_pcib_msi_attach(device_t dev)
498
{
499
struct bcm_pcib_softc *sc;
500
phandle_t node, xref;
501
char const *bcm_name;
502
int error, i, rid;
503
504
sc = device_get_softc(dev);
505
sc->msi_addr = 0xffffffffc;
506
507
/* Clear any pending interrupts. */
508
bcm_pcib_set_reg(sc, REG_MSI_CLR, 0xffffffff);
509
510
rid = 1;
511
sc->msi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
512
RF_ACTIVE);
513
if (sc->msi_irq_res == NULL) {
514
device_printf(dev, "could not allocate MSI irq resource.\n");
515
return (ENXIO);
516
}
517
518
sc->msi_isrcs = malloc(sizeof(*sc->msi_isrcs) * NUM_MSI, M_DEVBUF,
519
M_WAITOK | M_ZERO);
520
521
error = bus_setup_intr(dev, sc->msi_irq_res, INTR_TYPE_BIO |
522
INTR_MPSAFE, bcm_pcib_msi_intr, NULL, sc, &sc->msi_intr_cookie);
523
if (error != 0) {
524
device_printf(dev, "error: failed to setup MSI handler.\n");
525
return (error);
526
}
527
528
bcm_name = device_get_nameunit(dev);
529
for (i = 0; i < NUM_MSI; i++) {
530
sc->msi_isrcs[i].irq = i;
531
error = intr_isrc_register(&sc->msi_isrcs[i].isrc, dev, 0,
532
"%s,%u", bcm_name, i);
533
if (error != 0) {
534
device_printf(dev,
535
"error: failed to register interrupt %d.\n", i);
536
return (error);
537
}
538
}
539
540
node = ofw_bus_get_node(dev);
541
xref = OF_xref_from_node(node);
542
OF_device_register_xref(xref, dev);
543
544
error = intr_msi_register(dev, xref);
545
if (error != 0)
546
return (error);
547
548
mtx_init(&sc->msi_mtx, "bcm_pcib: msi_mtx", NULL, MTX_DEF);
549
550
bcm_pcib_set_reg(sc, REG_MSI_MASK_CLR, 0xffffffff);
551
bcm_pcib_set_reg(sc, REG_MSI_ADDR_LOW, (sc->msi_addr & 0xffffffff) | 1);
552
bcm_pcib_set_reg(sc, REG_MSI_ADDR_HIGH, (sc->msi_addr >> 32));
553
bcm_pcib_set_reg(sc, REG_MSI_CONFIG, REG_VALUE_MSI_CONFIG);
554
555
return (0);
556
}
557
558
static void
559
bcm_pcib_relocate_bridge_window(device_t dev)
560
{
561
/*
562
* In principle an out-of-bounds bridge window could be automatically
563
* adjusted at resource-activation time to lie within the bus address
564
* space by pcib_grow_window(), but that is not possible because the
565
* out-of-bounds resource allocation fails at allocation time. Instead,
566
* we will just fix up the window on the controller here, before it is
567
* re-discovered by pcib_probe_windows().
568
*/
569
570
struct bcm_pcib_softc *sc;
571
pci_addr_t base, size, new_base, new_limit;
572
uint16_t val;
573
574
sc = device_get_softc(dev);
575
576
val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMBASE_1, 2);
577
base = PCI_PPBMEMBASE(0, val);
578
579
val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, 2);
580
size = PCI_PPBMEMLIMIT(0, val) - base;
581
582
new_base = sc->base.base.ranges[0].pci_base;
583
val = (uint16_t) (new_base >> 16);
584
bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMBASE_1, val, 2);
585
586
new_limit = new_base + size;
587
val = (uint16_t) (new_limit >> 16);
588
bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, val, 2);
589
}
590
591
static uint32_t
592
encode_cpu_window_low(pci_addr_t phys_base, bus_size_t size)
593
{
594
595
return (((phys_base >> 0x10) & 0xfff0) |
596
((phys_base + size - 1) & 0xfff00000));
597
}
598
599
static uint32_t
600
encode_cpu_window_start_high(pci_addr_t phys_base)
601
{
602
603
return ((phys_base >> 0x20) & 0xff);
604
}
605
606
static uint32_t
607
encode_cpu_window_end_high(pci_addr_t phys_base, bus_size_t size)
608
{
609
610
return (((phys_base + size - 1) >> 0x20) & 0xff);
611
}
612
613
static int
614
bcm_pcib_attach(device_t dev)
615
{
616
struct bcm_pcib_softc *sc;
617
pci_addr_t phys_base, pci_base;
618
bus_size_t size;
619
uint32_t hardware_rev, bridge_state, link_state, tmp;
620
int error, tries;
621
622
sc = device_get_softc(dev);
623
sc->dev = dev;
624
625
/*
626
* This tag will be used in preference to the one created in
627
* pci_host_generic.c.
628
*/
629
error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
630
1, 0, /* alignment, bounds */
631
DMA_HIGH_LIMIT, /* lowaddr */
632
BUS_SPACE_MAXADDR, /* highaddr */
633
NULL, NULL, /* filter, filterarg */
634
DMA_HIGH_LIMIT, /* maxsize */
635
BUS_SPACE_UNRESTRICTED, /* nsegments */
636
DMA_HIGH_LIMIT, /* maxsegsize */
637
0, /* flags */
638
NULL, NULL, /* lockfunc, lockarg */
639
&sc->dmat);
640
if (error != 0)
641
return (error);
642
643
error = pci_host_generic_setup_fdt(dev);
644
if (error != 0)
645
return (error);
646
647
error = bcm_pcib_check_ranges(dev);
648
if (error != 0)
649
return (error);
650
651
mtx_init(&sc->config_mtx, "bcm_pcib: config_mtx", NULL, MTX_DEF);
652
653
bcm_pcib_reset_controller(sc);
654
655
hardware_rev = bcm_pcib_read_reg(sc, REG_CONTROLLER_HW_REV) & 0xffff;
656
device_printf(dev, "hardware identifies as revision 0x%x.\n",
657
hardware_rev);
658
659
/*
660
* Set PCI->CPU memory window. This encodes the inbound window showing
661
* the system memory to the controller.
662
*/
663
bcm_pcib_set_reg(sc, REG_DMA_WINDOW_LOW, REG_VALUE_DMA_WINDOW_LOW);
664
bcm_pcib_set_reg(sc, REG_DMA_WINDOW_HIGH, REG_VALUE_DMA_WINDOW_HIGH);
665
bcm_pcib_set_reg(sc, REG_DMA_CONFIG, REG_VALUE_DMA_WINDOW_CONFIG);
666
667
bcm_pcib_set_reg(sc, REG_BRIDGE_GISB_WINDOW, 0);
668
bcm_pcib_set_reg(sc, REG_DMA_WINDOW_1, 0);
669
670
bcm_pcib_enable_controller(sc);
671
672
/* Wait for controller to start. */
673
for(tries = 0; ; ++tries) {
674
bridge_state = bcm_pcib_read_reg(sc, REG_BRIDGE_STATE);
675
676
if ((bridge_state & 0x30) == 0x30)
677
/* Controller ready. */
678
break;
679
680
if (tries > 100) {
681
device_printf(dev,
682
"error: controller failed to start.\n");
683
return (ENXIO);
684
}
685
686
DELAY(1000);
687
}
688
689
link_state = bcm_pcib_read_reg(sc, REG_BRIDGE_LINK_STATE) >> 0x10;
690
if (!link_state) {
691
device_printf(dev, "error: controller started but link is not "
692
"up.\n");
693
return (ENXIO);
694
}
695
if (bootverbose)
696
device_printf(dev, "note: reported link speed is %s.\n",
697
bcm_pcib_link_state_string(link_state));
698
699
/*
700
* Set the CPU->PCI memory window. The map in this direction is not 1:1.
701
* Addresses seen by the CPU need to be adjusted to make sense to the
702
* controller as they pass through the window.
703
*/
704
pci_base = sc->base.base.ranges[0].pci_base;
705
phys_base = sc->base.base.ranges[0].phys_base;
706
size = sc->base.base.ranges[0].size;
707
708
bcm_pcib_set_reg(sc, REG_BUS_WINDOW_LOW, pci_base & 0xffffffff);
709
bcm_pcib_set_reg(sc, REG_BUS_WINDOW_HIGH, pci_base >> 32);
710
711
bcm_pcib_set_reg(sc, REG_CPU_WINDOW_LOW,
712
encode_cpu_window_low(phys_base, size));
713
bcm_pcib_set_reg(sc, REG_CPU_WINDOW_START_HIGH,
714
encode_cpu_window_start_high(phys_base));
715
bcm_pcib_set_reg(sc, REG_CPU_WINDOW_END_HIGH,
716
encode_cpu_window_end_high(phys_base, size));
717
718
/*
719
* The controller starts up declaring itself an endpoint; readvertise it
720
* as a bridge.
721
*/
722
bcm_pcib_set_reg(sc, PCI_ID_VAL3,
723
PCIC_BRIDGE << CLASS_SHIFT | PCIS_BRIDGE_PCI << SUBCLASS_SHIFT);
724
725
tmp = bcm_pcib_read_reg(sc, REG_PCIE_HARD_DEBUG);
726
tmp |= CLKREQ_ENABLE;
727
728
if (ofw_bus_has_prop(dev, "brcm,enable-l1ss")) {
729
if (bootverbose)
730
device_printf(dev, "note: enabling L1SS due to OF "
731
"property brcm,enable-l1ss\n");
732
733
tmp |= L1SS_ENABLE;
734
}
735
736
bcm_pcib_set_reg(sc, REG_PCIE_HARD_DEBUG, tmp);
737
DELAY(100);
738
739
bcm_pcib_relocate_bridge_window(dev);
740
741
/* Configure interrupts. */
742
error = bcm_pcib_msi_attach(dev);
743
if (error != 0)
744
return (error);
745
746
/* Done. */
747
device_add_child(dev, "pci", DEVICE_UNIT_ANY);
748
bus_attach_children(dev);
749
return (0);
750
}
751
752
/*
753
* Device method table.
754
*/
755
static device_method_t bcm_pcib_methods[] = {
756
/* Bus interface. */
757
DEVMETHOD(bus_get_dma_tag, bcm_pcib_get_dma_tag),
758
759
/* Device interface. */
760
DEVMETHOD(device_probe, bcm_pcib_probe),
761
DEVMETHOD(device_attach, bcm_pcib_attach),
762
763
/* PCIB interface. */
764
DEVMETHOD(pcib_read_config, bcm_pcib_read_config),
765
DEVMETHOD(pcib_write_config, bcm_pcib_write_config),
766
767
/* MSI interface. */
768
DEVMETHOD(msi_alloc_msi, bcm_pcib_alloc_msi),
769
DEVMETHOD(msi_release_msi, bcm_pcib_release_msi),
770
DEVMETHOD(msi_map_msi, bcm_pcib_map_msi),
771
772
DEVMETHOD_END
773
};
774
775
DEFINE_CLASS_1(pcib, bcm_pcib_driver, bcm_pcib_methods,
776
sizeof(struct bcm_pcib_softc), generic_pcie_fdt_driver);
777
778
DRIVER_MODULE(bcm_pcib, simplebus, bcm_pcib_driver, 0, 0);
779
780
781