Deleted Added
full compact
mv_pci.c (239277) mv_pci.c (240489)
1/*-
2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
3 * Copyright (c) 2010 The FreeBSD Foundation
1/*-
2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
3 * Copyright (c) 2010 The FreeBSD Foundation
4 * Copyright (c) 2010-2012 Semihalf
4 * All rights reserved.
5 *
6 * Developed by Semihalf.
7 *
8 * Portions of this software were developed by Semihalf
9 * under sponsorship from the FreeBSD Foundation.
10 *
11 * Redistribution and use in source and binary forms, with or without

--- 21 unchanged lines hidden (view full) ---

33 * SUCH DAMAGE.
34 */
35
36/*
37 * Marvell integrated PCI/PCI-Express controller driver.
38 */
39
40#include <sys/cdefs.h>
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *
9 * Portions of this software were developed by Semihalf
10 * under sponsorship from the FreeBSD Foundation.
11 *
12 * Redistribution and use in source and binary forms, with or without

--- 21 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37/*
38 * Marvell integrated PCI/PCI-Express controller driver.
39 */
40
41#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 239277 2012-08-15 05:15:49Z gonzo $");
42__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240489 2012-09-14 09:57:41Z gber $");
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>
48#include <sys/module.h>
49#include <sys/mutex.h>

--- 34 unchanged lines hidden (view full) ---

84
85#define PCIE_REG_CFG_ADDR 0x18F8
86#define PCIE_REG_CFG_DATA 0x18FC
87#define PCIE_REG_CONTROL 0x1A00
88#define PCIE_CTRL_LINK1X 0x00000001
89#define PCIE_REG_STATUS 0x1A04
90#define PCIE_REG_IRQ_MASK 0x1910
91
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/lock.h>
48#include <sys/malloc.h>
49#include <sys/module.h>
50#include <sys/mutex.h>

--- 34 unchanged lines hidden (view full) ---

