All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-05-18 11:24 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Merged mtk_cpux_{enable,disable}_irq() as one mtk_cpux_set_irq() function
   as suggested by Matthias

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   4 +
 drivers/clocksource/timer-mediatek.c          | 114 ++++++++++++++++++
 2 files changed, 118 insertions(+)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-05-18 11:24 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Merged mtk_cpux_{enable,disable}_irq() as one mtk_cpux_set_irq() function
   as suggested by Matthias

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   4 +
 drivers/clocksource/timer-mediatek.c          | 114 ++++++++++++++++++
 2 files changed, 118 insertions(+)

-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-05-18 11:24 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Merged mtk_cpux_{enable,disable}_irq() as one mtk_cpux_set_irq() function
   as suggested by Matthias

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   4 +
 drivers/clocksource/timer-mediatek.c          | 114 ++++++++++++++++++
 2 files changed, 118 insertions(+)

-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
  2022-05-18 11:24 ` AngeloGioacchino Del Regno
  (?)
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
System Timer on MediaTek platforms and add the MT6795 compatible for it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index 6f1f9dba6e88..49706cbef45d 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -2,6 +2,7 @@ MediaTek Timers
 ---------------
 
 MediaTek SoCs have two different timers on different platforms,
+- CPUX (ARM/ARM64 System Timer)
 - GPT (General Purpose Timer)
 - SYST (System Timer)
 
@@ -29,6 +30,9 @@ Required properties:
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
 	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
 
+	For those SoCs that use CPUX
+	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
+
 - reg: Should contain location and length for timer register.
 - clocks: Should contain system clock.
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
System Timer on MediaTek platforms and add the MT6795 compatible for it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index 6f1f9dba6e88..49706cbef45d 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -2,6 +2,7 @@ MediaTek Timers
 ---------------
 
 MediaTek SoCs have two different timers on different platforms,
+- CPUX (ARM/ARM64 System Timer)
 - GPT (General Purpose Timer)
 - SYST (System Timer)
 
@@ -29,6 +30,9 @@ Required properties:
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
 	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
 
+	For those SoCs that use CPUX
+	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
+
 - reg: Should contain location and length for timer register.
 - clocks: Should contain system clock.
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
System Timer on MediaTek platforms and add the MT6795 compatible for it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index 6f1f9dba6e88..49706cbef45d 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -2,6 +2,7 @@ MediaTek Timers
 ---------------
 
 MediaTek SoCs have two different timers on different platforms,
+- CPUX (ARM/ARM64 System Timer)
 - GPT (General Purpose Timer)
 - SYST (System Timer)
 
@@ -29,6 +30,9 @@ Required properties:
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
 	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
 
+	For those SoCs that use CPUX
+	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
+
 - reg: Should contain location and length for timer register.
 - clocks: Should contain system clock.
 
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
  2022-05-18 11:24 ` AngeloGioacchino Del Regno
  (?)
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Some MediaTek platforms with a buggy TrustZone ATF firmware will not
initialize the AArch64 System Timer correctly: in these cases, the
System Timer address is correctly programmed, as well as the CNTFRQ_EL0
register (reading 13MHz, as it should be), but the assigned hardware
timers are never started before (or after) booting Linux.

In this condition, any call to function get_cycles() will be returning
zero, as CNTVCT_EL0 will always read zero.

One common critical symptom of that is trying to use the udelay()
function (calling __delay()), which executes the following loop:

            start = get_cycles();
            while ((get_cycles() - start) < cycles)
                    cpu_relax();

which, when CNTVCT_EL0 always reads zero, translates to:

            while((0 - 0) < 0)  ==> while(0 < 0)

