blob: aa623fa357d561048b1c6311b19800207000e79e [file] [log] [blame]
Ramon Friedc64f19b2019-04-27 11:15:23 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2019 Ramon Fried <ramon.fried@gmail.com>
4 */
5
Ramon Friedc64f19b2019-04-27 11:15:23 +03006#include <dm.h>
7#include <errno.h>
8#include <pci.h>
9#include <pci_ep.h>
10#include <asm/test.h>
11
12/**
13 * struct sandbox_pci_ep_priv - private data for driver
14 * @hdr: Stores the EP device header
15 * @msix: required MSIx count;
16 * @msi: required MSI count;
17 */
18struct sandbox_pci_ep_priv {
19 struct pci_ep_header hdr;
20 struct pci_bar bars[6];
21 int msix;
22 int msi;
23 int irq_count;
24};
25
26/* Method exported for testing purposes */
27int sandbox_get_pci_ep_irq_count(struct udevice *dev)
28{
29 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
30
31 return priv->irq_count;
32}
33
34static const struct udevice_id sandbox_pci_ep_ids[] = {
35 { .compatible = "sandbox,pci_ep" },
36 { }
37};
38
39static int sandbox_write_header(struct udevice *dev, uint fn,
40 struct pci_ep_header *hdr)
41{
42 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
43
44 if (fn > 0)
45 return -ENODEV;
46
47 memcpy(&priv->hdr, hdr, sizeof(*hdr));
48
49 return 0;
50}
51
52static int sandbox_read_header(struct udevice *dev, uint fn,
53 struct pci_ep_header *hdr)
54{
55 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
56
57 if (fn > 0)
58 return -ENODEV;
59
60 memcpy(hdr, &priv->hdr, sizeof(*hdr));
61
62 return 0;
63}
64
65static int sandbox_set_bar(struct udevice *dev, uint fn,
66 struct pci_bar *ep_bar)
67{
68 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
69 int bar_idx;
70
71 if (fn > 0)
72 return -ENODEV;
73
74 bar_idx = ep_bar->barno;
75
76 memcpy(&priv->bars[bar_idx], ep_bar, sizeof(*ep_bar));
77
78 return 0;
79}
80
81static int sandbox_read_bar(struct udevice *dev, uint fn,
82 struct pci_bar *ep_bar, enum pci_barno barno)
83{
84 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
Ramon Friedc64f19b2019-04-27 11:15:23 +030085
86 if (fn > 0)
87 return -ENODEV;
88
Ramon Frieda4e697d2019-07-15 23:04:41 +030089 memcpy(ep_bar, &priv->bars[barno], sizeof(*ep_bar));
Ramon Friedc64f19b2019-04-27 11:15:23 +030090
91 return 0;
92}
93
94static int sandbox_set_msi(struct udevice *dev, uint fn, uint interrupts)
95{
96 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
97
98 if (fn > 0)
99 return -ENODEV;
100
101 priv->msi = interrupts;
102
103 return 0;
104}
105
106static int sandbox_get_msi(struct udevice *dev, uint fn)
107{
108 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
109
110 if (fn > 0)
111 return -ENODEV;
112
113 return priv->msi;
114}
115
116static int sandbox_set_msix(struct udevice *dev, uint fn, uint interrupts)
117{
118 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
119
120 if (fn > 0)
121 return -ENODEV;
122
123 priv->msix = interrupts;
124
125 return 0;
126}
127
128static int sandbox_get_msix(struct udevice *dev, uint fn)
129{
130 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
131
132 if (fn > 0)
133 return -ENODEV;
134
135 return priv->msix;
136}
137
138static int sandbox_raise_irq(struct udevice *dev, uint fn,
139 enum pci_ep_irq_type type, uint interrupt_num)
140{
141 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
142
143 if (fn > 0)
144 return -ENODEV;
145
146 priv->irq_count++;
147
148 return 0;
149}
150
151static int sandbox_pci_ep_probe(struct udevice *dev)
152{
153 struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
154
155 memset(priv, 0, sizeof(*priv));
156 return 0;
157}
158
159static struct pci_ep_ops sandbox_pci_ep_ops = {
160 .write_header = sandbox_write_header,
161 .read_header = sandbox_read_header,
162 .set_bar = sandbox_set_bar,
163 .read_bar = sandbox_read_bar,
164 .set_msi = sandbox_set_msi,
165 .get_msi = sandbox_get_msi,
166 .set_msix = sandbox_set_msix,
167 .get_msix = sandbox_get_msix,
168 .raise_irq = sandbox_raise_irq,
169};
170
171U_BOOT_DRIVER(pci_ep_sandbox) = {
172 .name = "pci_ep_sandbox",
173 .id = UCLASS_PCI_EP,
174 .of_match = sandbox_pci_ep_ids,
175 .probe = sandbox_pci_ep_probe,
176 .ops = &sandbox_pci_ep_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700177 .priv_auto = sizeof(struct sandbox_pci_ep_priv),
Ramon Friedc64f19b2019-04-27 11:15:23 +0300178};