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 | |