Merge tag 'uniphier-v2019.10' of https://gitlab.denx.de/u-boot/custodians/u-boot...
[oweals/u-boot.git] / 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 };