Commit bb413337826ef1a1445ff9fb33424fd231430228
Committed by
Tom Rini
1 parent
c2ccc9e5cb
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
pci_ep: add pci endpoint sandbox driver
Add a dummy PCI endpoint for sandbox. Supporting only a single function, it allows setting and reading header configuration. Signed-off-by: Ramon Fried <ramon.fried@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 5 changed files with 198 additions and 0 deletions Side-by-side Diff
arch/Kconfig
... | ... | @@ -90,6 +90,7 @@ |
90 | 90 | select DM_SPI_FLASH |
91 | 91 | select HAVE_BLOCK_DEVICE |
92 | 92 | select LZO |
93 | + select PCI_ENDPOINT | |
93 | 94 | select SPI |
94 | 95 | select SUPPORT_OF_CONTROL |
95 | 96 | imply BITREVERSE |
... | ... | @@ -120,6 +121,7 @@ |
120 | 121 | imply VIRTIO_BLK |
121 | 122 | imply VIRTIO_NET |
122 | 123 | imply DM_SOUND |
124 | + imply PCI_SANDBOX_EP | |
123 | 125 | imply PCH |
124 | 126 | |
125 | 127 | config SH |
arch/sandbox/dts/test.dts
drivers/pci_endpoint/Kconfig
... | ... | @@ -22,5 +22,14 @@ |
22 | 22 | endpoint mode. This PCIe controller may be embedded into many |
23 | 23 | different vendors SoCs. |
24 | 24 | |
25 | +config PCI_SANDBOX_EP | |
26 | + bool "Sandbox PCIe endpoint controller" | |
27 | + depends on PCI_ENDPOINT | |
28 | + help | |
29 | + Say Y here if you want to support the Sandbox PCIe controller in | |
30 | + endpoint mode. | |
31 | + The sandbox driver act as a dummy driver which stores and | |
32 | + retrieves PCIe endpoint configuration as is. | |
33 | + | |
25 | 34 | endmenu |
drivers/pci_endpoint/Makefile
drivers/pci_endpoint/sandbox-pci_ep.c
1 | +// SPDX-License-Identifier: GPL-2.0+ | |
2 | +/* | |
3 | + * Copyright (c) 2019 Ramon Fried <ramon.fried@gmail.com> | |
4 | + */ | |
5 | + | |
6 | +#include <common.h> | |
7 | +#include <dm.h> | |
8 | +#include <errno.h> | |
9 | +#include <pci.h> | |
10 | +#include <pci_ep.h> | |
11 | +#include <asm/test.h> | |
12 | + | |
13 | +/** | |
14 | + * struct sandbox_pci_ep_priv - private data for driver | |
15 | + * @hdr: Stores the EP device header | |
16 | + * @msix: required MSIx count; | |
17 | + * @msi: required MSI count; | |
18 | + */ | |
19 | +struct sandbox_pci_ep_priv { | |
20 | + struct pci_ep_header hdr; | |
21 | + struct pci_bar bars[6]; | |
22 | + int msix; | |
23 | + int msi; | |
24 | + int irq_count; | |
25 | +}; | |
26 | + | |
27 | +/* Method exported for testing purposes */ | |
28 | +int sandbox_get_pci_ep_irq_count(struct udevice *dev) | |
29 | +{ | |
30 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
31 | + | |
32 | + return priv->irq_count; | |
33 | +} | |
34 | + | |
35 | +static const struct udevice_id sandbox_pci_ep_ids[] = { | |
36 | + { .compatible = "sandbox,pci_ep" }, | |
37 | + { } | |
38 | +}; | |
39 | + | |
40 | +static int sandbox_write_header(struct udevice *dev, uint fn, | |
41 | + struct pci_ep_header *hdr) | |
42 | +{ | |
43 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
44 | + | |
45 | + if (fn > 0) | |
46 | + return -ENODEV; | |
47 | + | |
48 | + memcpy(&priv->hdr, hdr, sizeof(*hdr)); | |
49 | + | |
50 | + return 0; | |
51 | +} | |
52 | + | |
53 | +static int sandbox_read_header(struct udevice *dev, uint fn, | |
54 | + struct pci_ep_header *hdr) | |
55 | +{ | |
56 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
57 | + | |
58 | + if (fn > 0) | |
59 | + return -ENODEV; | |
60 | + | |
61 | + memcpy(hdr, &priv->hdr, sizeof(*hdr)); | |
62 | + | |
63 | + return 0; | |
64 | +} | |
65 | + | |
66 | +static int sandbox_set_bar(struct udevice *dev, uint fn, | |
67 | + struct pci_bar *ep_bar) | |
68 | +{ | |
69 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
70 | + int bar_idx; | |
71 | + | |
72 | + if (fn > 0) | |
73 | + return -ENODEV; | |
74 | + | |
75 | + bar_idx = ep_bar->barno; | |
76 | + | |
77 | + memcpy(&priv->bars[bar_idx], ep_bar, sizeof(*ep_bar)); | |
78 | + | |
79 | + return 0; | |
80 | +} | |
81 | + | |
82 | +static int sandbox_read_bar(struct udevice *dev, uint fn, | |
83 | + struct pci_bar *ep_bar, enum pci_barno barno) | |
84 | +{ | |
85 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
86 | + int bar_idx; | |
87 | + | |
88 | + if (fn > 0) | |
89 | + return -ENODEV; | |
90 | + | |
91 | + bar_idx = ep_bar->barno; | |
92 | + | |
93 | + memcpy(ep_bar, &priv->bars[bar_idx], sizeof(*ep_bar)); | |
94 | + | |
95 | + return 0; | |
96 | +} | |
97 | + | |
98 | +static int sandbox_set_msi(struct udevice *dev, uint fn, uint interrupts) | |
99 | +{ | |
100 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
101 | + | |
102 | + if (fn > 0) | |
103 | + return -ENODEV; | |
104 | + | |
105 | + priv->msi = interrupts; | |
106 | + | |
107 | + return 0; | |
108 | +} | |
109 | + | |
110 | +static int sandbox_get_msi(struct udevice *dev, uint fn) | |
111 | +{ | |
112 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
113 | + | |
114 | + if (fn > 0) | |
115 | + return -ENODEV; | |
116 | + | |
117 | + return priv->msi; | |
118 | +} | |
119 | + | |
120 | +static int sandbox_set_msix(struct udevice *dev, uint fn, uint interrupts) | |
121 | +{ | |
122 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
123 | + | |
124 | + if (fn > 0) | |
125 | + return -ENODEV; | |
126 | + | |
127 | + priv->msix = interrupts; | |
128 | + | |
129 | + return 0; | |
130 | +} | |
131 | + | |
132 | +static int sandbox_get_msix(struct udevice *dev, uint fn) | |
133 | +{ | |
134 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
135 | + | |
136 | + if (fn > 0) | |
137 | + return -ENODEV; | |
138 | + | |
139 | + return priv->msix; | |
140 | +} | |
141 | + | |
142 | +static int sandbox_raise_irq(struct udevice *dev, uint fn, | |
143 | + enum pci_ep_irq_type type, uint interrupt_num) | |
144 | +{ | |
145 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
146 | + | |
147 | + if (fn > 0) | |
148 | + return -ENODEV; | |
149 | + | |
150 | + priv->irq_count++; | |
151 | + | |
152 | + return 0; | |
153 | +} | |
154 | + | |
155 | +static int sandbox_pci_ep_probe(struct udevice *dev) | |
156 | +{ | |
157 | + struct sandbox_pci_ep_priv *priv = dev_get_priv(dev); | |
158 | + | |
159 | + memset(priv, 0, sizeof(*priv)); | |
160 | + return 0; | |
161 | +} | |
162 | + | |
163 | +static struct pci_ep_ops sandbox_pci_ep_ops = { | |
164 | + .write_header = sandbox_write_header, | |
165 | + .read_header = sandbox_read_header, | |
166 | + .set_bar = sandbox_set_bar, | |
167 | + .read_bar = sandbox_read_bar, | |
168 | + .set_msi = sandbox_set_msi, | |
169 | + .get_msi = sandbox_get_msi, | |
170 | + .set_msix = sandbox_set_msix, | |
171 | + .get_msix = sandbox_get_msix, | |
172 | + .raise_irq = sandbox_raise_irq, | |
173 | +}; | |
174 | + | |
175 | +U_BOOT_DRIVER(pci_ep_sandbox) = { | |
176 | + .name = "pci_ep_sandbox", | |
177 | + .id = UCLASS_PCI_EP, | |
178 | + .of_match = sandbox_pci_ep_ids, | |
179 | + .probe = sandbox_pci_ep_probe, | |
180 | + .ops = &sandbox_pci_ep_ops, | |
181 | + .priv_auto_alloc_size = sizeof(struct sandbox_pci_ep_priv), | |
182 | +}; |
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874
-
mentioned in commit eb1874