Deleted Added
full compact
3a4
> * Copyright (c) 2010-2012 Semihalf
41c42
< __FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 239277 2012-08-15 05:15:49Z gonzo $");
---
> __FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240489 2012-09-14 09:57:41Z gber $");
92,96c93,94
< #define STATUS_LINK_DOWN 1
< #define STATUS_BUS_OFFS 8
< #define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS)
< #define STATUS_DEV_OFFS 16
< #define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS)
---
> #define PCIE_CONTROL_ROOT_CMPLX (1 << 1)
> #define PCIE_CONTROL_HOT_RESET (1 << 24)
98,101c96
< #define P2P_CONF_BUS_OFFS 16
< #define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS)
< #define P2P_CONF_DEV_OFFS 24
< #define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS)
---
> #define PCIE_LINK_TIMEOUT 1000000
103c98,99
< #define PCI_VENDORID_MRVL 0x11AB
---
> #define PCIE_STATUS_LINK_DOWN 1
> #define PCIE_STATUS_DEV_OFFS 16
104a101,106
> /* Minimum PCI Memory and I/O allocations taken from PCI spec (in bytes) */
> #define PCI_MIN_IO_ALLOC 4
> #define PCI_MIN_MEM_ALLOC 16
>
> #define BITS_PER_UINT32 (NBBY * sizeof(uint32_t))
>
111,112c113,115
< bus_addr_t sc_mem_alloc; /* Next allocation. */
< int sc_mem_win_target;
---
> uint32_t sc_mem_map[MV_PCI_MEM_SLICE_SIZE /
> (PCI_MIN_MEM_ALLOC * BITS_PER_UINT32)];
> int sc_win_target;
118,119c121,122
< bus_addr_t sc_io_alloc; /* Next allocation. */
< int sc_io_win_target;
---
> uint32_t sc_io_map[MV_PCI_IO_SLICE_SIZE /
> (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
129a133
> int sc_mode; /* Endpoint / Root Complex */
145a150,151
> static void mv_pcib_enable(struct mv_pcib_softc *, uint32_t);
> static int mv_pcib_mem_init(struct mv_pcib_softc *);
147d152
<
188c193
<
---
>
233c238
< uint32_t val;
---
> uint32_t val, unit;
237a243
> unit = fdt_get_unit(self);
238a245
>
243,247c250,252
< sc->sc_mem_win_target = MV_WIN_PCIE_TARGET(0);
< sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(0);
< sc->sc_io_win_target = MV_WIN_PCIE_TARGET(0);
< sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(0);
< #ifdef SOC_MV_ORION
---
> sc->sc_win_target = MV_WIN_PCIE_TARGET(unit);
> sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(unit);
> sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(unit);
250c255
< sc->sc_mem_win_target = MV_WIN_PCI_TARGET;
---
> sc->sc_win_target = MV_WIN_PCI_TARGET;
252d256
< sc->sc_io_win_target = MV_WIN_PCI_TARGET;
254d257
< #endif
259,266d261
< * Get PCI interrupt info.
< */
< if (mv_pcib_intr_info(node, sc) != 0) {
< device_printf(self, "could not retrieve interrupt info\n");
< return (ENXIO);
< }
<
< /*
278a274,277
> val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_CONTROL);
> sc->sc_mode = (val & PCIE_CONTROL_ROOT_CMPLX ? MV_MODE_ROOT :
> MV_MODE_ENDPOINT);
>
279a279,287
> * Get PCI interrupt info.
> */
> if ((sc->sc_mode == MV_MODE_ROOT) &&
> (mv_pcib_intr_info(node, sc) != 0)) {
> device_printf(self, "could not retrieve interrupt info\n");
> return (ENXIO);
> }
>
> /*
288c296
< * Enable PCI bridge.
---
> * Enable PCIE device.
290,295c298
< val = mv_pcib_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0,
< PCIR_COMMAND, 2);
< val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN |
< PCIM_CMD_PORTEN;
< mv_pcib_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0,
< PCIR_COMMAND, val, 2);
---
> mv_pcib_enable(sc, unit);
297,298c300,305
< sc->sc_mem_alloc = sc->sc_mem_base;
< sc->sc_io_alloc = sc->sc_io_base;
---
> /*
> * Memory management.
> */
> err = mv_pcib_mem_init(sc);
> if (err)
> return (err);
299a307,376
> if (sc->sc_mode == MV_MODE_ROOT) {
> err = mv_pcib_init(sc, sc->sc_busnr,
> mv_pcib_maxslots(sc->sc_dev));
> if (err)
> goto error;
>
> device_add_child(self, "pci", -1);
> } else {
> sc->sc_devnr = 1;
> bus_space_write_4(sc->sc_bst, sc->sc_bsh,
> PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS);
> device_add_child(self, "pci_ep", -1);
> }
>
> return (bus_generic_attach(self));
>
> error:
> /* XXX SYS_RES_ should be released here */
> rman_fini(&sc->sc_mem_rman);
> rman_fini(&sc->sc_io_rman);
>
> return (err);
> }
>
> static void
> mv_pcib_enable(struct mv_pcib_softc *sc, uint32_t unit)
> {
> uint32_t val;
> #if !defined(SOC_MV_ARMADAXP)
> int timeout;
>
> /*
> * Check if PCIE device is enabled.
> */
> if (read_cpu_ctrl(CPU_CONTROL) & CPU_CONTROL_PCIE_DISABLE(unit)) {
> write_cpu_ctrl(CPU_CONTROL, read_cpu_ctrl(CPU_CONTROL) &
> ~(CPU_CONTROL_PCIE_DISABLE(unit)));
>
> timeout = PCIE_LINK_TIMEOUT;
> val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
> PCIE_REG_STATUS);
> while (((val & PCIE_STATUS_LINK_DOWN) == 1) && (timeout > 0)) {
> DELAY(1000);
> timeout -= 1000;
> val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
> PCIE_REG_STATUS);
> }
> }
> #endif
>
>
> if (sc->sc_mode == MV_MODE_ROOT) {
> /*
> * Enable PCI bridge.
> */
> val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND);
> val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN |
> PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
> bus_space_write_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND, val);
> }
> }
>
> static int
> mv_pcib_mem_init(struct mv_pcib_softc *sc)
> {
> int err;
>
> /*
> * Memory management.
> */
322,324c399
< err = mv_pcib_init(sc, sc->sc_busnr, mv_pcib_maxslots(sc->sc_dev));
< if (err)
< goto error;
---
> return (0);
326,328d400
< device_add_child(self, "pci", -1);
< return (bus_generic_attach(self));
<
330d401
< /* XXX SYS_RES_ should be released here */
332a404
>
335a408,484
> static inline uint32_t
> pcib_bit_get(uint32_t *map, uint32_t bit)
> {
> uint32_t n = bit / BITS_PER_UINT32;
>
> bit = bit % BITS_PER_UINT32;
> return (map[n] & (1 << bit));
> }
>
> static inline void
> pcib_bit_set(uint32_t *map, uint32_t bit)
> {
> uint32_t n = bit / BITS_PER_UINT32;
>
> bit = bit % BITS_PER_UINT32;
> map[n] |= (1 << bit);
> }
>
> static inline uint32_t
> pcib_map_check(uint32_t *map, uint32_t start, uint32_t bits)
> {
> uint32_t i;
>
> for (i = start; i < start + bits; i++)
> if (pcib_bit_get(map, i))
> return (0);
>
> return (1);
> }
>
> static inline void
> pcib_map_set(uint32_t *map, uint32_t start, uint32_t bits)
> {
> uint32_t i;
>
> for (i = start; i < start + bits; i++)
> pcib_bit_set(map, i);
> }
>
> /*
> * The idea of this allocator is taken from ARM No-Cache memory
> * management code (sys/arm/arm/vm_machdep.c).
> */
> static bus_addr_t
> pcib_alloc(struct mv_pcib_softc *sc, uint32_t smask)
> {
> uint32_t bits, bits_limit, i, *map, min_alloc, size;
> bus_addr_t addr = 0;
> bus_addr_t base;
>
> if (smask & 1) {
> base = sc->sc_io_base;
> min_alloc = PCI_MIN_IO_ALLOC;
> bits_limit = sc->sc_io_size / min_alloc;
> map = sc->sc_io_map;
> smask &= ~0x3;
> } else {
> base = sc->sc_mem_base;
> min_alloc = PCI_MIN_MEM_ALLOC;
> bits_limit = sc->sc_mem_size / min_alloc;
> map = sc->sc_mem_map;
> smask &= ~0xF;
> }
>
> size = ~smask + 1;
> bits = size / min_alloc;
>
> for (i = 0; i + bits <= bits_limit; i += bits)
> if (pcib_map_check(map, i, bits)) {
> pcib_map_set(map, i, bits);
> addr = base + (i * min_alloc);
> return (addr);
> }
>
> return (addr);
> }
>
340,341c489
< bus_addr_t *allocp, limit;
< uint32_t addr, bar, mask, size;
---
> uint32_t addr, bar;
344a493,498
>
> /*
> * Need to init the BAR register with 0xffffffff before correct
> * value can be read.
> */
> mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4);
352,377c506,507
< mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4);
< size = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4);
<
< /* Get BAR type and size */
< if (bar & 1) {
< /* I/O port */
< allocp = &sc->sc_io_alloc;
< limit = sc->sc_io_base + sc->sc_io_size;
< size &= ~0x3;
< if ((size & 0xffff0000) == 0)
< size |= 0xffff0000;
< } else {
< /* Memory */
< allocp = &sc->sc_mem_alloc;
< limit = sc->sc_mem_base + sc->sc_mem_size;
< size &= ~0xF;
< }
< mask = ~size;
< size = mask + 1;
<
< /* Sanity check (must be a power of 2) */
< if (size & mask)
< return (width);
<
< addr = (*allocp + mask) & ~mask;
< if ((*allocp = addr + size) > limit)
---
> addr = pcib_alloc(sc, bar);
> if (!addr)
381,382c511,512
< printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n",
< bus, slot, func, reg, size, addr);
---
> printf("PCI %u:%u:%u: reg %x: smask=%08x: addr=%08x\n",
> bus, slot, func, reg, bar, addr);
531c661
< return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
---
> return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
534a665,674
> if ((start == 0UL) && (end == ~0UL)) {
> start = sc->sc_mem_base;
> end = sc->sc_mem_base + sc->sc_mem_size - 1;
> count = sc->sc_mem_size;
> }
>
> if ((start < sc->sc_mem_base) || (start + count - 1 != end) ||
> (end > sc->sc_mem_base + sc->sc_mem_size - 1))
> return (NULL);
>
699,700c839,841
< /* Skip self */
< if (bus == sc->sc_busnr && slot == sc->sc_devnr)
---
> /* Return ~0 if link is inactive or trying to read from Root */
> if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
> PCIE_STATUS_LINK_DOWN) || (slot == 0))
712,713c853,855
< /* Skip self */
< if (bus == sc->sc_busnr && slot == sc->sc_devnr)
---
> /* Return if link is inactive or trying to write to Root */
> if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
> PCIE_STATUS_LINK_DOWN) || (slot == 0))
752,753c894,895
< error = decode_win_cpu_set(sc->sc_io_win_target,
< sc->sc_io_win_attr, io_space.base_parent, io_space.len, -1);
---
> error = decode_win_cpu_set(sc->sc_win_target,
> sc->sc_io_win_attr, io_space.base_parent, io_space.len, ~0);
759,760c901,903
< error = decode_win_cpu_set(sc->sc_mem_win_target,
< sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len, -1);
---
> error = decode_win_cpu_set(sc->sc_win_target,
> sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len,
> mem_space.base_parent);
787,805d929
< #if 0
< control = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
< PCIE_REG_CONTROL);
<
< /*
< * If this PCI-E port (controller) is configured (by the
< * underlying firmware) with lane width other than 1x, there
< * are auxiliary resources defined for aggregating more width
< * on our lane. Skip all such entries as they are not
< * standalone ports and must not have a device object
< * instantiated.
< */
< if ((control & PCIE_CTRL_LINK1X) == 0)
< while (info->op_base &&
< info->op_type == MV_TYPE_PCIE_AGGR_LANE)
< info++;
<
< mv_pcib_add_child(driver, parent, sc);
< #endif