85
86#define PCIE_REG_CFG_ADDR 0x18F8
87#define PCIE_REG_CFG_DATA 0x18FC
88#define PCIE_REG_CONTROL 0x1A00
89#define PCIE_CTRL_LINK1X 0x00000001
90#define PCIE_REG_STATUS 0x1A04
91#define PCIE_REG_IRQ_MASK 0x1910
92
92#define STATUS_LINK_DOWN 1
93#define STATUS_BUS_OFFS 8
94#define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS)
95#define STATUS_DEV_OFFS 16
96#define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS)
93#define PCIE_CONTROL_ROOT_CMPLX (1 << 1)
94#define PCIE_CONTROL_HOT_RESET (1 << 24)
97
95
98#define P2P_CONF_BUS_OFFS 16
99#define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS)
100#define P2P_CONF_DEV_OFFS 24
101#define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS)
96#define PCIE_LINK_TIMEOUT 1000000
102
97
103#define PCI_VENDORID_MRVL 0x11AB
98#define PCIE_STATUS_LINK_DOWN 1
99#define PCIE_STATUS_DEV_OFFS 16
104
100
101/* Minimum PCI Memory and I/O allocations taken from PCI spec (in bytes) */
102#define PCI_MIN_IO_ALLOC 4
103#define PCI_MIN_MEM_ALLOC 16
104
105#define BITS_PER_UINT32 (NBBY * sizeof(uint32_t))
106
105struct mv_pcib_softc {
106 device_t sc_dev;
107
108 struct rman sc_mem_rman;
109 bus_addr_t sc_mem_base;
110 bus_addr_t sc_mem_size;
107struct mv_pcib_softc {
108 device_t sc_dev;
109
110 struct rman sc_mem_rman;
111 bus_addr_t sc_mem_base;
112 bus_addr_t sc_mem_size;
111 bus_addr_t sc_mem_alloc; /* Next allocation. */
112 int sc_mem_win_target;
113 uint32_t sc_mem_map[MV_PCI_MEM_SLICE_SIZE /
114 (PCI_MIN_MEM_ALLOC * BITS_PER_UINT32)];
115 int sc_win_target;
113 int sc_mem_win_attr;
114
115 struct rman sc_io_rman;
116 bus_addr_t sc_io_base;
117 bus_addr_t sc_io_size;
116 int sc_mem_win_attr;
117
118 struct rman sc_io_rman;
119 bus_addr_t sc_io_base;
120 bus_addr_t sc_io_size;
118 bus_addr_t sc_io_alloc; /* Next allocation. */
119 int sc_io_win_target;
121 uint32_t sc_io_map[MV_PCI_IO_SLICE_SIZE /
122 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
120 int sc_io_win_attr;
121
122 struct resource *sc_res;
123 bus_space_handle_t sc_bsh;
124 bus_space_tag_t sc_bst;
125 int sc_rid;
126
127 int sc_busnr; /* Host bridge bus number */
128 int sc_devnr; /* Host bridge device number */
129 int sc_type;
123 int sc_io_win_attr;
124
125 struct resource *sc_res;
126 bus_space_handle_t sc_bsh;
127 bus_space_tag_t sc_bst;
128 int sc_rid;
129
130 int sc_busnr; /* Host bridge bus number */
131 int sc_devnr; /* Host bridge device number */
132 int sc_type;
133 int sc_mode; /* Endpoint / Root Complex */
130
131 struct fdt_pci_intr sc_intr_info;
132};
133
134/* Local forward prototypes */
135static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *);
136static void mv_pcib_hw_cfginit(void);
137static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int,
138 u_int, u_int, int);
139static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int,
140 u_int, u_int, uint32_t, int);
141static int mv_pcib_init(struct mv_pcib_softc *, int, int);
142static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int);
143static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int);
144static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *);
145static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t);
134
135 struct fdt_pci_intr sc_intr_info;
136};
137
138/* Local forward prototypes */
139static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *);
140static void mv_pcib_hw_cfginit(void);
141static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int,
142 u_int, u_int, int);
143static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int,
144 u_int, u_int, uint32_t, int);
145static int mv_pcib_init(struct mv_pcib_softc *, int, int);
146static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int);
147static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int);
148static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *);
149static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t);
150static void mv_pcib_enable(struct mv_pcib_softc *, uint32_t);
151static int mv_pcib_mem_init(struct mv_pcib_softc *);
146
152
147
148/* Forward prototypes */
149static int mv_pcib_probe(device_t);
150static int mv_pcib_attach(device_t);
151
152static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *,
153 u_long, u_long, u_long, u_int);
154static int mv_pcib_release_resource(device_t, device_t, int, int,
155 struct resource *);

--- 24 unchanged lines hidden (view full) ---

180 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
181 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
182
183 /* pcib interface */
184 DEVMETHOD(pcib_maxslots, mv_pcib_maxslots),
185 DEVMETHOD(pcib_read_config, mv_pcib_read_config),
186 DEVMETHOD(pcib_write_config, mv_pcib_write_config),
187 DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt),
153/* Forward prototypes */
154static int mv_pcib_probe(device_t);
155static int mv_pcib_attach(device_t);
156
157static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *,
158 u_long, u_long, u_long, u_int);
159static int mv_pcib_release_resource(device_t, device_t, int, int,
160 struct resource *);

--- 24 unchanged lines hidden (view full) ---

185 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
186 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
187
188 /* pcib interface */
189 DEVMETHOD(pcib_maxslots, mv_pcib_maxslots),
190 DEVMETHOD(pcib_read_config, mv_pcib_read_config),
191 DEVMETHOD(pcib_write_config, mv_pcib_write_config),
192 DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt),
188
193
189 /* OFW bus interface */
190 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
191 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
192 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
193 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
194 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
195
196 DEVMETHOD_END

--- 28 unchanged lines hidden (view full) ---

