[PATCH v2 3/7]powerpc/powernv: Nest PMU detection and device tree parser

2015-06-10 Thread Madhavan Srinivasan
Create a file "nest-pmu.c" to contain nest pmu related functions. Code
to detect nest pmu support and parser to collect per-chip reserved memory
region information from device tree (DT).

Detection mechanism is to look for specific property "ibm,ima-chip" in DT.
For Nest pmu, device tree will have two set of information.
1) Per-chip reserved memory region for nest pmu counter collection area.
2) Supported Nest PMUs and events

Device tree layout for the Nest PMU as follows.

  / -- DT root folder
  |
  -nest-ima -- Nest PMU folder
   |

   -ima-chip@  -- Per-chip folder for reserved region information
|
-ibm,chip-id-- Chip id
-ibm,ima-chip
-reg-- HOMER PORE Nest Counter collection Address (RA)
-size   -- size to map in kernel space

   -Alink_BW-- Nest PMU folder
|
-Alink0 -- Nest PMU Alink Event file
-scale.Alink0.scale -- Event scale file
-unit.Alink0.unit   -- Event unit file
-device_type-- "nest-ima-unit" marker
  

Subsequent patch will parse the next part of the DT to find various
Nest PMUs and their events.

Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Anton Blanchard 
Cc: Sukadev Bhattiprolu 
Cc: Anshuman Khandual 
Cc: Stephane Eranian 
Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/perf/Makefile   |  2 +-
 arch/powerpc/perf/nest-pmu.c | 78 
 2 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/perf/nest-pmu.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index f9c083a..6da656b 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS)   += callchain.o
 obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o
 obj64-$(CONFIG_PPC_PERF_CTRS)  += power4-pmu.o ppc970-pmu.o power5-pmu.o \
   power5+-pmu.o power6-pmu.o power7-pmu.o \
-  power8-pmu.o
+  power8-pmu.o nest-pmu.o
 obj32-$(CONFIG_PPC_PERF_CTRS)  += mpc7450-pmu.o
 
 obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
diff --git a/arch/powerpc/perf/nest-pmu.c b/arch/powerpc/perf/nest-pmu.c
new file mode 100644
index 000..e993630
--- /dev/null
+++ b/arch/powerpc/perf/nest-pmu.c
@@ -0,0 +1,78 @@
+/*
+ * Nest Performance Monitor counter support for POWER8 processors.
+ *
+ * Copyright (C) 2015 Madhavan Srinivasan, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "nest-pmu.h"
+
+static struct perchip_nest_info p8_perchip_nest_info[P8_MAX_CHIP];
+
+static int nest_ima_dt_parser(void)
+{
+   const __be32 *gcid;
+   const __be64 *chip_ima_reg;
+   const __be64 *chip_ima_size;
+   struct device_node *dev;
+   int idx;
+
+   /*
+* "nest-ima" folder contains two things,
+* a) per-chip reserved memory region for Nest PMU Counter data
+* b) Support Nest PMU units and their event files
+*/
+   for_each_node_with_property(dev, "ibm,ima-chip") {
+   gcid = of_get_property(dev, "ibm,chip-id", NULL);
+   chip_ima_reg = of_get_property(dev, "reg", NULL);
+   chip_ima_size = of_get_property(dev, "size", NULL);
+   if ((!gcid) || (!chip_ima_reg) || (!chip_ima_size)) {
+   pr_err("Nest_PMU: device %s missing property \n",
+   dev->full_name);
+   return -ENODEV;
+   }
+
+   /* Save per-chip reserve memory region */
+   idx = (uint32_t)be32_to_cpup(gcid);
+   p8_perchip_nest_info[idx].pbase = be64_to_cpup(chip_ima_reg);
+   p8_perchip_nest_info[idx].size = be64_to_cpup(chip_ima_size);
+   p8_perchip_nest_info[idx].vbase = (uint64_t)
+   phys_to_virt(p8_perchip_nest_info[idx].pbase);
+   }
+
+   return 0;
+}
+
+static int __init nest_pmu_init(void)
+{
+   int ret = -ENODEV;
+
+   /*
+* Lets do this only if we are hypervisor
+*/
+   if (!cur_cpu_spec->oprofile_cpu_type ||
+   !(strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8") == 0) ||
+   !cpu_has_feature(CPU_FTR_HVMODE))
+   return ret;
+
+   /*
+* Nest PMU information are grouped under "nest-ima" node
+* of the top-level Device-Tree directory. Detect Nest PMU
+* with "ibm,ima-chip" property.
+*/
+   if (!of_find_node_with_property(NULL, "ibm,ima-chip"))
+   return ret;
+
+   /*
+* Parser Device-tree for Nest PMU information
+*/
+   ret = nest_ima_dt_parser();
+   if (ret)
+   

[PATCH v2 3/7]powerpc/powernv: Nest PMU detection and device tree parser

2015-06-10 Thread Madhavan Srinivasan
Create a file nest-pmu.c to contain nest pmu related functions. Code
to detect nest pmu support and parser to collect per-chip reserved memory
region information from device tree (DT).

Detection mechanism is to look for specific property ibm,ima-chip in DT.
For Nest pmu, device tree will have two set of information.
1) Per-chip reserved memory region for nest pmu counter collection area.
2) Supported Nest PMUs and events

