Deleted Added
full compact
mv_pci.c (240489) mv_pci.c (240493)
1/*-
2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
3 * Copyright (c) 2010 The FreeBSD Foundation
4 * Copyright (c) 2010-2012 Semihalf
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *

--- 25 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>
1/*-
2 * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
3 * Copyright (c) 2010 The FreeBSD Foundation
4 * Copyright (c) 2010-2012 Semihalf
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *

--- 25 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>
42__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240489 2012-09-14 09:57:41Z gber $");
42__FBSDID("$FreeBSD: head/sys/arm/mv/mv_pci.c 240493 2012-09-14 10:06:56Z gber $");
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>
51#include <sys/queue.h>
52#include <sys/bus.h>
53#include <sys/rman.h>
54#include <sys/endian.h>
55
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>
51#include <sys/queue.h>
52#include <sys/bus.h>
53#include <sys/rman.h>
54#include <sys/endian.h>
55
56#include <machine/intr.h>
57
56#include <vm/vm.h>
57#include <vm/pmap.h>
58
59#include <dev/fdt/fdt_common.h>
60#include <dev/ofw/ofw_bus.h>
61#include <dev/ofw/ofw_bus_subr.h>
62#include <dev/pci/pcivar.h>
63#include <dev/pci/pcireg.h>

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

68
69#include <machine/resource.h>
70#include <machine/bus.h>
71
72#include <arm/mv/mvreg.h>
73#include <arm/mv/mvvar.h>
74#include <arm/mv/mvwin.h>
75
58#include <vm/vm.h>
59#include <vm/pmap.h>
60
61#include <dev/fdt/fdt_common.h>
62#include <dev/ofw/ofw_bus.h>
63#include <dev/ofw/ofw_bus_subr.h>
64#include <dev/pci/pcivar.h>
65#include <dev/pci/pcireg.h>

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

70
71#include <machine/resource.h>
72#include <machine/bus.h>
73
74#include <arm/mv/mvreg.h>
75#include <arm/mv/mvvar.h>
76#include <arm/mv/mvwin.h>
77
78#ifdef DEBUG
79#define debugf(fmt, args...) do { printf(fmt,##args); } while (0)
80#else
81#define debugf(fmt, args...)
82#endif
83
76#define PCI_CFG_ENA (1 << 31)
77#define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16)
78#define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11)
79#define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8)
80#define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc)
81
82#define PCI_REG_CFG_ADDR 0x0C78
83#define PCI_REG_CFG_DATA 0x0C7C
84#define PCI_CFG_ENA (1 << 31)
85#define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16)
86#define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11)
87#define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8)
88#define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc)
89
90#define PCI_REG_CFG_ADDR 0x0C78
91#define PCI_REG_CFG_DATA 0x0C7C
84#define PCI_REG_P2P_CONF 0x1D14
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

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

122 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
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
92
93#define PCIE_REG_CFG_ADDR 0x18F8
94#define PCIE_REG_CFG_DATA 0x18FC
95#define PCIE_REG_CONTROL 0x1A00
96#define PCIE_CTRL_LINK1X 0x00000001
97#define PCIE_REG_STATUS 0x1A04
98#define PCIE_REG_IRQ_MASK 0x1910
99

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

129 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
130 int sc_io_win_attr;
131
132 struct resource *sc_res;
133 bus_space_handle_t sc_bsh;
134 bus_space_tag_t sc_bst;
135 int sc_rid;
136
137 struct mtx sc_msi_mtx;
138 uint32_t sc_msi_bitmap;
139
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 */
134
135 struct fdt_pci_intr sc_intr_info;
136};
137

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

161static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
162static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t);
163
164static int mv_pcib_maxslots(device_t);
165static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int);
166static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
167 uint32_t, int);
168static int mv_pcib_route_interrupt(device_t, device_t, int);
140 int sc_busnr; /* Host bridge bus number */
141 int sc_devnr; /* Host bridge device number */
142 int sc_type;
143 int sc_mode; /* Endpoint / Root Complex */
144
145 struct fdt_pci_intr sc_intr_info;
146};
147

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