225 return (BUS_PROBE_DEFAULT);
226}
227
228static int
229mv_pcib_attach(device_t self)
230{
231 struct mv_pcib_softc *sc;
232 phandle_t node, parnode;
194 /* OFW bus interface */
195 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
196 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
197 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
198 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
199 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
200
201 DEVMETHOD_END

--- 28 unchanged lines hidden (view full) ---

230 return (BUS_PROBE_DEFAULT);
231}
232
233static int
234mv_pcib_attach(device_t self)
235{
236 struct mv_pcib_softc *sc;
237 phandle_t node, parnode;
233 uint32_t val;
238 uint32_t val, unit;
234 int err;
235
236 sc = device_get_softc(self);
237 sc->sc_dev = self;
239 int err;
240
241 sc = device_get_softc(self);
242 sc->sc_dev = self;
243 unit = fdt_get_unit(self);
238
244
245
239 node = ofw_bus_get_node(self);
240 parnode = OF_parent(node);
241 if (fdt_is_compatible(node, "mrvl,pcie")) {
242 sc->sc_type = MV_TYPE_PCIE;
246 node = ofw_bus_get_node(self);
247 parnode = OF_parent(node);
248 if (fdt_is_compatible(node, "mrvl,pcie")) {
249 sc->sc_type = MV_TYPE_PCIE;
243 sc->sc_mem_win_target = MV_WIN_PCIE_TARGET(0);
244 sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(0);
245 sc->sc_io_win_target = MV_WIN_PCIE_TARGET(0);
246 sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(0);
247#ifdef SOC_MV_ORION
250 sc->sc_win_target = MV_WIN_PCIE_TARGET(unit);
251 sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(unit);
252 sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(unit);
248 } else if (fdt_is_compatible(node, "mrvl,pci")) {
249 sc->sc_type = MV_TYPE_PCI;
253 } else if (fdt_is_compatible(node, "mrvl,pci")) {
254 sc->sc_type = MV_TYPE_PCI;
250 sc->sc_mem_win_target = MV_WIN_PCI_TARGET;
255 sc->sc_win_target = MV_WIN_PCI_TARGET;
251 sc->sc_mem_win_attr = MV_WIN_PCI_MEM_ATTR;
256 sc->sc_mem_win_attr = MV_WIN_PCI_MEM_ATTR;
252 sc->sc_io_win_target = MV_WIN_PCI_TARGET;
253 sc->sc_io_win_attr = MV_WIN_PCI_IO_ATTR;
257 sc->sc_io_win_attr = MV_WIN_PCI_IO_ATTR;
254#endif
255 } else
256 return (ENXIO);
257
258 /*
258 } else
259 return (ENXIO);
260
261 /*
259 * Get PCI interrupt info.
260 */
261 if (mv_pcib_intr_info(node, sc) != 0) {
262 device_printf(self, "could not retrieve interrupt info\n");
263 return (ENXIO);
264 }
265
266 /*
267 * Retrieve our mem-mapped registers range.
268 */
269 sc->sc_rid = 0;
270 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid,
271 RF_ACTIVE);
272 if (sc->sc_res == NULL) {
273 device_printf(self, "could not map memory\n");
274 return (ENXIO);
275 }
276 sc->sc_bst = rman_get_bustag(sc->sc_res);
277 sc->sc_bsh = rman_get_bushandle(sc->sc_res);
278
262 * Retrieve our mem-mapped registers range.
263 */
264 sc->sc_rid = 0;
265 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid,
266 RF_ACTIVE);
267 if (sc->sc_res == NULL) {
268 device_printf(self, "could not map memory\n");
269 return (ENXIO);
270 }
271 sc->sc_bst = rman_get_bustag(sc->sc_res);
272 sc->sc_bsh = rman_get_bushandle(sc->sc_res);
273
274 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_CONTROL);
275 sc->sc_mode = (val & PCIE_CONTROL_ROOT_CMPLX ? MV_MODE_ROOT :
276 MV_MODE_ENDPOINT);
277
279 /*
278 /*
279 * Get PCI interrupt info.
280 */
281 if ((sc->sc_mode == MV_MODE_ROOT) &&
282 (mv_pcib_intr_info(node, sc) != 0)) {
283 device_printf(self, "could not retrieve interrupt info\n");
284 return (ENXIO);
285 }
286
287 /*
280 * Configure decode windows for PCI(E) access.
281 */
282 if (mv_pcib_decode_win(node, sc) != 0)
283 return (ENXIO);
284
285 mv_pcib_hw_cfginit();
286
287 /*
288 * Configure decode windows for PCI(E) access.
289 */
290 if (mv_pcib_decode_win(node, sc) != 0)
291 return (ENXIO);
292
293 mv_pcib_hw_cfginit();
294
295 /*
288 * Enable PCI bridge.
296 * Enable PCIE device.
289 */
297 */
290 val = mv_pcib_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0,
291 PCIR_COMMAND, 2);
292 val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN |
293 PCIM_CMD_PORTEN;
294 mv_pcib_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0,
295 PCIR_COMMAND, val, 2);
298 mv_pcib_enable(sc, unit);
296
299
297 sc->sc_mem_alloc = sc->sc_mem_base;
298 sc->sc_io_alloc = sc->sc_io_base;
300 /*
301 * Memory management.
302 */
303 err = mv_pcib_mem_init(sc);
304 if (err)
305 return (err);
299
306
307 if (sc->sc_mode == MV_MODE_ROOT) {
308 err = mv_pcib_init(sc, sc->sc_busnr,
309 mv_pcib_maxslots(sc->sc_dev));
310 if (err)
311 goto error;
312
313 device_add_child(self, "pci", -1);
314 } else {
315 sc->sc_devnr = 1;
316 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
317 PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS);
318 device_add_child(self, "pci_ep", -1);
319 }
320
321 return (bus_generic_attach(self));
322
323error:
324 /* XXX SYS_RES_ should be released here */
325 rman_fini(&sc->sc_mem_rman);
326 rman_fini(&sc->sc_io_rman);
327
328 return (err);
329}
330
331static void
332mv_pcib_enable(struct mv_pcib_softc *sc, uint32_t unit)
333{
334 uint32_t val;
335#if !defined(SOC_MV_ARMADAXP)
336 int timeout;
337
338 /*
339 * Check if PCIE device is enabled.
340 */
341 if (read_cpu_ctrl(CPU_CONTROL) & CPU_CONTROL_PCIE_DISABLE(unit)) {
342 write_cpu_ctrl(CPU_CONTROL, read_cpu_ctrl(CPU_CONTROL) &
343 ~(CPU_CONTROL_PCIE_DISABLE(unit)));
344
345 timeout = PCIE_LINK_TIMEOUT;
346 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
347 PCIE_REG_STATUS);
348 while (((val & PCIE_STATUS_LINK_DOWN) == 1) && (timeout > 0)) {
349 DELAY(1000);
350 timeout -= 1000;
351 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
352 PCIE_REG_STATUS);
353 }
354 }
355#endif
356
357
358 if (sc->sc_mode == MV_MODE_ROOT) {
359 /*
360 * Enable PCI bridge.
361 */
362 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND);
363 val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN |
364 PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
365 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND, val);
366 }
367}
368
369static int
370mv_pcib_mem_init(struct mv_pcib_softc *sc)
371{
372 int err;
373
374 /*
375 * Memory management.
376 */
300 sc->sc_mem_rman.rm_type = RMAN_ARRAY;
301 err = rman_init(&sc->sc_mem_rman);
302 if (err)
303 return (err);
304
305 sc->sc_io_rman.rm_type = RMAN_ARRAY;
306 err = rman_init(&sc->sc_io_rman);
307 if (err) {

--- 6 unchanged lines hidden (view full) ---

314 if (err)
315 goto error;
316
317 err = rman_manage_region(&sc->sc_io_rman, sc->sc_io_base,
318 sc->sc_io_base + sc->sc_io_size - 1);
319 if (err)
320 goto error;
321
377 sc->sc_mem_rman.rm_type = RMAN_ARRAY;
378 err = rman_init(&sc->sc_mem_rman);
379 if (err)
380 return (err);
381
382 sc->sc_io_rman.rm_type = RMAN_ARRAY;
383 err = rman_init(&sc->sc_io_rman);
384 if (err) {

--- 6 unchanged lines hidden (view full) ---

391 if (err)
392 goto error;
393
394 err = rman_manage_region(&sc->sc_io_rman, sc->sc_io_base,
395 sc->sc_io_base + sc->sc_io_size - 1);
396 if (err)
397 goto error;
398
322 err = mv_pcib_init(sc, sc->sc_busnr, mv_pcib_maxslots(sc->sc_dev));
323 if (err)
324 goto error;
399 return (0);
325
400
326 device_add_child(self, "pci", -1);
327 return (bus_generic_attach(self));
328
329error:
401error:
330 /* XXX SYS_RES_ should be released here */
331 rman_fini(&sc->sc_mem_rman);
332 rman_fini(&sc->sc_io_rman);
402 rman_fini(&sc->sc_mem_rman);
403 rman_fini(&sc->sc_io_rman);
404
333 return (err);
334}
335
405 return (err);
406}
407
408static inline uint32_t
409pcib_bit_get(uint32_t *map, uint32_t bit)
410{
411 uint32_t n = bit / BITS_PER_UINT32;
412
413 bit = bit % BITS_PER_UINT32;
414 return (map[n] & (1 << bit));
415}
416
417static inline void
418pcib_bit_set(uint32_t *map, uint32_t bit)
419{
420 uint32_t n = bit / BITS_PER_UINT32;
421
422 bit = bit % BITS_PER_UINT32;
423 map[n] |= (1 << bit);
424}
425
426static inline uint32_t
427pcib_map_check(uint32_t *map, uint32_t start, uint32_t bits)
428{
429 uint32_t i;
430
431 for (i = start; i < start + bits; i++)
432 if (pcib_bit_get(map, i))
433 return (0);
434
435 return (1);
436}
437
438static inline void
439pcib_map_set(uint32_t *map, uint32_t start, uint32_t bits)
440{
441 uint32_t i;
442
443 for (i = start; i < start + bits; i++)
444 pcib_bit_set(map, i);
445}
446
447/*
448 * The idea of this allocator is taken from ARM No-Cache memory
449 * management code (sys/arm/arm/vm_machdep.c).
450 */
451static bus_addr_t
452pcib_alloc(struct mv_pcib_softc *sc, uint32_t smask)
453{
454 uint32_t bits, bits_limit, i, *map, min_alloc, size;
455 bus_addr_t addr = 0;
456 bus_addr_t base;
457
458 if (smask & 1) {
459 base = sc->sc_io_base;
460 min_alloc = PCI_MIN_IO_ALLOC;
461 bits_limit = sc->sc_io_size / min_alloc;
462 map = sc->sc_io_map;
463 smask &= ~0x3;
464 } else {
465 base = sc->sc_mem_base;
466 min_alloc = PCI_MIN_MEM_ALLOC;
467 bits_limit = sc->sc_mem_size / min_alloc;
468 map = sc->sc_mem_map;
469 smask &= ~0xF;
470 }
471
472 size = ~smask + 1;
473 bits = size / min_alloc;
474
475 for (i = 0; i + bits <= bits_limit; i += bits)
476 if (pcib_map_check(map, i, bits)) {
477 pcib_map_set(map, i, bits);
478 addr = base + (i * min_alloc);
479 return (addr);
480 }
481
482 return (addr);
483}
484
336static int
337mv_pcib_init_bar(struct mv_pcib_softc *sc, int bus, int slot, int func,
338 int barno)
339{
485static int
486mv_pcib_init_bar(struct mv_pcib_softc *sc, int bus, int slot, int func,
487 int barno)
488{
340 bus_addr_t *allocp, limit;
341 uint32_t addr, bar, mask, size;
489 uint32_t addr, bar;
342 int reg, width;
343
344 reg = PCIR_BAR(barno);
490 int reg, width;
491
492 reg = PCIR_BAR(barno);
493
494 /*
495 * Need to init the BAR register with 0xffffffff before correct
496 * value can be read.
497 */
498 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4);
345 bar = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4);
346 if (bar == 0)
347 return (1);
348
349 /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */
350 width = ((bar & 7) == 4) ? 2 : 1;
351
499 bar = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4);
500 if (bar == 0)
501 return (1);
502
503 /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */
504 width = ((bar & 7) == 4) ? 2 : 1;
505
352 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4);
353 size = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4);
354
355 /* Get BAR type and size */
356 if (bar & 1) {
357 /* I/O port */
358 allocp = &sc->sc_io_alloc;
359 limit = sc->sc_io_base + sc->sc_io_size;
360 size &= ~0x3;
361 if ((size & 0xffff0000) == 0)
362 size |= 0xffff0000;
363 } else {
364 /* Memory */
365 allocp = &sc->sc_mem_alloc;
366 limit = sc->sc_mem_base + sc->sc_mem_size;
367 size &= ~0xF;
368 }
369 mask = ~size;
370 size = mask + 1;
371
372 /* Sanity check (must be a power of 2) */
373 if (size & mask)
374 return (width);
375
376 addr = (*allocp + mask) & ~mask;
377 if ((*allocp = addr + size) > limit)
506 addr = pcib_alloc(sc, bar);
507 if (!addr)
378 return (-1);
379
380 if (bootverbose)
508 return (-1);
509
510 if (bootverbose)
381 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n",
382 bus, slot, func, reg, size, addr);
511 printf("PCI %u:%u:%u: reg %x: smask=%08x: addr=%08x\n",
512 bus, slot, func, reg, bar, addr);
383
384 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4);
385 if (width == 2)
386 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4,
387 0, 4);
388
389 return (width);
390}

