Commit bb413337826ef1a1445ff9fb33424fd231430228

Authored by Ramon Fried
Committed by Tom Rini
1 parent c2ccc9e5cb

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

... ... @@ -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
... ... @@ -487,6 +487,10 @@
487 487 };
488 488 };
489 489  
  490 + pci_ep: pci_ep {
  491 + compatible = "sandbox,pci_ep";
  492 + };
  493 +
490 494 probing {
491 495 compatible = "simple-bus";
492 496 test1 {
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
... ... @@ -5,4 +5,5 @@
5 5  
6 6 obj-y += pci_ep-uclass.o
7 7 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
  8 +obj-$(CONFIG_PCI_SANDBOX_EP) += sandbox-pci_ep.o
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 +};