Skip to contentSkip to conversation

arm: support pmu irq routed from CTI

PATCH New tom.leiming at gmail.com 3 participants 7 messages Mar 1, 2011 1 message not in the archive

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover arm: support pmu irq routed from CTI

Hi,

This patches support pmu irq routed from CTI, such as implemented on OMAP4:

- introduce some CTI helpers and registers' definition
- introduce platform_data to pmu driver, so perf irq handler can handle irq correctly if it is routed from CTI
- configure CTI on OMAP4 so that perf can work on OMAP4

The patches have been tested Ok on Pandaboard, and 'perf' does work after applying them.

 arch/arm/include/asm/cti.h    |  177 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/pmu.h    |   12 +++
 arch/arm/kernel/perf_event.c  |   51 ++++++++++--
 arch/arm/mach-omap2/devices.c |   54 ++++++++++++-
 4 files changed, 286 insertions(+), 8 deletions(-)

thanks,
Ming Lei

#1 lore raw

PATCH 1/3 arm: introduce cross trigger interface helpers

From: Ming Lei <[email protected]>

OMAP4 uses cross trigger interface(CTI) to route
performance monitor irq to GIC, so introduce cti
helpers to make access for cti easily.

---
 arch/arm/include/asm/cti.h |  177 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 177 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/cti.h
arch/arm/include/asm/cti.h new file +177 -0
new file mode 100644
index 0000000..c9addd3
@@ -0,0 +1,177 @@
+/*
+ *  arch/arm/include/asm/cti.h
+ */
+#ifndef __ASMARM_CTI_H
+#define __ASMARM_CTI_H
+
+#include	<asm/io.h>
+
+/*The registers' definition is from section 3.2 of
+ * 	Embedded Cross Trigger Revision: r0p0
+ **/
+#define		CTICONTROL		0x000
+#define		CTISTATUS		0x004
+#define		CTILOCK			0x008
+#define		CTIPROTECTION		0x00C
+#define		CTIINTACK		0x010
+#define		CTIAPPSET		0x014
+#define		CTIAPPCLEAR		0x018
+#define		CTIAPPPULSE		0x01c
+#define		CTIINEN			0x020
+#define		CTIOUTEN		0x0A0
+#define		CTITRIGINSTATUS		0x130
+#define		CTITRIGOUTSTATUS	0x134
+#define		CTICHINSTATUS		0x138
+#define		CTICHOUTSTATUS		0x13c
+#define		CTIPERIPHID0		0xFE0
+#define		CTIPERIPHID1		0xFE4
+#define		CTIPERIPHID2		0xFE8
+#define		CTIPERIPHID3		0xFEC
+#define		CTIPCELLID0		0xFF0
+#define		CTIPCELLID1		0xFF4
+#define		CTIPCELLID2		0xFF8
+#define		CTIPCELLID3		0xFFC
+
+/*The two below are from section 3.6.4 of
+ * 	CoreSight v1.0 Architecture Specification
+ **/
+#define		LOCKACCESS		0xFB0
+#define		LOCKSTATUS		0xFB4
+
+/**
+ * struct cti - cross trigger interface struct
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out_for_irq: triger out number which will cause
+ * 	the @irq happen
+ *
+ * cti struct used to operate cti registers.
+ */
+struct cti {
+	void *base;
+	int irq;
+	int trig_out_for_irq;
+};
+
+/**
+ * cti_init - initialize the cti instance
+ * @cti: cti instance
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out: triger out number which will cause
+ * 	the @irq happen
+ *
+ * called by machine code to pass the board dependent
+ * @base, @irq and @trig_out to cti.
+ */
+static inline void cti_init(struct cti *cti,
+	void *base, int irq, int trig_out)
+{
+	cti->base = base;
+	cti->irq  = irq;
+	cti->trig_out_for_irq = trig_out;
+}
+
+/**
+ * cti_map_trigger - use the @chan to map @trig_in to @trig_out
+ * @cti: cti instance
+ * @trig_in: trigger in number
+ * @trig_out: trigger out number
+ * @channel: channel number
+ *
+ * This function maps one trigger in of @trig_in to one trigger
+ * out of @trig_out using the channel @chan.
+ */
+static inline void cti_map_trigger(struct cti *cti,
+	int trig_in, int trig_out, int chan)
+{
+	void *base = cti->base;
+	unsigned long val;
+
+	val = __raw_readl(base + CTIINEN + trig_in * 4);
+	val |= 1 << chan;
+	__raw_writel(val, base + CTIINEN + trig_in * 4);
+
+	val = __raw_readl(base + CTIOUTEN + trig_out * 4);
+	val |= 1 << chan;
+	__raw_writel(val, base + CTIOUTEN + trig_out * 4);
+}
+
+/**
+ * cti_enable - enable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_enable(struct cti *cti)
+{
+	__raw_writel(0x1, cti->base);
+}
+
+/**
+ * cti_disable - disable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_disable(struct cti *cti)
+{
+	__raw_writel(0, cti->base);
+}
+
+/**
+ * cti_irq_ack - clear the cti irq
+ * @cti: cti instance
+ *
+ * clear the cti irq
+ */
+static inline void cti_irq_ack(struct cti *cti)
+{
+	void *base = cti->base;
+	unsigned long val;
+
+	val = __raw_readl(base + CTIINTACK);
+	val |= 1 << cti->trig_out_for_irq;
+	__raw_writel(val, base + CTIINTACK);
+}
+
+/**
+ * cti_unlock - unlock cti module
+ * @cti: cti instance
+ *
+ * unlock the cti module, or else any writes to the cti
+ * module is not allowed.
+ */
+static inline void cti_unlock(struct cti *cti)
+{
+	void *base = cti->base;
+	unsigned long val;
+
+	val = __raw_readl(base + LOCKSTATUS);
+
+	if (val & 1) {
+		val = 0xC5ACCE55;
+		__raw_writel(val, base + LOCKACCESS);
+	}
+}
+
+/**
+ * cti_unlock - lock cti module
+ * @cti: cti instance
+ *
+ * lock the cti module, so any writes to the cti
+ * module will be not allowed.
+ */
+static inline void cti_lock(struct cti *cti)
+{
+	void *base = cti->base;
+	unsigned long val;
+
+	val = __raw_readl(base + LOCKSTATUS);
+
+	if (!(val & 1)) {
+		val = ~0xC5ACCE55;
+		__raw_writel(val, base + LOCKACCESS);
+	}
+}
+#endif
Signature · 1 line
1.7.3
#2 lore raw