--- 132 unchanged lines hidden (view full) ---

523 switch (type) {
524 case SYS_RES_IOPORT:
525 rm = &sc->sc_io_rman;
526 break;
527 case SYS_RES_MEMORY:
528 rm = &sc->sc_mem_rman;
529 break;
530 default:
513
514 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4);
515 if (width == 2)
516 mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4,
517 0, 4);
518
519 return (width);
520}

--- 132 unchanged lines hidden (view full) ---

653 switch (type) {
654 case SYS_RES_IOPORT:
655 rm = &sc->sc_io_rman;
656 break;
657 case SYS_RES_MEMORY:
658 rm = &sc->sc_mem_rman;
659 break;
660 default:
531 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
661 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
532 type, rid, start, end, count, flags));
533 };
534
662 type, rid, start, end, count, flags));
663 };
664
665 if ((start == 0UL) && (end == ~0UL)) {
666 start = sc->sc_mem_base;
667 end = sc->sc_mem_base + sc->sc_mem_size - 1;
668 count = sc->sc_mem_size;
669 }
670
671 if ((start < sc->sc_mem_base) || (start + count - 1 != end) ||
672 (end > sc->sc_mem_base + sc->sc_mem_size - 1))
673 return (NULL);
674
535 res = rman_reserve_resource(rm, start, end, count, flags, child);
536 if (res == NULL)
537 return (NULL);
538
539 rman_set_rid(res, *rid);
540 rman_set_bustag(res, fdtbus_bs_tag);
541 rman_set_bushandle(res, start);
542