... generating an infinite loop, even though zero is never less
than zero, but always equal to it (this has to be researched,
but it's out of the scope of this commit).

To fix this issue on the affected MediaTek platforms, the solution
is to simply start the timers that are designed to be System Timer(s).
These timers, downstream, are called "CPUXGPT" and there is one
timer per CPU core; luckily, it is not necessary to set a start bit
on each CPUX General Purpose Timer, but it's conveniently enough to:
 - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
 - Set the ENABLE bit on a global register (starts all CPUX timers).

The only small hurdle with this setup is that it's all done through
the MCUSYS wrapper, where it is needed, for each read or write, to
select a register address (by writing it to an index register) and
then to perform any R/W on a "CON" register.

For example, writing "0x1" to the CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Write 0x1 to mcusys CON register

Reading from CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Read mcusys CON register.

Finally, starting this timer makes platforms affected by this issue
to work correctly.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..d5b29fd03ca2 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -22,6 +22,19 @@
 
 #define TIMER_SYNC_TICKS        (3)
 
+/* cpux mcusys wrapper */
+#define CPUX_CON_REG		0x0
+#define CPUX_IDX_REG		0x4
+
+/* cpux */
+#define CPUX_IDX_GLOBAL_CTRL	0x0
+ #define CPUX_ENABLE		BIT(0)
+ #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
+ #define CPUX_CLK_DIV1		BIT(8)
+ #define CPUX_CLK_DIV2		BIT(9)
+ #define CPUX_CLK_DIV4		BIT(10)
+#define CPUX_IDX_GLOBAL_IRQ	0x30
+
 /* gpt */
 #define GPT_IRQ_EN_REG          0x00
 #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
@@ -72,6 +85,52 @@
 
 static void __iomem *gpt_sched_reg __read_mostly;
 
+static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	return readl(timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	writel(val, timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
+{
+	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
+	u32 val;
+
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
+
+	if (enable)
+		val |= *irq_mask;
+	else
+		val &= ~(*irq_mask);
+
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
+}
+
+static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
+{
+	/* Clear any irq */
+	mtk_cpux_set_irq(to_timer_of(clkevt), false);
+
+	/*
+	 * Disabling CPUXGPT timer will crash the platform, especially
+	 * if Trusted Firmware is using it (usually, for sleep states),
+	 * so we only mask the IRQ and call it a day.
+	 */
+	return 0;
+}
+
+static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
+{
+	mtk_cpux_set_irq(to_timer_of(clkevt), true);
+	return 0;
+}
+
 static void mtk_syst_ack_irq(struct timer_of *to)
 {
 	/* Clear and disable interrupt */
@@ -281,6 +340,60 @@ static struct timer_of to = {
 	},
 };
 
+static int __init mtk_cpux_init(struct device_node *node)
+{
+	static struct timer_of to_cpux;
+	u32 freq, val;
+	int ret;
+
+	/*
+	 * There are per-cpu interrupts for the CPUX General Purpose Timer
+	 * but since this timer feeds the AArch64 System Timer we can rely
+	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
+	 */
+	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
+	to_cpux.clkevt.name = "mtk-cpuxgpt";
+	to_cpux.clkevt.rating = 10;
+	to_cpux.clkevt.cpumask = cpu_possible_mask;
+	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
+	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
+
+	/* If this fails, bad things are about to happen... */
+	ret = timer_of_init(node, &to_cpux);
+	if (ret) {
+		WARN(1, "Cannot start CPUX timers.\n");
+		return ret;
+	}
+
+	/*
+	 * Check if we're given a clock with the right frequency for this
+	 * timer, otherwise warn but keep going with the setup anyway, as
+	 * that makes it possible to still boot the kernel, even though
+	 * it may not work correctly (random lockups, etc).
+	 * The reason behind this is that having an early UART may not be
+	 * possible for everyone and this gives a chance to retrieve kmsg
+	 * for eventual debugging even on consumer devices.
+	 */
+	freq = timer_of_rate(&to_cpux);
+	if (freq > 13000000)
+		WARN(1, "Requested unsupported timer frequency %u\n", freq);
+
+	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	val &= ~CPUX_CLK_DIV_MASK;
+	val |= CPUX_CLK_DIV2;
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	/* Enable all CPUXGPT timers */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
+					TIMER_SYNC_TICKS, 0xffffffff);
+
+	return 0;
+}
+
 static int __init mtk_syst_init(struct device_node *node)
 {
 	int ret;
@@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
 TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Some MediaTek platforms with a buggy TrustZone ATF firmware will not
initialize the AArch64 System Timer correctly: in these cases, the
System Timer address is correctly programmed, as well as the CNTFRQ_EL0
register (reading 13MHz, as it should be), but the assigned hardware
timers are never started before (or after) booting Linux.

In this condition, any call to function get_cycles() will be returning
zero, as CNTVCT_EL0 will always read zero.

One common critical symptom of that is trying to use the udelay()
function (calling __delay()), which executes the following loop:

            start = get_cycles();
            while ((get_cycles() - start) < cycles)
                    cpu_relax();

which, when CNTVCT_EL0 always reads zero, translates to:

            while((0 - 0) < 0)  ==> while(0 < 0)

... generating an infinite loop, even though zero is never less
than zero, but always equal to it (this has to be researched,
but it's out of the scope of this commit).

To fix this issue on the affected MediaTek platforms, the solution
is to simply start the timers that are designed to be System Timer(s).
These timers, downstream, are called "CPUXGPT" and there is one
timer per CPU core; luckily, it is not necessary to set a start bit
on each CPUX General Purpose Timer, but it's conveniently enough to:
 - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
 - Set the ENABLE bit on a global register (starts all CPUX timers).

The only small hurdle with this setup is that it's all done through
the MCUSYS wrapper, where it is needed, for each read or write, to
select a register address (by writing it to an index register) and
then to perform any R/W on a "CON" register.

For example, writing "0x1" to the CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Write 0x1 to mcusys CON register

Reading from CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Read mcusys CON register.

Finally, starting this timer makes platforms affected by this issue
to work correctly.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..d5b29fd03ca2 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -22,6 +22,19 @@
 
 #define TIMER_SYNC_TICKS        (3)
 
+/* cpux mcusys wrapper */
+#define CPUX_CON_REG		0x0
+#define CPUX_IDX_REG		0x4
+
+/* cpux */
+#define CPUX_IDX_GLOBAL_CTRL	0x0
+ #define CPUX_ENABLE		BIT(0)
+ #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
+ #define CPUX_CLK_DIV1		BIT(8)
+ #define CPUX_CLK_DIV2		BIT(9)
+ #define CPUX_CLK_DIV4		BIT(10)
+#define CPUX_IDX_GLOBAL_IRQ	0x30
+
 /* gpt */
 #define GPT_IRQ_EN_REG          0x00
 #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
@@ -72,6 +85,52 @@
 
 static void __iomem *gpt_sched_reg __read_mostly;
 
+static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	return readl(timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	writel(val, timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
+{
+	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
+	u32 val;
+
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
+
+	if (enable)
+		val |= *irq_mask;
+	else
+		val &= ~(*irq_mask);
+
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
+}
+
+static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
+{
+	/* Clear any irq */
+	mtk_cpux_set_irq(to_timer_of(clkevt), false);
+
+	/*
+	 * Disabling CPUXGPT timer will crash the platform, especially
+	 * if Trusted Firmware is using it (usually, for sleep states),
+	 * so we only mask the IRQ and call it a day.
+	 */
+	return 0;
+}
+
+static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
+{
+	mtk_cpux_set_irq(to_timer_of(clkevt), true);
+	return 0;
+}
+
 static void mtk_syst_ack_irq(struct timer_of *to)
 {
 	/* Clear and disable interrupt */
@@ -281,6 +340,60 @@ static struct timer_of to = {
 	},
 };
 
+static int __init mtk_cpux_init(struct device_node *node)
+{
+	static struct timer_of to_cpux;
+	u32 freq, val;
+	int ret;
+
+	/*
+	 * There are per-cpu interrupts for the CPUX General Purpose Timer
+	 * but since this timer feeds the AArch64 System Timer we can rely
+	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
+	 */
+	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
+	to_cpux.clkevt.name = "mtk-cpuxgpt";
+	to_cpux.clkevt.rating = 10;
+	to_cpux.clkevt.cpumask = cpu_possible_mask;
+	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
+	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
+
+	/* If this fails, bad things are about to happen... */
+	ret = timer_of_init(node, &to_cpux);
+	if (ret) {
+		WARN(1, "Cannot start CPUX timers.\n");
+		return ret;
+	}
+
+	/*
+	 * Check if we're given a clock with the right frequency for this
+	 * timer, otherwise warn but keep going with the setup anyway, as
+	 * that makes it possible to still boot the kernel, even though
+	 * it may not work correctly (random lockups, etc).
+	 * The reason behind this is that having an early UART may not be
+	 * possible for everyone and this gives a chance to retrieve kmsg
+	 * for eventual debugging even on consumer devices.
+	 */
+	freq = timer_of_rate(&to_cpux);
+	if (freq > 13000000)
+		WARN(1, "Requested unsupported timer frequency %u\n", freq);
+
+	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	val &= ~CPUX_CLK_DIV_MASK;
+	val |= CPUX_CLK_DIV2;
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	/* Enable all CPUXGPT timers */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
+					TIMER_SYNC_TICKS, 0xffffffff);
+
+	return 0;
+}
+
 static int __init mtk_syst_init(struct device_node *node)
 {
 	int ret;
@@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
 TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);
-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
@ 2022-05-18 11:24   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 11:24 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

Some MediaTek platforms with a buggy TrustZone ATF firmware will not
initialize the AArch64 System Timer correctly: in these cases, the
System Timer address is correctly programmed, as well as the CNTFRQ_EL0
register (reading 13MHz, as it should be), but the assigned hardware
timers are never started before (or after) booting Linux.

In this condition, any call to function get_cycles() will be returning
zero, as CNTVCT_EL0 will always read zero.

One common critical symptom of that is trying to use the udelay()
function (calling __delay()), which executes the following loop:

            start = get_cycles();
            while ((get_cycles() - start) < cycles)
                    cpu_relax();

which, when CNTVCT_EL0 always reads zero, translates to:

            while((0 - 0) < 0)  ==> while(0 < 0)

... generating an infinite loop, even though zero is never less
than zero, but always equal to it (this has to be researched,
but it's out of the scope of this commit).

To fix this issue on the affected MediaTek platforms, the solution
is to simply start the timers that are designed to be System Timer(s).
These timers, downstream, are called "CPUXGPT" and there is one
timer per CPU core; luckily, it is not necessary to set a start bit
on each CPUX General Purpose Timer, but it's conveniently enough to:
 - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
 - Set the ENABLE bit on a global register (starts all CPUX timers).

The only small hurdle with this setup is that it's all done through
the MCUSYS wrapper, where it is needed, for each read or write, to
select a register address (by writing it to an index register) and
then to perform any R/W on a "CON" register.

For example, writing "0x1" to the CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Write 0x1 to mcusys CON register

Reading from CPUXGPT register offset 0x4:
- Write 0x4 to mcusys INDEX register
- Read mcusys CON register.

Finally, starting this timer makes platforms affected by this issue
to work correctly.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..d5b29fd03ca2 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -22,6 +22,19 @@
 
 #define TIMER_SYNC_TICKS        (3)
 
+/* cpux mcusys wrapper */
+#define CPUX_CON_REG		0x0
+#define CPUX_IDX_REG		0x4
+
+/* cpux */
+#define CPUX_IDX_GLOBAL_CTRL	0x0
+ #define CPUX_ENABLE		BIT(0)
+ #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
+ #define CPUX_CLK_DIV1		BIT(8)
+ #define CPUX_CLK_DIV2		BIT(9)
+ #define CPUX_CLK_DIV4		BIT(10)
+#define CPUX_IDX_GLOBAL_IRQ	0x30
+
 /* gpt */
 #define GPT_IRQ_EN_REG          0x00
 #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
@@ -72,6 +85,52 @@
 
 static void __iomem *gpt_sched_reg __read_mostly;
 
+static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	return readl(timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
+{
+	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
+	writel(val, timer_of_base(to) + CPUX_CON_REG);
+}
+
+static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
+{
+	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
+	u32 val;
+
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
+
+	if (enable)
+		val |= *irq_mask;
+	else
+		val &= ~(*irq_mask);
+
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
+}
+
+static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
+{
+	/* Clear any irq */
+	mtk_cpux_set_irq(to_timer_of(clkevt), false);
+
+	/*
+	 * Disabling CPUXGPT timer will crash the platform, especially
+	 * if Trusted Firmware is using it (usually, for sleep states),
+	 * so we only mask the IRQ and call it a day.
+	 */
+	return 0;
+}
+
+static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
+{
+	mtk_cpux_set_irq(to_timer_of(clkevt), true);
+	return 0;
+}
+
 static void mtk_syst_ack_irq(struct timer_of *to)
 {
 	/* Clear and disable interrupt */
@@ -281,6 +340,60 @@ static struct timer_of to = {
 	},
 };
 
+static int __init mtk_cpux_init(struct device_node *node)
+{
+	static struct timer_of to_cpux;
+	u32 freq, val;
+	int ret;
+
+	/*
+	 * There are per-cpu interrupts for the CPUX General Purpose Timer
+	 * but since this timer feeds the AArch64 System Timer we can rely
+	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
+	 */
+	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
+	to_cpux.clkevt.name = "mtk-cpuxgpt";
+	to_cpux.clkevt.rating = 10;
+	to_cpux.clkevt.cpumask = cpu_possible_mask;
+	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
+	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
+
+	/* If this fails, bad things are about to happen... */
+	ret = timer_of_init(node, &to_cpux);
+	if (ret) {
+		WARN(1, "Cannot start CPUX timers.\n");
+		return ret;
+	}
+
+	/*
+	 * Check if we're given a clock with the right frequency for this
+	 * timer, otherwise warn but keep going with the setup anyway, as
+	 * that makes it possible to still boot the kernel, even though
+	 * it may not work correctly (random lockups, etc).
+	 * The reason behind this is that having an early UART may not be
+	 * possible for everyone and this gives a chance to retrieve kmsg
+	 * for eventual debugging even on consumer devices.
+	 */
+	freq = timer_of_rate(&to_cpux);
+	if (freq > 13000000)
+		WARN(1, "Requested unsupported timer frequency %u\n", freq);
+
+	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	val &= ~CPUX_CLK_DIV_MASK;
+	val |= CPUX_CLK_DIV2;
+	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	/* Enable all CPUXGPT timers */
+	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
+
+	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
+					TIMER_SYNC_TICKS, 0xffffffff);
+
+	return 0;
+}
+
 static int __init mtk_syst_init(struct device_node *node)
 {
 	int ret;
@@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
 TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
  2022-05-18 11:24   ` AngeloGioacchino Del Regno
  (?)
@ 2022-06-01 20:03     ` Rob Herring
  -1 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2022-06-01 20:03 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: matthias.bgg, linux-kernel, konrad.dybcio, phone-devel,
	devicetree, martin.botka, tglx, paul.bouchara, robh+dt,
	linux-arm-kernel, krzysztof.kozlowski+dt,
	~postmarketos/upstreaming, daniel.lezcano, linux-mediatek,
	marijn.suijten

On Wed, 18 May 2022 13:24:34 +0200, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-01 20:03     ` Rob Herring
  0 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2022-06-01 20:03 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: matthias.bgg, linux-kernel, konrad.dybcio, phone-devel,
	devicetree, martin.botka, tglx, paul.bouchara, robh+dt,
	linux-arm-kernel, krzysztof.kozlowski+dt,
	~postmarketos/upstreaming, daniel.lezcano, linux-mediatek,
	marijn.suijten

On Wed, 18 May 2022 13:24:34 +0200, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-01 20:03     ` Rob Herring
  0 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2022-06-01 20:03 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: matthias.bgg, linux-kernel, konrad.dybcio, phone-devel,
	devicetree, martin.botka, tglx, paul.bouchara, robh+dt,
	linux-arm-kernel, krzysztof.kozlowski+dt,
	~postmarketos/upstreaming, daniel.lezcano, linux-mediatek,
	marijn.suijten

On Wed, 18 May 2022 13:24:34 +0200, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
  2022-05-18 11:24   ` AngeloGioacchino Del Regno
  (?)
@ 2022-06-07 16:11     ` Matthias Brugger
  -1 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> index 6f1f9dba6e88..49706cbef45d 100644
> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> @@ -2,6 +2,7 @@ MediaTek Timers
>   ---------------
>   
>   MediaTek SoCs have two different timers on different platforms,

Nit: There are now three different timers so maybe:
"MediaTek SoCs have different timers on different platforms,"

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> +- CPUX (ARM/ARM64 System Timer)
>   - GPT (General Purpose Timer)
>   - SYST (System Timer)
>   
> @@ -29,6 +30,9 @@ Required properties:
>   	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>   	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>   
> +	For those SoCs that use CPUX
> +	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
> +
>   - reg: Should contain location and length for timer register.
>   - clocks: Should contain system clock.
>   

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-07 16:11     ` Matthias Brugger
  0 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> index 6f1f9dba6e88..49706cbef45d 100644
> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> @@ -2,6 +2,7 @@ MediaTek Timers
>   ---------------
>   
>   MediaTek SoCs have two different timers on different platforms,

Nit: There are now three different timers so maybe:
"MediaTek SoCs have different timers on different platforms,"

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> +- CPUX (ARM/ARM64 System Timer)
>   - GPT (General Purpose Timer)
>   - SYST (System Timer)
>   
> @@ -29,6 +30,9 @@ Required properties:
>   	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>   	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>   
> +	For those SoCs that use CPUX
> +	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
> +
>   - reg: Should contain location and length for timer register.
>   - clocks: Should contain system clock.
>   

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-07 16:11     ` Matthias Brugger
  0 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
> System Timer on MediaTek platforms and add the MT6795 compatible for it.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> index 6f1f9dba6e88..49706cbef45d 100644
> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
> @@ -2,6 +2,7 @@ MediaTek Timers
>   ---------------
>   
>   MediaTek SoCs have two different timers on different platforms,

Nit: There are now three different timers so maybe:
"MediaTek SoCs have different timers on different platforms,"

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> +- CPUX (ARM/ARM64 System Timer)
>   - GPT (General Purpose Timer)
>   - SYST (System Timer)
>   
> @@ -29,6 +30,9 @@ Required properties:
>   	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>   	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>   
> +	For those SoCs that use CPUX
> +	* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
> +
>   - reg: Should contain location and length for timer register.
>   - clocks: Should contain system clock.
>   

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
  2022-05-18 11:24   ` AngeloGioacchino Del Regno
  (?)
@ 2022-06-07 16:11     ` Matthias Brugger
  -1 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Some MediaTek platforms with a buggy TrustZone ATF firmware will not
> initialize the AArch64 System Timer correctly: in these cases, the
> System Timer address is correctly programmed, as well as the CNTFRQ_EL0
> register (reading 13MHz, as it should be), but the assigned hardware
> timers are never started before (or after) booting Linux.
> 
> In this condition, any call to function get_cycles() will be returning
> zero, as CNTVCT_EL0 will always read zero.
> 
> One common critical symptom of that is trying to use the udelay()
> function (calling __delay()), which executes the following loop:
> 
>              start = get_cycles();
>              while ((get_cycles() - start) < cycles)
>                      cpu_relax();
> 
> which, when CNTVCT_EL0 always reads zero, translates to:
> 
>              while((0 - 0) < 0)  ==> while(0 < 0)
> 
> ... generating an infinite loop, even though zero is never less
> than zero, but always equal to it (this has to be researched,
> but it's out of the scope of this commit).
> 
> To fix this issue on the affected MediaTek platforms, the solution
> is to simply start the timers that are designed to be System Timer(s).
> These timers, downstream, are called "CPUXGPT" and there is one
> timer per CPU core; luckily, it is not necessary to set a start bit
> on each CPUX General Purpose Timer, but it's conveniently enough to:
>   - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
>   - Set the ENABLE bit on a global register (starts all CPUX timers).
> 
> The only small hurdle with this setup is that it's all done through
> the MCUSYS wrapper, where it is needed, for each read or write, to
> select a register address (by writing it to an index register) and
> then to perform any R/W on a "CON" register.
> 
> For example, writing "0x1" to the CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Write 0x1 to mcusys CON register
> 
> Reading from CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Read mcusys CON register.
> 
> Finally, starting this timer makes platforms affected by this issue
> to work correctly.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> ---
>   drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
>   1 file changed, 114 insertions(+)
> 
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> index 7bcb4a3f26fb..d5b29fd03ca2 100644
> --- a/drivers/clocksource/timer-mediatek.c
> +++ b/drivers/clocksource/timer-mediatek.c
> @@ -22,6 +22,19 @@
>   
>   #define TIMER_SYNC_TICKS        (3)
>   
> +/* cpux mcusys wrapper */
> +#define CPUX_CON_REG		0x0
> +#define CPUX_IDX_REG		0x4
> +
> +/* cpux */
> +#define CPUX_IDX_GLOBAL_CTRL	0x0
> + #define CPUX_ENABLE		BIT(0)
> + #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
> + #define CPUX_CLK_DIV1		BIT(8)
> + #define CPUX_CLK_DIV2		BIT(9)
> + #define CPUX_CLK_DIV4		BIT(10)
> +#define CPUX_IDX_GLOBAL_IRQ	0x30
> +
>   /* gpt */
>   #define GPT_IRQ_EN_REG          0x00
>   #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
> @@ -72,6 +85,52 @@
>   
>   static void __iomem *gpt_sched_reg __read_mostly;
>   
> +static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	return readl(timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	writel(val, timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
> +{
> +	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
> +	u32 val;
> +
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
> +
> +	if (enable)
> +		val |= *irq_mask;
> +	else
> +		val &= ~(*irq_mask);
> +
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
> +}
> +
> +static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
> +{
> +	/* Clear any irq */
> +	mtk_cpux_set_irq(to_timer_of(clkevt), false);
> +
> +	/*
> +	 * Disabling CPUXGPT timer will crash the platform, especially
> +	 * if Trusted Firmware is using it (usually, for sleep states),
> +	 * so we only mask the IRQ and call it a day.
> +	 */
> +	return 0;
> +}
> +
> +static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
> +{
> +	mtk_cpux_set_irq(to_timer_of(clkevt), true);
> +	return 0;
> +}
> +
>   static void mtk_syst_ack_irq(struct timer_of *to)
>   {
>   	/* Clear and disable interrupt */
> @@ -281,6 +340,60 @@ static struct timer_of to = {
>   	},
>   };
>   
> +static int __init mtk_cpux_init(struct device_node *node)
> +{
> +	static struct timer_of to_cpux;
> +	u32 freq, val;
> +	int ret;
> +
> +	/*
> +	 * There are per-cpu interrupts for the CPUX General Purpose Timer
> +	 * but since this timer feeds the AArch64 System Timer we can rely
> +	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
> +	 */
> +	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
> +	to_cpux.clkevt.name = "mtk-cpuxgpt";
> +	to_cpux.clkevt.rating = 10;
> +	to_cpux.clkevt.cpumask = cpu_possible_mask;
> +	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
> +	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
> +
> +	/* If this fails, bad things are about to happen... */
> +	ret = timer_of_init(node, &to_cpux);
> +	if (ret) {
> +		WARN(1, "Cannot start CPUX timers.\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * Check if we're given a clock with the right frequency for this
> +	 * timer, otherwise warn but keep going with the setup anyway, as
> +	 * that makes it possible to still boot the kernel, even though
> +	 * it may not work correctly (random lockups, etc).
> +	 * The reason behind this is that having an early UART may not be
> +	 * possible for everyone and this gives a chance to retrieve kmsg
> +	 * for eventual debugging even on consumer devices.
> +	 */
> +	freq = timer_of_rate(&to_cpux);
> +	if (freq > 13000000)
> +		WARN(1, "Requested unsupported timer frequency %u\n", freq);
> +
> +	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	val &= ~CPUX_CLK_DIV_MASK;
> +	val |= CPUX_CLK_DIV2;
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	/* Enable all CPUXGPT timers */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
> +					TIMER_SYNC_TICKS, 0xffffffff);
> +
> +	return 0;
> +}
> +
>   static int __init mtk_syst_init(struct device_node *node)
>   {
>   	int ret;
> @@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
>   }
>   TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
>   TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> +TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
@ 2022-06-07 16:11     ` Matthias Brugger
  0 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Some MediaTek platforms with a buggy TrustZone ATF firmware will not
> initialize the AArch64 System Timer correctly: in these cases, the
> System Timer address is correctly programmed, as well as the CNTFRQ_EL0
> register (reading 13MHz, as it should be), but the assigned hardware
> timers are never started before (or after) booting Linux.
> 
> In this condition, any call to function get_cycles() will be returning
> zero, as CNTVCT_EL0 will always read zero.
> 
> One common critical symptom of that is trying to use the udelay()
> function (calling __delay()), which executes the following loop:
> 
>              start = get_cycles();
>              while ((get_cycles() - start) < cycles)
>                      cpu_relax();
> 
> which, when CNTVCT_EL0 always reads zero, translates to:
> 
>              while((0 - 0) < 0)  ==> while(0 < 0)
> 
> ... generating an infinite loop, even though zero is never less
> than zero, but always equal to it (this has to be researched,
> but it's out of the scope of this commit).
> 
> To fix this issue on the affected MediaTek platforms, the solution
> is to simply start the timers that are designed to be System Timer(s).
> These timers, downstream, are called "CPUXGPT" and there is one
> timer per CPU core; luckily, it is not necessary to set a start bit
> on each CPUX General Purpose Timer, but it's conveniently enough to:
>   - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
>   - Set the ENABLE bit on a global register (starts all CPUX timers).
> 
> The only small hurdle with this setup is that it's all done through
> the MCUSYS wrapper, where it is needed, for each read or write, to
> select a register address (by writing it to an index register) and
> then to perform any R/W on a "CON" register.
> 
> For example, writing "0x1" to the CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Write 0x1 to mcusys CON register
> 
> Reading from CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Read mcusys CON register.
> 
> Finally, starting this timer makes platforms affected by this issue
> to work correctly.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> ---
>   drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
>   1 file changed, 114 insertions(+)
> 
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> index 7bcb4a3f26fb..d5b29fd03ca2 100644
> --- a/drivers/clocksource/timer-mediatek.c
> +++ b/drivers/clocksource/timer-mediatek.c
> @@ -22,6 +22,19 @@
>   
>   #define TIMER_SYNC_TICKS        (3)
>   
> +/* cpux mcusys wrapper */
> +#define CPUX_CON_REG		0x0
> +#define CPUX_IDX_REG		0x4
> +
> +/* cpux */
> +#define CPUX_IDX_GLOBAL_CTRL	0x0
> + #define CPUX_ENABLE		BIT(0)
> + #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
> + #define CPUX_CLK_DIV1		BIT(8)
> + #define CPUX_CLK_DIV2		BIT(9)
> + #define CPUX_CLK_DIV4		BIT(10)
> +#define CPUX_IDX_GLOBAL_IRQ	0x30
> +
>   /* gpt */
>   #define GPT_IRQ_EN_REG          0x00
>   #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
> @@ -72,6 +85,52 @@
>   
>   static void __iomem *gpt_sched_reg __read_mostly;
>   
> +static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	return readl(timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	writel(val, timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
> +{
> +	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
> +	u32 val;
> +
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
> +
> +	if (enable)
> +		val |= *irq_mask;
> +	else
> +		val &= ~(*irq_mask);
> +
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
> +}
> +
> +static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
> +{
> +	/* Clear any irq */
> +	mtk_cpux_set_irq(to_timer_of(clkevt), false);
> +
> +	/*
> +	 * Disabling CPUXGPT timer will crash the platform, especially
> +	 * if Trusted Firmware is using it (usually, for sleep states),
> +	 * so we only mask the IRQ and call it a day.
> +	 */
> +	return 0;
> +}
> +
> +static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
> +{
> +	mtk_cpux_set_irq(to_timer_of(clkevt), true);
> +	return 0;
> +}
> +
>   static void mtk_syst_ack_irq(struct timer_of *to)
>   {
>   	/* Clear and disable interrupt */
> @@ -281,6 +340,60 @@ static struct timer_of to = {
>   	},
>   };
>   
> +static int __init mtk_cpux_init(struct device_node *node)
> +{
> +	static struct timer_of to_cpux;
> +	u32 freq, val;
> +	int ret;
> +
> +	/*
> +	 * There are per-cpu interrupts for the CPUX General Purpose Timer
> +	 * but since this timer feeds the AArch64 System Timer we can rely
> +	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
> +	 */
> +	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
> +	to_cpux.clkevt.name = "mtk-cpuxgpt";
> +	to_cpux.clkevt.rating = 10;
> +	to_cpux.clkevt.cpumask = cpu_possible_mask;
> +	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
> +	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
> +
> +	/* If this fails, bad things are about to happen... */
> +	ret = timer_of_init(node, &to_cpux);
> +	if (ret) {
> +		WARN(1, "Cannot start CPUX timers.\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * Check if we're given a clock with the right frequency for this
> +	 * timer, otherwise warn but keep going with the setup anyway, as
> +	 * that makes it possible to still boot the kernel, even though
> +	 * it may not work correctly (random lockups, etc).
> +	 * The reason behind this is that having an early UART may not be
> +	 * possible for everyone and this gives a chance to retrieve kmsg
> +	 * for eventual debugging even on consumer devices.
> +	 */
> +	freq = timer_of_rate(&to_cpux);
> +	if (freq > 13000000)
> +		WARN(1, "Requested unsupported timer frequency %u\n", freq);
> +
> +	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	val &= ~CPUX_CLK_DIV_MASK;
> +	val |= CPUX_CLK_DIV2;
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	/* Enable all CPUXGPT timers */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
> +					TIMER_SYNC_TICKS, 0xffffffff);
> +
> +	return 0;
> +}
> +
>   static int __init mtk_syst_init(struct device_node *node)
>   {
>   	int ret;
> @@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
>   }
>   TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
>   TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> +TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers
@ 2022-06-07 16:11     ` Matthias Brugger
  0 siblings, 0 replies; 24+ messages in thread
From: Matthias Brugger @ 2022-06-07 16:11 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara



On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
> Some MediaTek platforms with a buggy TrustZone ATF firmware will not
> initialize the AArch64 System Timer correctly: in these cases, the
> System Timer address is correctly programmed, as well as the CNTFRQ_EL0
> register (reading 13MHz, as it should be), but the assigned hardware
> timers are never started before (or after) booting Linux.
> 
> In this condition, any call to function get_cycles() will be returning
> zero, as CNTVCT_EL0 will always read zero.
> 
> One common critical symptom of that is trying to use the udelay()
> function (calling __delay()), which executes the following loop:
> 
>              start = get_cycles();
>              while ((get_cycles() - start) < cycles)
>                      cpu_relax();
> 
> which, when CNTVCT_EL0 always reads zero, translates to:
> 
>              while((0 - 0) < 0)  ==> while(0 < 0)
> 
> ... generating an infinite loop, even though zero is never less
> than zero, but always equal to it (this has to be researched,
> but it's out of the scope of this commit).
> 
> To fix this issue on the affected MediaTek platforms, the solution
> is to simply start the timers that are designed to be System Timer(s).
> These timers, downstream, are called "CPUXGPT" and there is one
> timer per CPU core; luckily, it is not necessary to set a start bit
> on each CPUX General Purpose Timer, but it's conveniently enough to:
>   - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz);
>   - Set the ENABLE bit on a global register (starts all CPUX timers).
> 
> The only small hurdle with this setup is that it's all done through
> the MCUSYS wrapper, where it is needed, for each read or write, to
> select a register address (by writing it to an index register) and
> then to perform any R/W on a "CON" register.
> 
> For example, writing "0x1" to the CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Write 0x1 to mcusys CON register
> 
> Reading from CPUXGPT register offset 0x4:
> - Write 0x4 to mcusys INDEX register
> - Read mcusys CON register.
> 
> Finally, starting this timer makes platforms affected by this issue
> to work correctly.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>

> ---
>   drivers/clocksource/timer-mediatek.c | 114 +++++++++++++++++++++++++++
>   1 file changed, 114 insertions(+)
> 
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> index 7bcb4a3f26fb..d5b29fd03ca2 100644
> --- a/drivers/clocksource/timer-mediatek.c
> +++ b/drivers/clocksource/timer-mediatek.c
> @@ -22,6 +22,19 @@
>   
>   #define TIMER_SYNC_TICKS        (3)
>   
> +/* cpux mcusys wrapper */
> +#define CPUX_CON_REG		0x0
> +#define CPUX_IDX_REG		0x4
> +
> +/* cpux */
> +#define CPUX_IDX_GLOBAL_CTRL	0x0
> + #define CPUX_ENABLE		BIT(0)
> + #define CPUX_CLK_DIV_MASK	GENMASK(10, 8)
> + #define CPUX_CLK_DIV1		BIT(8)
> + #define CPUX_CLK_DIV2		BIT(9)
> + #define CPUX_CLK_DIV4		BIT(10)
> +#define CPUX_IDX_GLOBAL_IRQ	0x30
> +
>   /* gpt */
>   #define GPT_IRQ_EN_REG          0x00
>   #define GPT_IRQ_ENABLE(val)     BIT((val) - 1)
> @@ -72,6 +85,52 @@
>   
>   static void __iomem *gpt_sched_reg __read_mostly;
>   
> +static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	return readl(timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to)
> +{
> +	writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG);
> +	writel(val, timer_of_base(to) + CPUX_CON_REG);
> +}
> +
> +static void mtk_cpux_set_irq(struct timer_of *to, bool enable)
> +{
> +	const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask);
> +	u32 val;
> +
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to);
> +
> +	if (enable)
> +		val |= *irq_mask;
> +	else
> +		val &= ~(*irq_mask);
> +
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to);
> +}
> +
> +static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt)
> +{
> +	/* Clear any irq */
> +	mtk_cpux_set_irq(to_timer_of(clkevt), false);
> +
> +	/*
> +	 * Disabling CPUXGPT timer will crash the platform, especially
> +	 * if Trusted Firmware is using it (usually, for sleep states),
> +	 * so we only mask the IRQ and call it a day.
> +	 */
> +	return 0;
> +}
> +
> +static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt)
> +{
> +	mtk_cpux_set_irq(to_timer_of(clkevt), true);
> +	return 0;
> +}
> +
>   static void mtk_syst_ack_irq(struct timer_of *to)
>   {
>   	/* Clear and disable interrupt */
> @@ -281,6 +340,60 @@ static struct timer_of to = {
>   	},
>   };
>   
> +static int __init mtk_cpux_init(struct device_node *node)
> +{
> +	static struct timer_of to_cpux;
> +	u32 freq, val;
> +	int ret;
> +
> +	/*
> +	 * There are per-cpu interrupts for the CPUX General Purpose Timer
> +	 * but since this timer feeds the AArch64 System Timer we can rely
> +	 * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
> +	 */
> +	to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
> +	to_cpux.clkevt.name = "mtk-cpuxgpt";
> +	to_cpux.clkevt.rating = 10;
> +	to_cpux.clkevt.cpumask = cpu_possible_mask;
> +	to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown;
> +	to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume;
> +
> +	/* If this fails, bad things are about to happen... */
> +	ret = timer_of_init(node, &to_cpux);
> +	if (ret) {
> +		WARN(1, "Cannot start CPUX timers.\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * Check if we're given a clock with the right frequency for this
> +	 * timer, otherwise warn but keep going with the setup anyway, as
> +	 * that makes it possible to still boot the kernel, even though
> +	 * it may not work correctly (random lockups, etc).
> +	 * The reason behind this is that having an early UART may not be
> +	 * possible for everyone and this gives a chance to retrieve kmsg
> +	 * for eventual debugging even on consumer devices.
> +	 */
> +	freq = timer_of_rate(&to_cpux);
> +	if (freq > 13000000)
> +		WARN(1, "Requested unsupported timer frequency %u\n", freq);
> +
> +	/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	val &= ~CPUX_CLK_DIV_MASK;
> +	val |= CPUX_CLK_DIV2;
> +	mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	/* Enable all CPUXGPT timers */
> +	val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +	mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux);
> +
> +	clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux),
> +					TIMER_SYNC_TICKS, 0xffffffff);
> +
> +	return 0;
> +}
> +
>   static int __init mtk_syst_init(struct device_node *node)
>   {
>   	int ret;
> @@ -339,3 +452,4 @@ static int __init mtk_gpt_init(struct device_node *node)
>   }
>   TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
>   TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> +TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
  2022-06-07 16:11     ` Matthias Brugger
  (?)
@ 2022-06-09  9:35       ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-09  9:35 UTC (permalink / raw)
  To: Matthias Brugger, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara

Il 07/06/22 18:11, Matthias Brugger ha scritto:
> 
> 
> On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
>> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
>> System Timer on MediaTek platforms and add the MT6795 compatible for it.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> ---
>>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt 
>> b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> index 6f1f9dba6e88..49706cbef45d 100644
>> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> @@ -2,6 +2,7 @@ MediaTek Timers
>>   ---------------
>>   MediaTek SoCs have two different timers on different platforms,
> 
> Nit: There are now three different timers so maybe:
> "MediaTek SoCs have different timers on different platforms,"
> 
> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
> 

Hi Matthias,
can we please ignore that description nit for this patch?

I was anyway planning to do a YAML conversion after getting this merged in, perhaps
we can just fix that on the new one instead?

Cheers,
Angelo

>> +- CPUX (ARM/ARM64 System Timer)
>>   - GPT (General Purpose Timer)
>>   - SYST (System Timer)
>> @@ -29,6 +30,9 @@ Required properties:
>>       * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>>       * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>> +    For those SoCs that use CPUX
>> +    * "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
>> +
>>   - reg: Should contain location and length for timer register.
>>   - clocks: Should contain system clock.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-09  9:35       ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-09  9:35 UTC (permalink / raw)
  To: Matthias Brugger, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara

Il 07/06/22 18:11, Matthias Brugger ha scritto:
> 
> 
> On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
>> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
>> System Timer on MediaTek platforms and add the MT6795 compatible for it.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> ---
>>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt 
>> b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> index 6f1f9dba6e88..49706cbef45d 100644
>> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> @@ -2,6 +2,7 @@ MediaTek Timers
>>   ---------------
>>   MediaTek SoCs have two different timers on different platforms,
> 
> Nit: There are now three different timers so maybe:
> "MediaTek SoCs have different timers on different platforms,"
> 
> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
> 

Hi Matthias,
can we please ignore that description nit for this patch?

I was anyway planning to do a YAML conversion after getting this merged in, perhaps
we can just fix that on the new one instead?

Cheers,
Angelo

>> +- CPUX (ARM/ARM64 System Timer)
>>   - GPT (General Purpose Timer)
>>   - SYST (System Timer)
>> @@ -29,6 +30,9 @@ Required properties:
>>       * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>>       * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>> +    For those SoCs that use CPUX
>> +    * "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
>> +
>>   - reg: Should contain location and length for timer register.
>>   - clocks: Should contain system clock.


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible
@ 2022-06-09  9:35       ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-09  9:35 UTC (permalink / raw)
  To: Matthias Brugger, daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, linux-kernel, devicetree,
	linux-arm-kernel, linux-mediatek, konrad.dybcio, marijn.suijten,
	martin.botka, ~postmarketos/upstreaming, phone-devel,
	paul.bouchara

Il 07/06/22 18:11, Matthias Brugger ha scritto:
> 
> 
> On 18/05/2022 13:24, AngeloGioacchino Del Regno wrote:
>> Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64
>> System Timer on MediaTek platforms and add the MT6795 compatible for it.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> ---
>>   .../devicetree/bindings/timer/mediatek,mtk-timer.txt          | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt 
>> b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> index 6f1f9dba6e88..49706cbef45d 100644
>> --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
>> @@ -2,6 +2,7 @@ MediaTek Timers
>>   ---------------
>>   MediaTek SoCs have two different timers on different platforms,
> 
> Nit: There are now three different timers so maybe:
> "MediaTek SoCs have different timers on different platforms,"
> 
> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
> 

Hi Matthias,
can we please ignore that description nit for this patch?

I was anyway planning to do a YAML conversion after getting this merged in, perhaps
we can just fix that on the new one instead?

Cheers,
Angelo

>> +- CPUX (ARM/ARM64 System Timer)
>>   - GPT (General Purpose Timer)
>>   - SYST (System Timer)
>> @@ -29,6 +30,9 @@ Required properties:
>>       * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
>>       * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
>> +    For those SoCs that use CPUX
>> +    * "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
>> +
>>   - reg: Should contain location and length for timer register.
>>   - clocks: Should contain system clock.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-06-13 13:32 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-13 13:32 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Changed statement in documentation, now saying:
   "MediaTek SoCs have different timers on different platforms"

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   6 +-
 drivers/clocksource/timer-mediatek.c          | 119 ++++++++++++++++++
 2 files changed, 124 insertions(+), 1 deletion(-)

-- 
2.35.1


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-06-13 13:32 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-13 13:32 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Changed statement in documentation, now saying:
   "MediaTek SoCs have different timers on different platforms"

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   6 +-
 drivers/clocksource/timer-mediatek.c          | 119 ++++++++++++++++++
 2 files changed, 124 insertions(+), 1 deletion(-)

-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer
@ 2022-06-13 13:32 ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 24+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-06-13 13:32 UTC (permalink / raw)
  To: daniel.lezcano
  Cc: tglx, robh+dt, krzysztof.kozlowski+dt, matthias.bgg,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	konrad.dybcio, marijn.suijten, martin.botka,
	~postmarketos/upstreaming, phone-devel, paul.bouchara,
	AngeloGioacchino Del Regno

In an effort to give some love to the apparently forgotten MT6795 SoC,
I am upstreaming more components that are necessary to support platforms
powered by this one apart from a simple boot to serial console.

This series introduces support to start the System Timer for the CPU
cores found in various MediaTek SoCs including, but not limited to the
MT6795 Helio X10 - and will most probably unblock many developers for
the upstreaming of various platforms.

For a broad overview of why/what/when, please look at the description
of patch [2/2] in this series.

Tested on a MT6795 Sony Xperia M5 (codename "Holly") smartphone.

Changes in v3:
 - Changed statement in documentation, now saying:
   "MediaTek SoCs have different timers on different platforms"

Changes in v2:
 - Added back a lost line in commit 2/2 (sorry, commit didn't get amended...!)
 - Tested again for safety

AngeloGioacchino Del Regno (2):
  dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795
    compatible
  clocksource/drivers/timer-mediatek: Implement CPUXGPT timers

 .../bindings/timer/mediatek,mtk-timer.txt     |   6 +-
 drivers/clocksource/timer-mediatek.c          | 119 ++++++++++++++++++
 2 files changed, 124 insertions(+), 1 deletion(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2022-06-13 17:51 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-18 11:24 [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer AngeloGioacchino Del Regno
2022-05-18 11:24 ` AngeloGioacchino Del Regno
2022-05-18 11:24 ` AngeloGioacchino Del Regno
2022-05-18 11:24 ` [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible AngeloGioacchino Del Regno
2022-05-18 11:24   ` AngeloGioacchino Del Regno
2022-05-18 11:24   ` AngeloGioacchino Del Regno
2022-06-01 20:03   ` Rob Herring
2022-06-01 20:03     ` Rob Herring
2022-06-01 20:03     ` Rob Herring
2022-06-07 16:11   ` Matthias Brugger
2022-06-07 16:11     ` Matthias Brugger
2022-06-07 16:11     ` Matthias Brugger
2022-06-09  9:35     ` AngeloGioacchino Del Regno
2022-06-09  9:35       ` AngeloGioacchino Del Regno
2022-06-09  9:35       ` AngeloGioacchino Del Regno
2022-05-18 11:24 ` [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers AngeloGioacchino Del Regno
2022-05-18 11:24   ` AngeloGioacchino Del Regno
2022-05-18 11:24   ` AngeloGioacchino Del Regno
2022-06-07 16:11   ` Matthias Brugger
2022-06-07 16:11     ` Matthias Brugger
2022-06-07 16:11     ` Matthias Brugger
2022-06-13 13:32 [PATCH v3 0/2] MediaTek SoC ARM/ARM64 System Timer AngeloGioacchino Del Regno
2022-06-13 13:32 ` AngeloGioacchino Del Regno
2022-06-13 13:32 ` AngeloGioacchino Del Regno

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.