ARM: SOCFPGA: Enable PMU through the CTI
Subsystems (6)
RFC PATCH 1/1 ARM: SOCFPGA: Enable PMU through the CTI
From: Dinh Nguyen <[email protected]>
SOCFPGA has a PMU(Performance Measurement Unit) that has its IRQs routed through Coresight using the CTI(Cross-Trigger Interface).
This patch enables the PMU and initializes the CTI for usage by oprofile/perfmon.
A lot of the code/idea was taken from this:
https://patchwork.kernel.org/patch/1432541/
--- arch/arm/boot/dts/socfpga.dtsi | 18 +++++ arch/arm/include/asm/pmu.h | 3 + arch/arm/kernel/perf_event.c | 16 +++++ arch/arm/mach-socfpga/Makefile | 1 + arch/arm/mach-socfpga/socfpga.c | 21 +++++- arch/arm/mach-socfpga/socfpga_cti.c | 125 +++++++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga_cti.h | 16 +++++ 7 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-socfpga/socfpga_cti.c create mode 100644 arch/arm/mach-socfpga/socfpga_cti.h
arch/arm/boot/dts/socfpga.dtsi +18 -0
@@ -255,6 +255,24 @@ cache-level = <2>; }; + pmu { + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 176 4>, <0 177 4>; + ranges; + + cti0: cti0 at ff118000 { + compatible = "arm,coresight-cti"; + reg = <0xff118000 0x100>; + }; + + cti1: cti1 at ff119000 { + compatible = "arm,coresight-cti"; + reg = <0xff119000 0x100>; + }; + }; + /* Local timer */ timer at fffec600 { compatible = "arm,cortex-a9-twd-timer";
arch/arm/include/asm/pmu.h +3 -0
@@ -38,6 +38,9 @@ struct arm_pmu_platdata { irq_handler_t pmu_handler);int (*runtime_resume)(struct device *dev);int (*runtime_suspend)(struct device *dev); +int (*init)(struct platform_device *pdev); +int (*start)(struct platform_device *pdev); +int (*stop)(struct platform_device *pdev); };#ifdef CONFIG_HW_PERF_EVENTS
arch/arm/kernel/perf_event.c +16 -0
@@ -305,6 +305,11 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)static void armpmu_release_hardware (struct arm_pmu *armpmu) { +struct platform_device *plat_device = armpmu->plat_device; +struct arm_pmu_platdata *plat =dev_get_platdata (&plat_device->dev); + +if (plat->stop) + plat->stop (plat_device); armpmu->free_irq (armpmu);pm_runtime_put_sync (&armpmu->plat_device->dev); }
@@ -314,6 +319,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu) {int err;struct platform_device *pmu_device = armpmu->plat_device; +struct arm_pmu_platdata *plat =dev_get_platdata (&pmu_device->dev);if (!pmu_device)return -ENODEV ;
@@ -324,6 +330,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)armpmu_release_hardware (armpmu);return err; } +if (plat->start) + plat->start (pmu_device);return 0 ; }
@@ -506,10 +514,18 @@ static void armpmu_init(struct arm_pmu *armpmu)int armpmu_register (struct arm_pmu *armpmu,int type) { +struct platform_device *plat_device = armpmu->plat_device; +struct arm_pmu_platdata *plat =dev_get_platdata (&plat_device->dev); +armpmu_init (armpmu);pm_runtime_enable (&armpmu->plat_device->dev);pr_info ("enabled with %s PMU driver, %d counters available\n" , armpmu->name, armpmu->num_events); + +/* Platform specific initialization. ie. CTI enable */ +if (plat->init) + plat->init (plat_device); +return perf_pmu_register (&armpmu->pmu, armpmu->name, type); }
arch/arm/mach-socfpga/Makefile +1 -0
@@ -4,3 +4,4 @@ obj-y := socfpga.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o +obj-$(CONFIG_HW_PERF_EVENTS) += socfpga_cti.o
arch/arm/mach-socfpga/socfpga.c +20 -1
@@ -24,8 +24,10 @@#include <asm/hardware/cache-l2x0.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/pmu.h> #include "core.h" +#include "socfpga_cti.h" void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE ));void __iomem *sys_manager_base_addr;
@@ -33,6 +35,22 @@ void __iomem *rst_manager_base_addr;void __iomem *clk_mgr_base_addr;unsigned long cpu1start_addr; +#ifdef CONFIG_HW_PERF_EVENTS +static struct arm_pmu_platdata socfpga_pmu_platdata = { + .handle_irq = socfpga_pmu_handler, + .init = socfpga_init_cti, + .start = socfpga_start_cti, + .stop = socfpga_stop_cti, +}; +#endif + +static const struct of_dev_auxdata socfpga_auxdata_lookup[]__initconst = { +#ifdef CONFIG_HW_PERF_EVENTS +OF_DEV_AUXDATA ("arm,cortex-a9-pmu" ,0 ,"arm-pmu" , &socfpga_pmu_platdata), +#endif + {/* sentinel */ } +}; +static struct map_desc scu_io_desc__initdata = { .virtual =SOCFPGA_SCU_VIRT_BASE , .pfn =0 ,/* run-time */
@@ -106,7 +124,8 @@ static void socfpga_cyclone5_restart(char mode, const char *cmd)static void __init socfpga_cyclone5_init (void ) {l2x0_of_init (0 , ~0UL ); -of_platform_populate (NULL , of_default_bus_match_table,NULL ,NULL ); +of_platform_populate (NULL , of_default_bus_match_table, + socfpga_auxdata_lookup,NULL );of_clk_init (NULL );socfpga_init_clocks (); }
arch/arm/mach-socfpga/socfpga_cti.c new file +125 -0
125 lines not on this page · raw message
arch/arm/mach-socfpga/socfpga_cti.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef __SOCFPGA_CTI_H +#define __SOCFPGA_CTI_H + +#define CTI_MPU_IRQ_TRIG_IN 1 +#define CTI_MPU_IRQ_TRIG_OUT 6 + +#define PMU_CHANNEL_0 0 +#define PMU_CHANNEL_1 1 + +#ifdef CONFIG_HW_PERF_EVENTS +extern irqreturn_t socfpga_pmu_handler (int irq,void *dev,irq_handler_t handler); +extern int socfpga_init_cti (struct platform_device *pdev); +extern int socfpga_start_cti (struct platform_device *pdev); +extern int socfpga_stop_cti (struct platform_device *pdev); +#endif +#endif /* __SOCFPGA_CTI_H */
Signature · 1 line
1.7.9.5
RFC PATCH 1/1 ARM: SOCFPGA: Enable PMU through the CTI
Hello,
[adding Jon Hunter]
Quoted 19 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
SOCFPGA has a PMU(Performance Measurement Unit) that has its IRQs routed through Coresight using the CTI(Cross-Trigger Interface).
This patch enables the PMU and initializes the CTI for usage by oprofile/perfmon.
A lot of the code/idea was taken from this:
https://patchwork.kernel.org/patch/1432541/Signed-off-by Dinh Nguyen <[email protected]>CC Ming Lei <[email protected]>CC Will Deacon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Russell King <[email protected]>CC Arnd Bergmann <[email protected]>CC Olof Johansson <[email protected]>Cc Pavel Machek <[email protected]>
Quoted 11 lines
--- arch/arm/boot/dts/socfpga.dtsi | 18 +++++ arch/arm/include/asm/pmu.h | 3 + arch/arm/kernel/perf_event.c | 16 +++++ arch/arm/mach-socfpga/Makefile | 1 + arch/arm/mach-socfpga/socfpga.c | 21 +++++- arch/arm/mach-socfpga/socfpga_cti.c | 125 +++++++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga_cti.h | 16 +++++ 7 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-socfpga/socfpga_cti.c create mode 100644 arch/arm/mach-socfpga/socfpga_cti.h
Whilst it's great to see somebody else making use of CTI, I think this would benefit from Jon's separate CTI driver that he posted once:
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-December/137156.html
Jon -- would you be interested in reviving that work so the socfpga guys can make use of it?
arch/arm/include/asm/pmu.h struct arm_pmu_platdata { · line 43
Quoted 11 lines
arch/arm/include/asm/pmu.h +3
-0@@ -38,6 +38,9 @@ struct arm_pmu_platdata { irq_handler_t pmu_handler);int (*runtime_resume)(struct device *dev);int (*runtime_suspend)(struct device *dev); +int (*init)(struct platform_device *pdev); +int (*start)(struct platform_device *pdev); +int (*stop)(struct platform_device *pdev);
For omap4, we were planning to use the runtime PM callbacks for managing the CTI iirc.
Will
RFC PATCH 1/1 ARM: SOCFPGA: Enable PMU through the CTI
Quoted 36 lines · Will Deacon
Hello,
[adding Jon Hunter]
Quoted 19 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
SOCFPGA has a PMU(Performance Measurement Unit) that has its IRQs routed through Coresight using the CTI(Cross-Trigger Interface).
This patch enables the PMU and initializes the CTI for usage by oprofile/perfmon.
A lot of the code/idea was taken from this:
https://patchwork.kernel.org/patch/1432541/Signed-off-by Dinh Nguyen <[email protected]>CC Ming Lei <[email protected]>CC Will Deacon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Russell King <[email protected]>CC Arnd Bergmann <[email protected]>CC Olof Johansson <[email protected]>Cc Pavel Machek <[email protected]>Quoted 11 lines
--- arch/arm/boot/dts/socfpga.dtsi | 18 +++++ arch/arm/include/asm/pmu.h | 3 + arch/arm/kernel/perf_event.c | 16 +++++ arch/arm/mach-socfpga/Makefile | 1 + arch/arm/mach-socfpga/socfpga.c | 21 +++++- arch/arm/mach-socfpga/socfpga_cti.c | 125 +++++++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga_cti.h | 16 +++++ 7 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-socfpga/socfpga_cti.c create mode 100644 arch/arm/mach-socfpga/socfpga_cti.h
Quoted 7 lines
Whilst it's great to see somebody else making use of CTI, I think this would benefit from Jon's separate CTI driver that he posted once:
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-December/137156.html
Jon -- would you be interested in reviving that work so the socfpga guys can make use of it?
Sorry the delay I have been moving house!
Anyway, although I would be interesting in reviving and completing the work on cti, realistically, I am not sure when I would get to it now. I do have the latest code on my github account [1]. However, probably still needs more work before it is ready for the mainline in sorting out the DT bindings, etc. I was also thinking about making the cti look like a interrupt controller in DT as that is the way it is currently being used. However, I am not implemented that but should not be much work.
Cheers
Jon
RFC PATCH 1/1 ARM: SOCFPGA: Enable PMU through the CTI
In reply to dinguyen at altera.comHi!
Quoted 18 lines
SOCFPGA has a PMU(Performance Measurement Unit) that has its IRQs routed through Coresight using the CTI(Cross-Trigger Interface).
This patch enables the PMU and initializes the CTI for usage by oprofile/perfmon.
A lot of the code/idea was taken from this:
https://patchwork.kernel.org/patch/1432541/arch/arm/kernel/perf_event.c +3
-0@@ -305,6 +305,11 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)static void armpmu_release_hardware (struct arm_pmu *armpmu) { +struct platform_device *plat_device = armpmu->plat_device; +struct arm_pmu_platdata *plat =dev_get_platdata (&plat_device->dev); +
...
arch/arm/kernel/perf_event.c armpmu_reserve_hardware(struct arm_pmu *armpmu) · line 321
Quoted 4 lines
arch/arm/kernel/perf_event.c +0
-0@@ -314,6 +319,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu) {int err;struct platform_device *pmu_device = armpmu->plat_device;
pmu_device == plat_device, AFAICT. One of them should be renamed for consistency. Or maybe even make it "pdev" ... shorter and used in the code below...
arch/arm/kernel/perf_event.c armpmu_reserve_hardware(struct arm_pmu *armpmu) · line 325
Quoted 4 lines
arch/arm/kernel/perf_event.c +3
-0+int socfpga_init_cti (struct platform_device *pdev) +{ +/*configure CTI0 for pmu irq routing*/
Comments should normally be "/* word */"...
I'll take a more detailed look later.
Thanks,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html