--- 148 unchanged lines hidden (view full) ---

691}
692
693static uint32_t
694mv_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
695 u_int reg, int bytes)
696{
697 struct mv_pcib_softc *sc = device_get_softc(dev);
698
675 res = rman_reserve_resource(rm, start, end, count, flags, child);
676 if (res == NULL)
677 return (NULL);
678
679 rman_set_rid(res, *rid);
680 rman_set_bustag(res, fdtbus_bs_tag);
681 rman_set_bushandle(res, start);
682

--- 148 unchanged lines hidden (view full) ---

831}
832
833static uint32_t
834mv_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
835 u_int reg, int bytes)
836{
837 struct mv_pcib_softc *sc = device_get_softc(dev);
838
699 /* Skip self */
700 if (bus == sc->sc_busnr && slot == sc->sc_devnr)
839 /* Return ~0 if link is inactive or trying to read from Root */
840 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
841 PCIE_STATUS_LINK_DOWN) || (slot == 0))
701 return (~0U);
702
703 return (mv_pcib_hw_cfgread(sc, bus, slot, func, reg, bytes));
704}
705
706static void
707mv_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
708 u_int reg, uint32_t val, int bytes)
709{
710 struct mv_pcib_softc *sc = device_get_softc(dev);
711
842 return (~0U);
843
844 return (mv_pcib_hw_cfgread(sc, bus, slot, func, reg, bytes));
845}
846
847static void
848mv_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
849 u_int reg, uint32_t val, int bytes)
850{
851 struct mv_pcib_softc *sc = device_get_softc(dev);
852
712 /* Skip self */
713 if (bus == sc->sc_busnr && slot == sc->sc_devnr)
853 /* Return if link is inactive or trying to write to Root */
854 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
855 PCIE_STATUS_LINK_DOWN) || (slot == 0))
714 return;
715
716 mv_pcib_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes);
717}
718
719static int
720mv_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
721{

--- 22 unchanged lines hidden (view full) ---

744 dev = sc->sc_dev;
745
746 if ((error = fdt_pci_ranges(node, &io_space, &mem_space)) != 0) {
747 device_printf(dev, "could not retrieve 'ranges' data\n");
748 return (error);
749 }
750
751 /* Configure CPU decoding windows */
856 return;
857
858 mv_pcib_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes);
859}
860
861static int
862mv_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
863{

--- 22 unchanged lines hidden (view full) ---

886 dev = sc->sc_dev;
887
888 if ((error = fdt_pci_ranges(node, &io_space, &mem_space)) != 0) {
889 device_printf(dev, "could not retrieve 'ranges' data\n");
890 return (error);
891 }
892
893 /* Configure CPU decoding windows */
752 error = decode_win_cpu_set(sc->sc_io_win_target,
753 sc->sc_io_win_attr, io_space.base_parent, io_space.len, -1);
894 error = decode_win_cpu_set(sc->sc_win_target,
895 sc->sc_io_win_attr, io_space.base_parent, io_space.len, ~0);
754 if (error < 0) {
755 device_printf(dev, "could not set up CPU decode "
756 "window for PCI IO\n");
757 return (ENXIO);
758 }
896 if (error < 0) {
897 device_printf(dev, "could not set up CPU decode "
898 "window for PCI IO\n");
899 return (ENXIO);
900 }
759 error = decode_win_cpu_set(sc->sc_mem_win_target,
760 sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len, -1);
901 error = decode_win_cpu_set(sc->sc_win_target,
902 sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len,
903 mem_space.base_parent);
761 if (error < 0) {
762 device_printf(dev, "could not set up CPU decode "
763 "windows for PCI MEM\n");
764 return (ENXIO);
765 }
766
767 sc->sc_io_base = io_space.base_parent;
768 sc->sc_io_size = io_space.len;

--- 10 unchanged lines hidden (view full) ---

779 int error;
780
781 if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0)
782 return (error);
783
784 return (0);
785}
786
904 if (error < 0) {
905 device_printf(dev, "could not set up CPU decode "
906 "windows for PCI MEM\n");
907 return (ENXIO);
908 }
909
910 sc->sc_io_base = io_space.base_parent;
911 sc->sc_io_size = io_space.len;

--- 10 unchanged lines hidden (view full) ---

922 int error;
923
924 if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0)
925 return (error);
926
927 return (0);
928}
929
787#if 0
788 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
789 PCIE_REG_CONTROL);
790
791 /*
792 * If this PCI-E port (controller) is configured (by the
793 * underlying firmware) with lane width other than 1x, there
794 * are auxiliary resources defined for aggregating more width
795 * on our lane. Skip all such entries as they are not
796 * standalone ports and must not have a device object
797 * instantiated.
798 */
799 if ((control & PCIE_CTRL_LINK1X) == 0)
800 while (info->op_base &&
801 info->op_type == MV_TYPE_PCIE_AGGR_LANE)
802 info++;
803
804 mv_pcib_add_child(driver, parent, sc);
805#endif