layerscape: update patches-4.14 to LSDK 19.03
[openwrt/staging/stintel.git] / target / linux / layerscape / patches-4.14 / 711-dpaa-bqman-support-layerscape.patch
index 7946d3cbc1527a1252ea78139bdc92b25c5cd3a7..715cfe0875aa750ef087716ce729b8400a1117e8 100644 (file)
@@ -1,28 +1,32 @@
-From 48dbe4b3a31795b8efdfff82f69eccd086052eed Mon Sep 17 00:00:00 2001
+From 371e99a257cb714f9a6027d6571cb1a43855d926 Mon Sep 17 00:00:00 2001
 From: Biwen Li <biwen.li@nxp.com>
-Date: Fri, 16 Nov 2018 10:27:30 +0800
-Subject: [PATCH 16/39] dpaa-bqman: support layerscape 
+Date: Wed, 17 Apr 2019 18:58:24 +0800
+Subject: [PATCH] dpaa-bqman: support layerscape
+
 This is an integrated patch of dpaa-bqman for layerscape
 
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
 Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
 Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
 Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
 Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
 ---
  drivers/soc/fsl/qbman/Kconfig       |   2 +-
- drivers/soc/fsl/qbman/bman.c        |  24 ++++-
- drivers/soc/fsl/qbman/bman_ccsr.c   |  35 ++++++-
- drivers/soc/fsl/qbman/bman_portal.c |  12 ++-
+ drivers/soc/fsl/qbman/bman.c        |  24 +++-
+ drivers/soc/fsl/qbman/bman_ccsr.c   |  57 +++++++++-
+ drivers/soc/fsl/qbman/bman_portal.c |  44 ++++++--
  drivers/soc/fsl/qbman/bman_priv.h   |   3 +
  drivers/soc/fsl/qbman/dpaa_sys.h    |   8 +-
- drivers/soc/fsl/qbman/qman.c        |  46 ++++++++-
- drivers/soc/fsl/qbman/qman_ccsr.c   | 140 ++++++++++++++++++++++------
- drivers/soc/fsl/qbman/qman_portal.c |  12 ++-
+ drivers/soc/fsl/qbman/qman.c        |  46 +++++++-
+ drivers/soc/fsl/qbman/qman_ccsr.c   | 168 +++++++++++++++++++++++-----
+ drivers/soc/fsl/qbman/qman_portal.c |  60 ++++++++--
  drivers/soc/fsl/qbman/qman_priv.h   |   5 +-
  drivers/soc/fsl/qbman/qman_test.h   |   2 -
- 11 files changed, 236 insertions(+), 53 deletions(-)
+ include/soc/fsl/bman.h              |  16 +++
+ include/soc/fsl/qman.h              |  17 +++
+ 13 files changed, 390 insertions(+), 62 deletions(-)
 
 --- a/drivers/soc/fsl/qbman/Kconfig
 +++ b/drivers/soc/fsl/qbman/Kconfig
@@ -83,20 +87,49 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return 0;
 --- a/drivers/soc/fsl/qbman/bman_ccsr.c
 +++ b/drivers/soc/fsl/qbman/bman_ccsr.c