Device tree layout for the Nest PMU as follows.

  / -- DT root folder
  |
  -nest-ima -- Nest PMU folder
   |

   -ima-chip@chip-id  -- Per-chip folder for reserved region information
|
-ibm,chip-id-- Chip id
-ibm,ima-chip
-reg-- HOMER PORE Nest Counter collection Address (RA)
-size   -- size to map in kernel space

   -Alink_BW-- Nest PMU folder
|
-Alink0 -- Nest PMU Alink Event file
-scale.Alink0.scale -- Event scale file
-unit.Alink0.unit   -- Event unit file
-device_type-- nest-ima-unit marker
  

Subsequent patch will parse the next part of the DT to find various
Nest PMUs and their events.

Cc: Michael Ellerman m...@ellerman.id.au
Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
Cc: Paul Mackerras pau...@samba.org
Cc: Anton Blanchard an...@samba.org
Cc: Sukadev Bhattiprolu suka...@linux.vnet.ibm.com
Cc: Anshuman Khandual khand...@linux.vnet.ibm.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Madhavan Srinivasan ma...@linux.vnet.ibm.com
---
 arch/powerpc/perf/Makefile   |  2 +-
 arch/powerpc/perf/nest-pmu.c | 78 
 2 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/perf/nest-pmu.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index f9c083a..6da656b 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS)   += callchain.o
 obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o
 obj64-$(CONFIG_PPC_PERF_CTRS)  += power4-pmu.o ppc970-pmu.o power5-pmu.o \
   power5+-pmu.o power6-pmu.o power7-pmu.o \
-  power8-pmu.o
+  power8-pmu.o nest-pmu.o
 obj32-$(CONFIG_PPC_PERF_CTRS)  += mpc7450-pmu.o
 
 obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
diff --git a/arch/powerpc/perf/nest-pmu.c b/arch/powerpc/perf/nest-pmu.c
new file mode 100644
index 000..e993630
--- /dev/null
+++ b/arch/powerpc/perf/nest-pmu.c
@@ -0,0 +1,78 @@
+/*
+ * Nest Performance Monitor counter support for POWER8 processors.
+ *
+ * Copyright (C) 2015 Madhavan Srinivasan, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include nest-pmu.h
+
+static struct perchip_nest_info p8_perchip_nest_info[P8_MAX_CHIP];
+
+static int nest_ima_dt_parser(void)
+{
+   const __be32 *gcid;
+   const __be64 *chip_ima_reg;
+   const __be64 *chip_ima_size;
+   struct device_node *dev;
+   int idx;
+
+   /*
+* nest-ima folder contains two things,
+* a) per-chip reserved memory region for Nest PMU Counter data
+* b) Support Nest PMU units and their event files
+*/
+   for_each_node_with_property(dev, ibm,ima-chip) {
+   gcid = of_get_property(dev, ibm,chip-id, NULL);
+   chip_ima_reg = of_get_property(dev, reg, NULL);
+   chip_ima_size = of_get_property(dev, size, NULL);
+   if ((!gcid) || (!chip_ima_reg) || (!chip_ima_size)) {
+   pr_err(Nest_PMU: device %s missing property \n,
+   dev-full_name);
+   return -ENODEV;
+   }
+
+   /* Save per-chip reserve memory region */
+   idx = (uint32_t)be32_to_cpup(gcid);
+   p8_perchip_nest_info[idx].pbase = be64_to_cpup(chip_ima_reg);
+   p8_perchip_nest_info[idx].size = be64_to_cpup(chip_ima_size);
+   p8_perchip_nest_info[idx].vbase = (uint64_t)
+   phys_to_virt(p8_perchip_nest_info[idx].pbase);
+   }
+
+   return 0;
+}
+
+static int __init nest_pmu_init(void)
+{
+   int ret = -ENODEV;
+
+   /*
+* Lets do this only if we are hypervisor
+*/
+   if (!cur_cpu_spec-oprofile_cpu_type ||
+   !(strcmp(cur_cpu_spec-oprofile_cpu_type, ppc64/power8) == 0) ||
+   !cpu_has_feature(CPU_FTR_HVMODE))
+   return ret;
+
+   /*
+* Nest PMU information are grouped under nest-ima node
+* of the top-level Device-Tree directory. Detect Nest PMU
+* with ibm,ima-chip property.
+*/
+   if (!of_find_node_with_property(NULL, ibm,ima-chip))
+   return ret;
+
+