PATCH 2/3 arm: pmu: support pmu irq routed from CTI

In reply to tom.leiming at gmail.com

From: Ming Lei <[email protected]>

This patch introduces pmu_platform_data struct to support pmu irq routed from CTI, such as implemented on OMAP4.

Generally speaking, clearing cti irq should be done in irq handler, also enabling cti module after calling request_irq and disabling cti module before calling free_irq.

---
 arch/arm/include/asm/pmu.h   |   12 ++++++++++
 arch/arm/kernel/perf_event.c |   51 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 7 deletions(-)
arch/arm/include/asm/pmu.h +12 -0
index 8ccea012..afb879e 100644
@@ -12,11 +12,23 @@
 #ifndef __ARM_PMU_H__
 #define __ARM_PMU_H__
 
+#include <asm/cti.h>
+
 enum arm_pmu_type {
 	ARM_PMU_DEVICE_CPU	= 0,
 	ARM_NUM_PMU_DEVICES,
 };
 
+#define MAX_CTI_NUM  4
+/*If the irq of pmu is routed from CTI, the pmu_platfrom_data
+ * instance must be passed to pmu driver via platform_data of
+ * platform_devic.dev*/
+struct pmu_platform_data {
+	int use_cti_irq;
+	int cti_cnt;
+	struct cti cti[MAX_CTI_NUM];
+};
+
 #ifdef CONFIG_CPU_HAS_PMU
 
 /**
arch/arm/kernel/perf_event.c +44 -7

91 lines not on this page · raw message

Signature · 1 line
1.7.3
#3 lore raw

PATCH 2/3 arm: pmu: support pmu irq routed from CTI

Hello,

Quoted 13 lines

Subject: [PATCH 2/3] arm: pmu: support pmu irq routed from CTI

From: Ming Lei <[email protected]>

This patch introduces pmu_platform_data struct to support pmu irq routed from CTI, such as implemented on OMAP4.

Generally speaking, clearing cti irq should be done in irq handler, also enabling cti module after calling request_irq and disabling cti module before calling free_irq.

Quoted 5 lines
---
 arch/arm/include/asm/pmu.h   |   12 ++++++++++
 arch/arm/kernel/perf_event.c |   51 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 7 deletions(-)

This will conflict with the the ux500 PMU workaround:

http://lists.infradead.org/pipermail/linux-arm-kernel/2011-February/041145.html

Will

A message that is not in the archive (sent off-list or not yet received): -294597288559385401@unknownmsgid

author
#5 lore raw

PATCH 2/3 arm: pmu: support pmu irq routed from CTI

Hi,

2011/3/1 Will Deacon <[email protected]>:

Quoted 21 lines

Hello,

Quoted 13 lines

Subject: [PATCH 2/3] arm: pmu: support pmu irq routed from CTI

From: Ming Lei <[email protected]>

This patch introduces pmu_platform_data struct to support pmu irq routed from CTI, such as implemented on OMAP4.

Generally speaking, clearing cti irq should be done in irq handler, also enabling cti module after calling request_irq and disabling cti module before calling free_irq.

Quoted 5 lines

---
?arch/arm/include/asm/pmu.h ? | ? 12 ++++++++++ ?arch/arm/kernel/perf_event.c | ? 51 ++++++++++++++++++++++++++++++++++++----- ?2 files changed, 56 insertions(+), 7 deletions(-)

Quoted 3 lines

This will conflict with the the ux500 PMU workaround:

http://lists.infradead.org/pipermail/linux-arm-kernel/2011-February/041145.html

Thanks for your pointing out it.

I will send out -v1 of these patches against the latest -next tree.

thanks,

Signature · 1 line
Lei Ming
#6 lore raw

PATCH 3/3 arm: omap4: support pmu

In reply to tom.leiming at gmail.com

From: Ming Lei <[email protected]>

This patch supports pmu irq routed from CTI, so make pmu/perf working on OMAP4.

The idea is from Woodruff Richard in the disscussion "Oprofile on Pandaboard / Omap4" of pandaboard at googlegroups.com.

Cc Woodruff Richard <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc linux-omap at vger.kernel.org
---
 arch/arm/mach-omap2/devices.c |   54 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/devices.c +53 -1
index 71f099b..54e9705 100644
@@ -34,6 +34,7 @@
 
 #include "mux.h"
 #include "control.h"
+#include "dbg44xx.h"
 
 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
@@ -347,19 +348,70 @@ static struct resource omap3_pmu_resource = {
 	.flags	= IORESOURCE_IRQ,
 };
 
+static struct resource omap4_pmu_resource[] = {
+	{
+	.start	= OMAP44XX_IRQ_CTI0,
+	.end	= OMAP44XX_IRQ_CTI0,
+	.flags	= IORESOURCE_IRQ,
+	},
+	{
+	.start	= OMAP44XX_IRQ_CTI1,
+	.end	= OMAP44XX_IRQ_CTI1,
+	.flags	= IORESOURCE_IRQ,
+	}
+};
+
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
 	.id		= ARM_PMU_DEVICE_CPU,
 	.num_resources	= 1,
 };
 
+struct pmu_platform_data omap4_pmu_data;
+
+static void omap4_configure_pmu_irq(void)
+{
+	void *base0;
+	void *base1;
+
+	base0 = ioremap(OMAP4430_CTI0_BASE, 4096);
+	base1 = ioremap(OMAP4430_CTI1_BASE, 4096);
+	if (!base0 && !base1) {
+		pr_err("ioremap for omap4 CTI failed\n");
+		return;
+	}
+
+	/*configure CTI0 for pmu irq routing*/
+	cti_init(&omap4_pmu_data.cti[0], base0,
+			OMAP44XX_IRQ_CTI0, 6);
+	cti_unlock(&omap4_pmu_data.cti[0]);
+	cti_map_trigger(&omap4_pmu_data.cti[0],
+			1, 6, 2);
+
+	/*configure CTI1 for pmu irq routing*/
+	cti_init(&omap4_pmu_data.cti[1], base1,
+			OMAP44XX_IRQ_CTI1, 6);
+	cti_unlock(&omap4_pmu_data.cti[1]);
+	cti_map_trigger(&omap4_pmu_data.cti[1],
+			1, 6, 3);
+
+	omap4_pmu_data.cti_cnt = 2;
+	omap4_pmu_data.use_cti_irq = 1;
+}
+
 static void omap_init_pmu(void)
 {
 	if (cpu_is_omap24xx())
 		omap_pmu_device.resource = &omap2_pmu_resource;
 	else if (cpu_is_omap34xx())
 		omap_pmu_device.resource = &omap3_pmu_resource;
-	else
+	else if (cpu_is_omap44xx()) {
+		omap_pmu_device.resource = omap4_pmu_resource;
+		omap_pmu_device.num_resources = 2;
+		omap_pmu_device.dev.platform_data = &omap4_pmu_data;
+
+		omap4_configure_pmu_irq();
+	} else
 		return;
 
 	platform_device_register(&omap_pmu_device);
Signature · 1 line
1.7.3
#7 lore raw

PATCH 3/3 arm: omap4: support pmu

Quoted 14 lines

-----Original Message-----
From: linux-omap-owner at vger.kernel.org [mailto:linux-omap- owner at vger.kernel.org] On Behalf Of tom.leiming at gmail.com
Sent: Tuesday, March 01, 2011 6:47 PM
To: linux at arm.linux.org.uk
Cc: linux-arm-kernel at lists.infradead.org; Ming Lei; Woodruff Richard; Tony Lindgren; linux-omap at vger.kernel.org
Subject: [PATCH 3/3] arm: omap4: support pmu

From: Ming Lei <[email protected]>

This patch supports pmu irq routed from CTI, so
make pmu/perf working on OMAP4.

Quoted 8 lines

The idea is from Woodruff Richard in the disscussion "Oprofile on Pandaboard / Omap4" of pandaboard at googlegroups.com.

Cc Woodruff Richard <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc linux-omap at vger.kernel.org

---

Thanks Mein Lei for this.

Quoted 98 lines
 arch/arm/mach-omap2/devices.c |   54
++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)
arch/arm/mach- renamed from arch/arm/mach-omap2/devices.c +0 -0