-@@ -170,10 +170,11 @@ static int fsl_bman_probe(struct platfor
+@@ -29,6 +29,7 @@
+  */
+ #include "bman_priv.h"
++#include <linux/iommu.h>
+ u16 bman_ip_rev;
+ EXPORT_SYMBOL(bman_ip_rev);
+@@ -120,6 +121,7 @@ static void bm_set_memory(u64 ba, u32 si
+  */
+ static dma_addr_t fbpr_a;
+ static size_t fbpr_sz;
++static int __bman_probed;
+ static int bman_fbpr(struct reserved_mem *rmem)
+ {
+@@ -166,14 +168,24 @@ static irqreturn_t bman_isr(int irq, voi
+       return IRQ_HANDLED;
+ }
++int bman_is_probed(void)
++{
++      return __bman_probed;
++}
++EXPORT_SYMBOL_GPL(bman_is_probed);
++
+ static int fsl_bman_probe(struct platform_device *pdev)
  {
        int ret, err_irq;
        struct device *dev = &pdev->dev;
 -      struct device_node *node = dev->of_node;
 +      struct device_node *mem_node, *node = dev->of_node;
++      struct iommu_domain *domain;
        struct resource *res;
        u16 id, bm_pool_cnt;
        u8 major, minor;
 +      u64 size;
++
++      __bman_probed = -1;
  
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-@@ -201,6 +202,38 @@ static int fsl_bman_probe(struct platfor
+@@ -201,6 +213,47 @@ static int fsl_bman_probe(struct platfor
                return -ENODEV;
        }
  
@@ -131,13 +164,98 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      }
 +
 +      dev_dbg(dev, "Allocated FBPR 0x%llx 0x%zx\n", fbpr_a, fbpr_sz);
++
++      /* Create an 1-to-1 iommu mapping for FBPR area */
++      domain = iommu_get_domain_for_dev(dev);
++      if (domain) {
++              ret = iommu_map(domain, fbpr_a, fbpr_a, PAGE_ALIGN(fbpr_sz),
++                              IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
++              if (ret)
++                      dev_warn(dev, "failed to iommu_map() %d\n", ret);
++      }
 +
        bm_set_memory(fbpr_a, fbpr_sz);
  
        err_irq = platform_get_irq(pdev, 0);
+@@ -240,6 +293,8 @@ static int fsl_bman_probe(struct platfor
+               return ret;
+       }
++      __bman_probed = 1;
++
+       return 0;
+ };
 --- a/drivers/soc/fsl/qbman/bman_portal.c
 +++ b/drivers/soc/fsl/qbman/bman_portal.c
-@@ -123,7 +123,14 @@ static int bman_portal_probe(struct plat
+@@ -32,6 +32,7 @@
+ static struct bman_portal *affine_bportals[NR_CPUS];
+ static struct cpumask portal_cpus;
++static int __bman_portals_probed;
+ /* protect bman global registers and global data shared among portals */
+ static DEFINE_SPINLOCK(bman_lock);
+@@ -85,6 +86,12 @@ static int bman_online_cpu(unsigned int
+       return 0;
+ }
++int bman_portals_probed(void)
++{
++      return __bman_portals_probed;
++}
++EXPORT_SYMBOL_GPL(bman_portals_probed);
++
+ static int bman_portal_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -92,11 +99,21 @@ static int bman_portal_probe(struct plat
+       struct bm_portal_config *pcfg;
+       struct resource *addr_phys[2];
+       void __iomem *va;
+-      int irq, cpu;
++      int irq, cpu, err;
++
++      err = bman_is_probed();
++      if (!err)
++              return -EPROBE_DEFER;
++      if (err < 0) {
++              dev_err(&pdev->dev, "failing probe due to bman probe error\n");
++              return -ENODEV;
++      }
+       pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
+-      if (!pcfg)
++      if (!pcfg) {
++              __bman_portals_probed = -1;
+               return -ENOMEM;
++      }
+       pcfg->dev = dev;
+@@ -104,14 +121,14 @@ static int bman_portal_probe(struct plat
+                                            DPAA_PORTAL_CE);
+       if (!addr_phys[0]) {
+               dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
+       }
+       addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
+                                            DPAA_PORTAL_CI);
+       if (!addr_phys[1]) {
+               dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
+       }
+       pcfg->cpu = -1;
+@@ -119,11 +136,18 @@ static int bman_portal_probe(struct plat
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0) {
+               dev_err(dev, "Can't get %pOF IRQ'\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
        }
        pcfg->irq = irq;
  
@@ -153,7 +271,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (!va) {
                dev_err(dev, "ioremap::CE failed\n");
                goto err_ioremap1;
-@@ -131,8 +138,7 @@ static int bman_portal_probe(struct plat
+@@ -131,8 +155,7 @@ static int bman_portal_probe(struct plat
  
        pcfg->addr_virt[DPAA_PORTAL_CE] = va;
  
@@ -163,6 +281,25 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (!va) {
                dev_err(dev, "ioremap::CI failed\n");
                goto err_ioremap2;
+@@ -149,6 +172,9 @@ static int bman_portal_probe(struct plat
+       }
+       cpumask_set_cpu(cpu, &portal_cpus);
++      if (!__bman_portals_probed &&
++          cpumask_weight(&portal_cpus) == num_online_cpus())
++              __bman_portals_probed = 1;
+       spin_unlock(&bman_lock);
+       pcfg->cpu = cpu;
+@@ -168,6 +194,8 @@ err_portal_init:
+ err_ioremap2:
+       iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]);
+ err_ioremap1:
++       __bman_portals_probed = -1;
++
+       return -ENXIO;
+ }
 --- a/drivers/soc/fsl/qbman/bman_priv.h
 +++ b/drivers/soc/fsl/qbman/bman_priv.h
 @@ -33,6 +33,9 @@
@@ -290,7 +427,23 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        /*
 --- a/drivers/soc/fsl/qbman/qman_ccsr.c
 +++ b/drivers/soc/fsl/qbman/qman_ccsr.c
-@@ -401,21 +401,42 @@ static int qm_init_pfdr(struct device *d
+@@ -29,6 +29,7 @@
+  */
+ #include "qman_priv.h"
++#include <linux/iommu.h>
+ u16 qman_ip_rev;
+ EXPORT_SYMBOL(qman_ip_rev);
+@@ -273,6 +274,7 @@ static const struct qman_error_info_mdat
+ static u32 __iomem *qm_ccsr_start;
+ /* A SDQCR mask comprising all the available/visible pool channels */
+ static u32 qm_pools_sdqcr;
++static int __qman_probed;
+ static inline u32 qm_ccsr_in(u32 offset)
+ {
+@@ -401,21 +403,42 @@ static int qm_init_pfdr(struct device *d
  }
  
  /*
@@ -338,7 +491,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return 0;
  }
  RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
-@@ -431,32 +452,13 @@ static int qman_pfdr(struct reserved_mem
+@@ -431,32 +454,13 @@ static int qman_pfdr(struct reserved_mem
  }
  RESERVEDMEM_OF_DECLARE(qman_pfdr, "fsl,qman-pfdr", qman_pfdr);
  
@@ -373,21 +526,49 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  static void log_edata_bits(struct device *dev, u32 bit_count)
  {
        u32 i, j, mask = 0xffffffff;
-@@ -687,11 +689,12 @@ static int qman_resource_init(struct dev
+@@ -595,6 +599,7 @@ static int qman_init_ccsr(struct device
+ #define LIO_CFG_LIODN_MASK 0x0fff0000
+ void qman_liodn_fixup(u16 channel)
+ {
++#ifdef CONFIG_PPC
+       static int done;
+       static u32 liodn_offset;
+       u32 before, after;
+@@ -614,6 +619,7 @@ void qman_liodn_fixup(u16 channel)
+               qm_ccsr_out(REG_REV3_QCSP_LIO_CFG(idx), after);
+       else
+               qm_ccsr_out(REG_QCSP_LIO_CFG(idx), after);
++#endif
+ }
+ #define IO_CFG_SDEST_MASK 0x00ff0000
+@@ -684,14 +690,24 @@ static int qman_resource_init(struct dev
+       return 0;
+ }
++int qman_is_probed(void)
++{
++      return __qman_probed;
++}
++EXPORT_SYMBOL_GPL(qman_is_probed);
++
  static int fsl_qman_probe(struct platform_device *pdev)
  {
        struct device *dev = &pdev->dev;
 -      struct device_node *node = dev->of_node;
 +      struct device_node *mem_node, *node = dev->of_node;
++      struct iommu_domain *domain;
        struct resource *res;
        int ret, err_irq;
        u16 id;
        u8 major, minor;
 +      u64 size;
++
++      __qman_probed = -1;
  
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-@@ -717,6 +720,8 @@ static int fsl_qman_probe(struct platfor
+@@ -717,6 +733,8 @@ static int fsl_qman_probe(struct platfor
                qman_ip_rev = QMAN_REV30;
        else if (major == 3 && minor == 1)
                qman_ip_rev = QMAN_REV31;
@@ -396,7 +577,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        else {
                dev_err(dev, "Unknown QMan version\n");
                return -ENODEV;
-@@ -727,10 +732,83 @@ static int fsl_qman_probe(struct platfor
+@@ -727,10 +745,96 @@ static int fsl_qman_probe(struct platfor
                qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
        }
  
@@ -481,12 +662,116 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              }
 +      }
 +      dev_info(dev, "Allocated PFDR 0x%llx 0x%zx\n", pfdr_a, pfdr_sz);
++
++      /* Create an 1-to-1 iommu mapping for fqd and pfdr areas */
++      domain = iommu_get_domain_for_dev(dev);
++      if (domain) {
++              ret = iommu_map(domain, fqd_a, fqd_a, PAGE_ALIGN(fqd_sz),
++                              IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
++              if (ret)
++                      dev_warn(dev, "iommu_map(fqd) failed %d\n", ret);
++              ret = iommu_map(domain, pfdr_a, pfdr_a, PAGE_ALIGN(pfdr_sz),
++                              IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
++              if (ret)
++                      dev_warn(dev, "iommu_map(pfdr) failed %d\n", ret);
++      }
  
        ret = qman_init_ccsr(dev);
        if (ret) {
+@@ -793,6 +897,8 @@ static int fsl_qman_probe(struct platfor
+       if (ret)
+               return ret;
++      __qman_probed = 1;
++
+       return 0;
+ }
 --- a/drivers/soc/fsl/qbman/qman_portal.c
 +++ b/drivers/soc/fsl/qbman/qman_portal.c
-@@ -262,7 +262,14 @@ static int qman_portal_probe(struct plat
+@@ -29,6 +29,7 @@
+  */
+ #include "qman_priv.h"
++#include <linux/iommu.h>
+ struct qman_portal *qman_dma_portal;
+ EXPORT_SYMBOL(qman_dma_portal);
+@@ -38,6 +39,7 @@ EXPORT_SYMBOL(qman_dma_portal);
+ #define CONFIG_FSL_DPA_PIRQ_FAST  1
+ static struct cpumask portal_cpus;
++static int __qman_portals_probed;
+ /* protect qman global registers and global data shared among portals */
+ static DEFINE_SPINLOCK(qman_lock);
+@@ -218,19 +220,36 @@ static int qman_online_cpu(unsigned int
+       return 0;
+ }
++int qman_portals_probed(void)
++{
++      return __qman_portals_probed;
++}
++EXPORT_SYMBOL_GPL(qman_portals_probed);
++
+ static int qman_portal_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
++      struct iommu_domain *domain;
+       struct qm_portal_config *pcfg;
+       struct resource *addr_phys[2];
+       void __iomem *va;
+       int irq, cpu, err;
+       u32 val;
++      err = qman_is_probed();
++      if (!err)
++              return -EPROBE_DEFER;
++      if (err < 0) {
++              dev_err(&pdev->dev, "failing probe due to qman probe error\n");
++              return -ENODEV;
++      }
++
+       pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
+-      if (!pcfg)
++      if (!pcfg) {
++              __qman_portals_probed = -1;
+               return -ENOMEM;
++      }
+       pcfg->dev = dev;
+@@ -238,19 +257,20 @@ static int qman_portal_probe(struct plat
+                                            DPAA_PORTAL_CE);
+       if (!addr_phys[0]) {
+               dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
+       }
+       addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
+                                            DPAA_PORTAL_CI);
+       if (!addr_phys[1]) {
+               dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
+       }
+       err = of_property_read_u32(node, "cell-index", &val);
+       if (err) {
+               dev_err(dev, "Can't get %pOF property 'cell-index'\n", node);
++              __qman_portals_probed = -1;
+               return err;
+       }
+       pcfg->channel = val;
+@@ -258,11 +278,18 @@ static int qman_portal_probe(struct plat
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0) {
+               dev_err(dev, "Can't get %pOF IRQ\n", node);
+-              return -ENXIO;
++              goto err_ioremap1;
        }
        pcfg->irq = irq;
  
@@ -502,7 +787,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (!va) {
                dev_err(dev, "ioremap::CE failed\n");
                goto err_ioremap1;
-@@ -270,8 +277,7 @@ static int qman_portal_probe(struct plat
+@@ -270,8 +297,7 @@ static int qman_portal_probe(struct plat
  
        pcfg->addr_virt[DPAA_PORTAL_CE] = va;
  
@@ -512,6 +797,47 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (!va) {
                dev_err(dev, "ioremap::CI failed\n");
                goto err_ioremap2;
+@@ -279,6 +305,21 @@ static int qman_portal_probe(struct plat
+       pcfg->addr_virt[DPAA_PORTAL_CI] = va;
++      /* Create an 1-to-1 iommu mapping for cena portal area */
++      domain = iommu_get_domain_for_dev(dev);
++      if (domain) {
++              /*
++               * Note: not mapping this as cacheable triggers the infamous
++               * QMan CIDE error.
++               */
++              err = iommu_map(domain,
++                              addr_phys[0]->start, addr_phys[0]->start,
++                              PAGE_ALIGN(resource_size(addr_phys[0])),
++                              IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
++              if (err)
++                      dev_warn(dev, "failed to iommu_map() %d\n", err);
++      }
++
+       pcfg->pools = qm_get_pools_sdqcr();
+       spin_lock(&qman_lock);
+@@ -290,6 +331,9 @@ static int qman_portal_probe(struct plat
+       }
+       cpumask_set_cpu(cpu, &portal_cpus);
++      if (!__qman_portals_probed &&
++          cpumask_weight(&portal_cpus) == num_online_cpus())
++              __qman_portals_probed = 1;
+       spin_unlock(&qman_lock);
+       pcfg->cpu = cpu;
+@@ -314,6 +358,8 @@ err_portal_init:
+ err_ioremap2:
+       iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]);
+ err_ioremap1:
++      __qman_portals_probed = -1;
++
+       return -ENXIO;
+ }
 --- a/drivers/soc/fsl/qbman/qman_priv.h
 +++ b/drivers/soc/fsl/qbman/qman_priv.h
 @@ -28,13 +28,13 @@
@@ -548,3 +874,50 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 -
  int qman_test_stash(void);
  int qman_test_api(void);
+--- a/include/soc/fsl/bman.h
++++ b/include/soc/fsl/bman.h
+@@ -126,4 +126,20 @@ int bman_release(struct bman_pool *pool,
+  */
+ int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num);
++/**
++ * bman_is_probed - Check if bman is probed
++ *
++ * Returns 1 if the bman driver successfully probed, -1 if the bman driver
++ * failed to probe or 0 if the bman driver did not probed yet.
++ */
++int bman_is_probed(void);
++/**
++ * bman_portals_probed - Check if all cpu bound bman portals are probed
++ *
++ * Returns 1 if all the required cpu bound bman portals successfully probed,
++ * -1 if probe errors appeared or 0 if the bman portals did not yet finished
++ * probing.
++ */
++int bman_portals_probed(void);
++
+ #endif        /* __FSL_BMAN_H */
+--- a/include/soc/fsl/qman.h
++++ b/include/soc/fsl/qman.h
+@@ -1186,4 +1186,21 @@ int qman_alloc_cgrid_range(u32 *result,
+  */
+ int qman_release_cgrid(u32 id);
++/**
++ * qman_is_probed - Check if qman is probed
++ *
++ * Returns 1 if the qman driver successfully probed, -1 if the qman driver
++ * failed to probe or 0 if the qman driver did not probed yet.
++ */
++int qman_is_probed(void);
++
++/**
++ * qman_portals_probed - Check if all cpu bound qman portals are probed
++ *
++ * Returns 1 if all the required cpu bound qman portals successfully probed,
++ * -1 if probe errors appeared or 0 if the qman portals did not yet finished
++ * probing.
++ */
++int qman_portals_probed(void);
++
+ #endif        /* __FSL_QMAN_H */