171static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
172static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t);
173
174static int mv_pcib_maxslots(device_t);
175static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int);
176static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
177 uint32_t, int);
178static int mv_pcib_route_interrupt(device_t, device_t, int);
179#if defined(SOC_MV_ARMADAXP)
180static int mv_pcib_alloc_msi(device_t, device_t, int, int, int *);
181static int mv_pcib_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
182static int mv_pcib_release_msi(device_t, device_t, int, int *);
183#endif
169
170/*
171 * Bus interface definitions.
172 */
173static device_method_t mv_pcib_methods[] = {
174 /* Device interface */
175 DEVMETHOD(device_probe, mv_pcib_probe),
176 DEVMETHOD(device_attach, mv_pcib_attach),

--- 8 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),
184
185/*
186 * Bus interface definitions.
187 */
188static device_method_t mv_pcib_methods[] = {
189 /* Device interface */
190 DEVMETHOD(device_probe, mv_pcib_probe),
191 DEVMETHOD(device_attach, mv_pcib_attach),

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

200 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
201 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
202
203 /* pcib interface */
204 DEVMETHOD(pcib_maxslots, mv_pcib_maxslots),
205 DEVMETHOD(pcib_read_config, mv_pcib_read_config),
206 DEVMETHOD(pcib_write_config, mv_pcib_write_config),
207 DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt),
193
208
209#if defined(SOC_MV_ARMADAXP)
210 DEVMETHOD(pcib_alloc_msi, mv_pcib_alloc_msi),
211 DEVMETHOD(pcib_release_msi, mv_pcib_release_msi),
212 DEVMETHOD(pcib_map_msi, mv_pcib_map_msi),
213#endif
214
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

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

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
215 /* OFW bus interface */
216 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
217 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
218 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
219 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
220 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
221
222 DEVMETHOD_END

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

334 device_add_child(self, "pci", -1);
335 } else {
336 sc->sc_devnr = 1;
337 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
338 PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS);
339 device_add_child(self, "pci_ep", -1);
340 }
341
342 mtx_init(&sc->sc_msi_mtx, "msi_mtx", NULL, MTX_DEF);
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);

--- 593 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
343 return (bus_generic_attach(self));
344
345error:
346 /* XXX SYS_RES_ should be released here */
347 rman_fini(&sc->sc_mem_rman);
348 rman_fini(&sc->sc_io_rman);
349
350 return (err);

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

944 int error;
945
946 if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0)
947 return (error);
948
949 return (0);
950}
951
952#if defined(SOC_MV_ARMADAXP)
953static int
954mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
955 uint32_t *data)
956{
957 struct mv_pcib_softc *sc;
958
959 sc = device_get_softc(dev);
960 irq = irq - MSI_IRQ;
961
962 /* validate parameters */
963 if (isclr(&sc->sc_msi_bitmap, irq)) {
964 device_printf(dev, "invalid MSI 0x%x\n", irq);
965 return (EINVAL);
966 }
967
968 mv_msi_data(irq, addr, data);
969
970 debugf("%s: irq: %d addr: %jx data: %x\n",
971 __func__, irq, *addr, *data);
972
973 return (0);
974}
975
976static int
977mv_pcib_alloc_msi(device_t dev, device_t child, int count,
978 int maxcount __unused, int *irqs)
979{
980 struct mv_pcib_softc *sc;
981 u_int start = 0, i;
982
983 if (powerof2(count) == 0 || count > MSI_IRQ_NUM)
984 return (EINVAL);
985
986 sc = device_get_softc(dev);
987 mtx_lock(&sc->sc_msi_mtx);
988
989 for (start = 0; (start + count) < MSI_IRQ_NUM; start++) {
990 for (i = start; i < start + count; i++) {
991 if (isset(&sc->sc_msi_bitmap, i))
992 break;
993 }
994 if (i == start + count)
995 break;
996 }
997
998 if ((start + count) == MSI_IRQ_NUM) {
999 mtx_unlock(&sc->sc_msi_mtx);
1000 return (ENXIO);
1001 }
1002
1003 for (i = start; i < start + count; i++) {
1004 setbit(&sc->sc_msi_bitmap, i);
1005 irqs[i] = MSI_IRQ + i;
1006 }
1007 debugf("%s: start: %x count: %x\n", __func__, start, count);
1008
1009 mtx_unlock(&sc->sc_msi_mtx);
1010 return (0);
1011}
1012
1013static int
1014mv_pcib_release_msi(device_t dev, device_t child, int count, int *irqs)
1015{
1016 struct mv_pcib_softc *sc;
1017 u_int i;
1018
1019 sc = device_get_softc(dev);
1020 mtx_lock(&sc->sc_msi_mtx);
1021
1022 for (i = 0; i < count; i++)
1023 clrbit(&sc->sc_msi_bitmap, irqs[i] - MSI_IRQ);
1024
1025 mtx_unlock(&sc->sc_msi_mtx);
1026 return (0);
1027}
1028#endif