All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] [PATCH 2/3] ThunderX platform support for PCI
@ 2015-02-20 11:40 Manish Jaggi
  0 siblings, 0 replies; only message in thread
From: Manish Jaggi @ 2015-02-20 11:40 UTC (permalink / raw)
  To: xen-devel
  Cc: Prasun.kapoor, Vijaya >> Kumar, Vijaya, Julien Grall,
	Stefano Stabellini (Stefano.Stabellini@citrix.com), Ian Campbell

Support added for the thunderX platfrom for reading writing config space
---
  xen/arch/arm/platforms/thunderx.c | 124 ++++++++++++++++++++++++++++++++++++++
  1 file changed, 124 insertions(+)

diff --git a/xen/arch/arm/platforms/thunderx.c b/xen/arch/arm/platforms/thunderx.c
index 96560e1..1b6f0c3 100644
--- a/xen/arch/arm/platforms/thunderx.c
+++ b/xen/arch/arm/platforms/thunderx.c
@@ -3,6 +3,7 @@
   *
   * Cavium Thunder specific settings
   *
+ * Manish Jaggi <manish.jaggi@caviumnetworks.com>
   * Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
   * Copyright (c) 2015 Cavium Inc.
   *
@@ -17,8 +18,48 @@
   * GNU General Public License for more details.
   */
  
+#include <asm/device.h>
+#include <asm/io.h>
+#include <xen/mm.h>
+#include <xen/vmap.h>
+#include <asm/pci.h>
  #include <asm/platform.h>
  
+#define THUNDER_PCIE_BUS_SHIFT          20
+#define THUNDER_PCIE_DEV_SHIFT          15
+#define THUNDER_PCIE_FUNC_SHIFT         12
+#define MAX_PCI_BRIDGE 4
+#define MAX_PCI_BARS 4
+struct pci_conf {
+    paddr_t valid;
+    paddr_t base;
+    paddr_t size;
+    void *dt_node;
+};
+struct pci_conf thunder_pci_ctrl_confs[MAX_PCI_BRIDGE];
+static int thunder_pci_dt_node_init(struct dt_device_node *node, const void *data)
+{
+    int i, res;
+    struct pci_conf *pconf;
+
+    for ( i = 0; i < MAX_PCI_BRIDGE; i++ )
+    {
+        pconf = &thunder_pci_ctrl_confs[i];
+        if ( pconf->valid )
+            continue;
+
+        res = dt_device_get_address(node, 0, &pconf->base, &pconf->size);
+        if ( res || !pconf->base )
+           panic("PCI: Cannot find a valid PCI reg address");
+
+        pconf->dt_node = node;
+        pconf->valid=1;
+        break;
+    }
+
+    return 1;
+}
+
  static int thunderx_specific_mapping(struct domain *d)
  {
      uint64_t addr, size;
@@ -43,6 +84,86 @@ static int thunderx_specific_mapping(struct domain *d)
      return 0;
  }
  
+static paddr_t thunder_pci_build_config_addr(int seg, int bus, int dev,
+                                             int fn, int reg)
+{
+    struct pci_conf *pconf;
+    paddr_t func_cfg_base;
+    pconf = &thunder_pci_ctrl_confs[seg];
+
+    func_cfg_base =  pconf->base +
+                     ((bus << THUNDER_PCIE_BUS_SHIFT) |
+                      (dev << THUNDER_PCIE_DEV_SHIFT) |
+                      (fn  << THUNDER_PCIE_FUNC_SHIFT));
+
+    return func_cfg_base;
+}
+static int thunder_pci_read_config(unsigned int seg, unsigned int bus,
+                                   unsigned int dev, unsigned int func,
+                                   int reg, int size, uint32_t *val)
+{
+    paddr_t func_cfg_base;
+    void __iomem *cfg_addr = NULL;
+
+    func_cfg_base = thunder_pci_build_config_addr(seg, bus, dev, func, reg);
+    cfg_addr = ioremap_nocache(func_cfg_base, PAGE_SIZE);
+    if ( cfg_addr )
+    {
+        cfg_addr += (reg & ~0x3);
+        *val = readl(cfg_addr);
+
+        if ( size == 1 )
+            *val = (*val >> (8 * (reg & 3))) & 0xff;
+        else if (size == 2)
+            *val = (*val >> (8 * (reg & 3))) & 0xffff;
+        iounmap(cfg_addr);
+        return 0;
+    }
+    return -1;
+}
+
+static int thunder_pci_write_config(unsigned int seg, unsigned int bus,
+                                    unsigned int dev, unsigned int func,
+                                    int reg, int size, uint32_t val)
+{
+    void __iomem *cfg_addr = NULL;
+    uint32_t cur_val, final_val;
+    paddr_t func_cfg_base;
+
+    func_cfg_base = thunder_pci_build_config_addr(seg, bus, dev, func, reg);
+    cfg_addr = ioremap_nocache(func_cfg_base, PAGE_SIZE);
+    if ( cfg_addr )
+    {
+        cfg_addr += (reg & ~0x3);
+
+        cur_val = readl(cfg_addr);
+
+        switch ( size )
+        {
+        case 1:
+            val = ((val & 0xff) << (8 * (reg & 3)));
+            cur_val = cur_val & ~(0xff << (8 * (reg & 3)));
+            break;
+        case 2:
+            val = ((val & 0xffff) << (8 * (reg & 3)));
+            cur_val = cur_val & ~(0xffff << (8 * (reg & 3)));
+            break;
+        case 4:
+            cur_val = 0;
+            break;
+        default:
+            goto end;
+        }
+
+        final_val = cur_val | val;
+        writel(final_val, cfg_addr);
+        iounmap(cfg_addr);
+        return 0;
+    }
+end:
+    return -1;
+}
+
  static const char * const thunderx_dt_compat[] __initconst =
  {
      "cavium,thunder-88xx",
@@ -52,6 +173,9 @@ static const char * const thunderx_dt_compat[] __initconst =
  PLATFORM_START(thunderx, "THUNDERX")
      .compatible = thunderx_dt_compat,
      .specific_mapping = thunderx_specific_mapping,
+    .pci_read_config = thunder_pci_read_config,
+    .pci_write_config = thunder_pci_write_config,
+    .pci_dt_node_init = thunder_pci_dt_node_init,
      .dom0_gnttab_start = 0x40000000000,
      .dom0_gnttab_size = 0x20000,
  PLATFORM_END
-- 
1.9.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-02-20 11:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-20 11:40 [RFC] [PATCH 2/3] ThunderX platform support for PCI Manish Jaggi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.