Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm64/cavium/thunder_pcie_pem_fdt.c
39478 views
1
/*
2
* Copyright (C) 2016 Cavium Inc.
3
* All rights reserved.
4
*
5
* Developed by Semihalf.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
#include <sys/cdefs.h>
29
#include "opt_platform.h"
30
31
#include <sys/param.h>
32
#include <sys/systm.h>
33
#include <sys/malloc.h>
34
#include <sys/types.h>
35
#include <sys/sysctl.h>
36
#include <sys/kernel.h>
37
#include <sys/rman.h>
38
#include <sys/module.h>
39
#include <sys/bus.h>
40
#include <sys/endian.h>
41
#include <sys/cpuset.h>
42
43
#include <dev/ofw/openfirm.h>
44
#include <dev/ofw/ofw_bus.h>
45
#include <dev/ofw/ofw_bus_subr.h>
46
47
#include <dev/pci/pcivar.h>
48
#include <dev/pci/pcireg.h>
49
#include <dev/pci/pcib_private.h>
50
#include <dev/pci/pci_host_generic.h>
51
52
#include <machine/intr.h>
53
54
#include "thunder_pcie_common.h"
55
#include "thunder_pcie_pem.h"
56
57
#include "pcib_if.h"
58
59
static int thunder_pem_fdt_probe(device_t);
60
static int thunder_pem_fdt_alloc_msix(device_t, device_t, int *);
61
static int thunder_pem_fdt_release_msix(device_t, device_t, int);
62
static int thunder_pem_fdt_alloc_msi(device_t, device_t, int, int, int *);
63
static int thunder_pem_fdt_release_msi(device_t, device_t, int, int *);
64
static int thunder_pem_fdt_map_msi(device_t, device_t, int, uint64_t *,
65
uint32_t *);
66
static int thunder_pem_fdt_get_id(device_t, device_t, enum pci_id_type,
67
uintptr_t *);
68
69
static device_method_t thunder_pem_fdt_methods[] = {
70
/* Device interface */
71
DEVMETHOD(device_probe, thunder_pem_fdt_probe),
72
73
/* pcib interface */
74
DEVMETHOD(pcib_alloc_msix, thunder_pem_fdt_alloc_msix),
75
DEVMETHOD(pcib_release_msix, thunder_pem_fdt_release_msix),
76
DEVMETHOD(pcib_alloc_msi, thunder_pem_fdt_alloc_msi),
77
DEVMETHOD(pcib_release_msi, thunder_pem_fdt_release_msi),
78
DEVMETHOD(pcib_map_msi, thunder_pem_fdt_map_msi),
79
DEVMETHOD(pcib_get_id, thunder_pem_fdt_get_id),
80
81
/* End */
82
DEVMETHOD_END
83
};
84
85
DEFINE_CLASS_1(pcib, thunder_pem_fdt_driver, thunder_pem_fdt_methods,
86
sizeof(struct thunder_pem_softc), thunder_pem_driver);
87
88
DRIVER_MODULE(thunder_pem, simplebus, thunder_pem_fdt_driver, 0, 0);
89
DRIVER_MODULE(thunder_pem, ofwbus, thunder_pem_fdt_driver, 0, 0);
90
91
static int
92
thunder_pem_fdt_probe(device_t dev)
93
{
94
95
if (!ofw_bus_status_okay(dev))
96
return (ENXIO);
97
98
if (ofw_bus_is_compatible(dev, "cavium,pci-host-thunder-pem")) {
99
device_set_desc(dev, THUNDER_PEM_DESC);
100
return (BUS_PROBE_DEFAULT);
101
}
102
103
return (ENXIO);
104
}
105
106
static int
107
thunder_pem_fdt_alloc_msi(device_t pci, device_t child, int count, int maxcount,
108
int *irqs)
109
{
110
phandle_t msi_parent;
111
int err;
112
113
err = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child),
114
&msi_parent, NULL);
115
if (err != 0)
116
return (err);
117
return (intr_alloc_msi(pci, child, msi_parent, count, maxcount,
118
irqs));
119
}
120
121
static int
122
thunder_pem_fdt_release_msi(device_t pci, device_t child, int count, int *irqs)
123
{
124
phandle_t msi_parent;
125
int err;
126
127
err = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child),
128
&msi_parent, NULL);
129
if (err != 0)
130
return (err);
131
return (intr_release_msi(pci, child, msi_parent, count, irqs));
132
}
133
134
static int
135
thunder_pem_fdt_alloc_msix(device_t pci, device_t child, int *irq)
136
{
137
phandle_t msi_parent;
138
int err;
139
140
err = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child),
141
&msi_parent, NULL);
142
if (err != 0)
143
return (err);
144
return (intr_alloc_msix(pci, child, msi_parent, irq));
145
}
146
147
static int
148
thunder_pem_fdt_release_msix(device_t pci, device_t child, int irq)
149
{
150
phandle_t msi_parent;
151
int err;
152
153
err = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child),
154
&msi_parent, NULL);
155
if (err != 0)
156
return (err);
157
return (intr_release_msix(pci, child, msi_parent, irq));
158
}
159
160
static int
161
thunder_pem_fdt_map_msi(device_t pci, device_t child, int irq, uint64_t *addr,
162
uint32_t *data)
163
{
164
phandle_t msi_parent;
165
int err;
166
167
err = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child),
168
&msi_parent, NULL);
169
if (err != 0)
170
return (err);
171
return (intr_map_msi(pci, child, msi_parent, irq, addr, data));
172
}
173
174
static int
175
thunder_pem_fdt_get_id(device_t dev, device_t child, enum pci_id_type type,
176
uintptr_t *id)
177
{
178
phandle_t node;
179
int err;
180
uint32_t rid;
181
uint16_t pci_rid;
182
183
if (type != PCI_ID_MSI)
184
return (pcib_get_id(dev, child, type, id));
185
186
node = ofw_bus_get_node(dev);
187
pci_rid = pci_get_rid(child);
188
189
err = ofw_bus_msimap(node, pci_rid, NULL, &rid);
190
if (err != 0)
191
return (err);
192
*id = rid;
193
194
return (0);
195
}
196
197