omap2/devices.c
index 71f099b..54e9705 100644

arch/arm/mach-omap2/devices.c +53 -2
@@ -34,6 +34,7 @@
 
 #include "mux.h"
 #include "control.h"
+#include "dbg44xx.h"
 
 #if defined(CONFIG_VIDEO_OMAP2) ||
 defined(CONFIG_VIDEO_OMAP2_MODULE)
@@ -347,19 +348,70 @@ static struct resource omap3_pmu_resource = {
 	.flags	= IORESOURCE_IRQ,
 };
 
+static struct resource omap4_pmu_resource[] = {
+	{
+	.start	= OMAP44XX_IRQ_CTI0,
+	.end	= OMAP44XX_IRQ_CTI0,
+	.flags	= IORESOURCE_IRQ,
+	},
+	{
+	.start	= OMAP44XX_IRQ_CTI1,
+	.end	= OMAP44XX_IRQ_CTI1,
+	.flags	= IORESOURCE_IRQ,
+	}
+};
+
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
 	.id		= ARM_PMU_DEVICE_CPU,
 	.num_resources	= 1,
 };
 
+struct pmu_platform_data omap4_pmu_data;
+
+static void omap4_configure_pmu_irq(void)
+{
+	void *base0;
+	void *base1;
+
+	base0 = ioremap(OMAP4430_CTI0_BASE, 4096);
+	base1 = ioremap(OMAP4430_CTI1_BASE, 4096);
+	if (!base0 && !base1) {
+		pr_err("ioremap for omap4 CTI failed\n");
+		return;
+	}
+
+	/*configure CTI0 for pmu irq routing*/
+	cti_init(&omap4_pmu_data.cti[0], base0,
+			OMAP44XX_IRQ_CTI0, 6);
+	cti_unlock(&omap4_pmu_data.cti[0]);
+	cti_map_trigger(&omap4_pmu_data.cti[0],
+			1, 6, 2);
+
+	/*configure CTI1 for pmu irq routing*/
+	cti_init(&omap4_pmu_data.cti[1], base1,
+			OMAP44XX_IRQ_CTI1, 6);
+	cti_unlock(&omap4_pmu_data.cti[1]);
+	cti_map_trigger(&omap4_pmu_data.cti[1],
+			1, 6, 3);
+
+	omap4_pmu_data.cti_cnt = 2;
+	omap4_pmu_data.use_cti_irq = 1;
+}
+
 static void omap_init_pmu(void)
 {
 	if (cpu_is_omap24xx())
 		omap_pmu_device.resource = &omap2_pmu_resource;
 	else if (cpu_is_omap34xx())
 		omap_pmu_device.resource = &omap3_pmu_resource;
-	else
+	else if (cpu_is_omap44xx()) {
+		omap_pmu_device.resource = omap4_pmu_resource;
+		omap_pmu_device.num_resources = 2;
+		omap_pmu_device.dev.platform_data = &omap4_pmu_data;
+
+		omap4_configure_pmu_irq();
+	} else
 		return;
 
 	platform_device_register(&omap_pmu_device);
--

1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux- omap" in
the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html