From 557804a81d256b15952dcd179280ede92a5bfae1 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 15 Oct 2021 10:29:14 +0200 Subject: dt-bindings: timer: cadence_ttc: Add power-domains Describe optional power-domain property to fix dts_check warnings. The similar change was done by commit 8c0aa567146b ("dt-bindings: gpio: fsl-imx-gpio: Add power-domains"). Signed-off-by: Michal Simek Acked-by: Rob Herring Link: https://lore.kernel.org/r/cc655a72b20790f6d7408b1aaf81c4bf878aafb4.1634286552.git.michal.simek@xilinx.com Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/timer/cdns,ttc.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/timer/cdns,ttc.yaml b/Documentation/devicetree/bindings/timer/cdns,ttc.yaml index 8615353f69b4..c3386076a98c 100644 --- a/Documentation/devicetree/bindings/timer/cdns,ttc.yaml +++ b/Documentation/devicetree/bindings/timer/cdns,ttc.yaml @@ -25,6 +25,9 @@ properties: clocks: maxItems: 1 + power-domains: + maxItems: 1 + timer-width: $ref: "/schemas/types.yaml#/definitions/uint32" description: | -- cgit v1.2.3 From ad253b3dd79851d926154ef747a69427573233e4 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Tue, 24 Aug 2021 11:56:37 +0200 Subject: dt-bindings: timer: remove rockchip,rk3066-timer compatible string from rockchip,rk-timer.yaml The Rockchip rk3066 timers have a different register layout then rk3288 with only a 32 vs 64 bits timer channel. The timers in rk3066a.dtsi have "snps,dw-apb-timer" as compatible string, so remove the "rockchip,rk3066-timer" from rockchip,rk-timer.yaml Signed-off-by: Johan Jonker Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210824095637.2547-1-jbx6244@gmail.com Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml index e26ecb5893ae..5d157d87dad5 100644 --- a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml +++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml @@ -18,7 +18,6 @@ properties: - enum: - rockchip,rv1108-timer - rockchip,rk3036-timer - - rockchip,rk3066-timer - rockchip,rk3188-timer - rockchip,rk3228-timer - rockchip,rk3229-timer -- cgit v1.2.3 From 7cd925a8823d16de5614d3f0aabea9948747accd Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 1 Nov 2021 21:35:30 +0200 Subject: clocksource/drivers/exynos_mct: Refactor resources allocation Move interrupts allocation from exynos4_timer_resources() into separate function together with the interrupt number parsing code from mct_init_dt(), so the code for managing interrupts is kept together. While touching exynos4_timer_resources() function, move of_iomap() to it. No functional changes. Signed-off-by: Marek Szyprowski Reviewed-by: Chanwoo Choi Tested-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20211101193531.15078-2-semen.protsenko@linaro.org Signed-off-by: Daniel Lezcano --- drivers/clocksource/exynos_mct.c | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 5e3e96d3d1b9..857cf12ebe57 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -504,11 +504,14 @@ static int exynos4_mct_dying_cpu(unsigned int cpu) return 0; } -static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base) +static int __init exynos4_timer_resources(struct device_node *np) { - int err, cpu; struct clk *mct_clk, *tick_clk; + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: unable to ioremap mct address space\n", __func__); + tick_clk = of_clk_get_by_name(np, "fin_pll"); if (IS_ERR(tick_clk)) panic("%s: unable to determine tick clock rate\n", __func__); @@ -519,9 +522,27 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem * panic("%s: unable to retrieve mct clock instance\n", __func__); clk_prepare_enable(mct_clk); - reg_base = base; - if (!reg_base) - panic("%s: unable to ioremap mct address space\n", __func__); + return 0; +} + +static int __init exynos4_timer_interrupts(struct device_node *np, + unsigned int int_type) +{ + int nr_irqs, i, err, cpu; + + mct_int_type = int_type; + + /* This driver uses only one global timer interrupt */ + mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); + + /* + * Find out the number of local irqs specified. The local + * timer irqs are specified after the four global timer + * irqs are specified. + */ + nr_irqs = of_irq_count(np); + for (i = MCT_L0_IRQ; i < nr_irqs; i++) + mct_irqs[i] = irq_of_parse_and_map(np, i); if (mct_int_type == MCT_INT_PPI) { @@ -581,24 +602,13 @@ out_irq: static int __init mct_init_dt(struct device_node *np, unsigned int int_type) { - u32 nr_irqs, i; int ret; - mct_int_type = int_type; - - /* This driver uses only one global timer interrupt */ - mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); - - /* - * Find out the number of local irqs specified. The local - * timer irqs are specified after the four global timer - * irqs are specified. - */ - nr_irqs = of_irq_count(np); - for (i = MCT_L0_IRQ; i < nr_irqs; i++) - mct_irqs[i] = irq_of_parse_and_map(np, i); + ret = exynos4_timer_resources(np); + if (ret) + return ret; - ret = exynos4_timer_resources(np, of_iomap(np, 0)); + ret = exynos4_timer_interrupts(np, int_type); if (ret) return ret; -- cgit v1.2.3 From c4f5b30dda01f2f6979a9681142de454991182ee Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 12 Nov 2021 18:44:10 +0000 Subject: reset: Add of_reset_control_get_optional_exclusive() Add optional variant of of_reset_control_get_exclusive(). If the requested reset is not specified in the device tree, this function returns NULL instead of an error. Suggested-by: Philipp Zabel Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211112184413.4391-2-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- include/linux/reset.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/linux/reset.h b/include/linux/reset.h index db0e6115a2f6..8a21b5756c3e 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -454,6 +454,26 @@ static inline struct reset_control *of_reset_control_get_exclusive( return __of_reset_control_get(node, id, 0, false, false, true); } +/** + * of_reset_control_get_optional_exclusive - Lookup and obtain an optional exclusive + * reference to a reset controller. + * @node: device to be reset by the controller + * @id: reset line name + * + * Optional variant of of_reset_control_get_exclusive(). If the requested reset + * is not specified in the device tree, this function returns NULL instead of + * an error. + * + * Returns a struct reset_control or IS_ERR() condition containing errno. + * + * Use of id names is optional. + */ +static inline struct reset_control *of_reset_control_get_optional_exclusive( + struct device_node *node, const char *id) +{ + return __of_reset_control_get(node, id, 0, false, true, true); +} + /** * of_reset_control_get_shared - Lookup and obtain a shared reference * to a reset controller. -- cgit v1.2.3 From 453e2cadc97ca52e423852435522eb7d4f4b5b6b Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 26 Nov 2021 15:39:58 +0800 Subject: dt-bindings: timer: tpm-timer: Add imx8ulp compatible string The tpm timer on i.MX8ULP is derived from i.MX7ULP, it use two compatible strings, so update the compatible string for it. Reviewed-by: Dong Aisheng Acked-by: Rob Herring Signed-off-by: Jacky Bai Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20211126074002.1535696-4-peng.fan@oss.nxp.com Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml index edd9585f6726..f69773a8e4b9 100644 --- a/Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml +++ b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml @@ -19,7 +19,11 @@ description: | properties: compatible: - const: fsl,imx7ulp-tpm + oneOf: + - const: fsl,imx7ulp-tpm + - items: + - const: fsl,imx8ulp-tpm + - const: fsl,imx7ulp-tpm reg: maxItems: 1 -- cgit v1.2.3 From 410fbda49cc9b2165e80b87880f164d9644b460d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 3 Nov 2021 16:48:04 +0000 Subject: clocksource/drivers/exynos_mct: Fix silly typo resulting in checkpatch warning Commit ae460fd9164b ("clocksource/drivers/exynos_mct: Prioritise Arm arch timer on arm64") changed the rating of the MCT clockevents device to be lower than the Arm architected timer and, in the process, replaced a semicolon with a comma thanks to a silly copy-paste error. Put the semicolon back so that the code looks more idiomatic and resolve the SUSPECT_COMMA_SEMICOLON warning from checkpatch at the same time. Cc: Krzysztof Kozlowski Cc: Daniel Lezcano Signed-off-by: Will Deacon Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20211103164804.30182-1-will@kernel.org Signed-off-by: Daniel Lezcano --- drivers/clocksource/exynos_mct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 857cf12ebe57..6db3d5511b0f 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -467,7 +467,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu) evt->tick_resume = set_state_shutdown; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERCPU; - evt->rating = MCT_CLKEVENTS_RATING, + evt->rating = MCT_CLKEVENTS_RATING; exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); -- cgit v1.2.3 From 92d06a3f67ad809649d26aa7698e4d42362585a8 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 12 Nov 2021 18:44:11 +0000 Subject: dt-bindings: timer: renesas: ostm: Document Renesas RZ/G2L OSTM Document the General Timer Module(a.k.a OSTM) found on the RZ/G2L SoC. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211112184413.4391-3-biju.das.jz@bp.renesas.com Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/timer/renesas,ostm.yaml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml index 600d47ab7d58..7fa7f977b44c 100644 --- a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml +++ b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml @@ -21,9 +21,10 @@ properties: compatible: items: - enum: - - renesas,r7s72100-ostm # RZ/A1H - - renesas,r7s9210-ostm # RZ/A2M - - const: renesas,ostm # Generic + - renesas,r7s72100-ostm # RZ/A1H + - renesas,r7s9210-ostm # RZ/A2M + - renesas,r9a07g044-ostm # RZ/G2{L,LC} + - const: renesas,ostm # Generic reg: maxItems: 1 @@ -37,6 +38,9 @@ properties: power-domains: maxItems: 1 + resets: + maxItems: 1 + required: - compatible - reg @@ -44,6 +48,16 @@ required: - clocks - power-domains +if: + properties: + compatible: + contains: + enum: + - renesas,r9a07g044-ostm +then: + required: + - resets + additionalProperties: false examples: -- cgit v1.2.3 From 3a3e9f23c2cae907677a236fa547610ca747e6fb Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 12 Nov 2021 18:44:12 +0000 Subject: clocksource/drivers/renesas-ostm: Add RZ/G2L OSTM support RZ/G2L SoC has Generic Timer Module(a.k.a OSTM) which needs to deassert the reset line before accessing any registers. This patch adds an entry point for RZ/G2L so that we can deassert the reset line in probe callback. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211112184413.4391-4-biju.das.jz@bp.renesas.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/renesas-ostm.c | 39 +++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/renesas-ostm.c b/drivers/clocksource/renesas-ostm.c index 3d06ba66008c..21d1392637b8 100644 --- a/drivers/clocksource/renesas-ostm.c +++ b/drivers/clocksource/renesas-ostm.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -159,6 +161,7 @@ static int __init ostm_init_clkevt(struct timer_of *to) static int __init ostm_init(struct device_node *np) { + struct reset_control *rstc; struct timer_of *to; int ret; @@ -166,6 +169,14 @@ static int __init ostm_init(struct device_node *np) if (!to) return -ENOMEM; + rstc = of_reset_control_get_optional_exclusive(np, NULL); + if (IS_ERR(rstc)) { + ret = PTR_ERR(rstc); + goto err_free; + } + + reset_control_deassert(rstc); + to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK; if (system_clock) { /* @@ -178,7 +189,7 @@ static int __init ostm_init(struct device_node *np) ret = timer_of_init(np, to); if (ret) - goto err_free; + goto err_reset; /* * First probed device will be used as system clocksource. Any @@ -203,9 +214,35 @@ static int __init ostm_init(struct device_node *np) err_cleanup: timer_of_cleanup(to); +err_reset: + reset_control_assert(rstc); + reset_control_put(rstc); err_free: kfree(to); return ret; } TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init); + +#ifdef CONFIG_ARCH_R9A07G044 +static int __init ostm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + return ostm_init(dev->of_node); +} + +static const struct of_device_id ostm_of_table[] = { + { .compatible = "renesas,ostm", }, + { /* sentinel */ } +}; + +static struct platform_driver ostm_device_driver = { + .driver = { + .name = "renesas_ostm", + .of_match_table = of_match_ptr(ostm_of_table), + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(ostm_device_driver, ostm_probe); +#endif -- cgit v1.2.3 From a2807f657976b943bf0eb81d026398d28aa89863 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 12 Nov 2021 18:44:13 +0000 Subject: clocksource/drivers/renesas,ostm: Make RENESAS_OSTM symbol visible As RZ/G2L uses the ARM Architected Timer as system timer, enabling the OSTM is not mandatory. Make RENESAS_OSTM symbol visible, so that user can enable it when needed. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211112184413.4391-5-biju.das.jz@bp.renesas.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f65e31bab9ae..821ea4aa5c86 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -510,7 +510,8 @@ config SH_TIMER_MTU2 This hardware comes with 16-bit timer registers. config RENESAS_OSTM - bool "Renesas OSTM timer driver" if COMPILE_TEST + bool "Renesas OSTM timer driver" + depends on ARCH_RENESAS || COMPILE_TEST select CLKSRC_MMIO select TIMER_OF help -- cgit v1.2.3 From f5bd5fc9d478cdb94f89ccc74870dd81d1919b42 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 1 Dec 2021 20:50:29 +0800 Subject: clocksource/drivers/imx-sysctr: Mark two variable with __ro_after_init The variables 'sys_ctr_base' and 'cmpcr' are not be updated after init, so mark them as __ro_after_init. Cc: Kees Cook Signed-off-by: Peng Fan Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20211201125030.2307746-1-peng.fan@oss.nxp.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-imx-sysctr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index 18b90fc56bfc..2b309af11266 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -20,8 +20,8 @@ #define SYS_CTR_CLK_DIV 0x3 -static void __iomem *sys_ctr_base; -static u32 cmpcr; +static void __iomem *sys_ctr_base __ro_after_init; +static u32 cmpcr __ro_after_init; static void sysctr_timer_enable(bool enable) { -- cgit v1.2.3 From 0ed9e4ebcebcb36bd1186e68cf2f72b3e0bfbac6 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 1 Dec 2021 20:50:30 +0800 Subject: clocksource/drivers/timer-imx-sysctr: Set cpumask to cpu_possible_mask The syctr interrupt could set the affinity to any cores in the SoC. However, the default affinity is set to cpu 0. This timer will be used as broadcast timer on all the i.MX SoCs. Because DYNIRQ flag is set, the core time framework will runtime set the interrupt affinity to the cores that needs to wake up and the cpumask will runtime set to the core that will be wake up. So even the sysctr initialization use cpumask 0, there is no issue, the current patch is just use cpu_possible_mask to show the fact that the timer supports routed to all the cpu cores and nothing else. Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20211201125030.2307746-2-peng.fan@oss.nxp.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-imx-sysctr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index 2b309af11266..55a8e198d2a1 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -119,7 +119,7 @@ static struct timer_of to_sysctr = { static void __init sysctr_clockevent_init(void) { - to_sysctr.clkevt.cpumask = cpumask_of(0); + to_sysctr.clkevt.cpumask = cpu_possible_mask; clockevents_config_and_register(&to_sysctr.clkevt, timer_of_rate(&to_sysctr), -- cgit v1.2.3 From 0642fb4ba68f7158f7a6d92190b3090cf0c7fac6 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Tue, 23 Nov 2021 11:25:24 -0800 Subject: clocksource/drivers/pistachio: Fix -Wunused-but-set-variable warning Variable 'overflow' set but not used, but this is the intended behavior. The hardware only updates the counter register after the overflow register read. However, the value of overflow is not actually needed. Link: https://lore.kernel.org/lkml/202111200402.afQsussU-lkp@intel.com/ Reported-by: kernel test robot Suggested-by: Daniel Lezcano Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20211123192524.1038304-1-dfustini@baylibre.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-pistachio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-pistachio.c b/drivers/clocksource/timer-pistachio.c index 6f37181a8c63..69c069e6f0a2 100644 --- a/drivers/clocksource/timer-pistachio.c +++ b/drivers/clocksource/timer-pistachio.c @@ -71,7 +71,8 @@ static u64 notrace pistachio_clocksource_read_cycles(struct clocksource *cs) { struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); - u32 counter, overflow; + __maybe_unused u32 overflow; + u32 counter; unsigned long flags; /* -- cgit v1.2.3 From 5fc1f93f69989e72be7a84ded6ee867d6415f690 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Fri, 17 Dec 2021 20:57:22 +0100 Subject: clocksource/drivers: Add MStar MSC313e timer support The MSC313e-compatible SoCs have 3 timer hardware blocks. All of these are free running 32-bit increasing counters and can generate interrupts. Based onto a maximum value register, each timer can either count from 0 to max, one time then stop (which generates interrupts) or can count from 0 to max and then roll. This commit adds basic support for these timers, the first timer block being used as clocksource/sched_clock and delay, while the others will be used as clockevents. Signed-off-by: Romain Perier Co-developed-by: Daniel Palmer Signed-off-by: Daniel Palmer Link: https://lore.kernel.org/r/20211217195727.8955-2-romain.perier@gmail.com Signed-off-by: Daniel Lezcano --- MAINTAINERS | 1 + drivers/clocksource/Kconfig | 9 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-msc313e.c | 244 ++++++++++++++++++++++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 drivers/clocksource/timer-msc313e.c diff --git a/MAINTAINERS b/MAINTAINERS index 7a2345ce8521..f39a1617bf50 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2282,6 +2282,7 @@ F: Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml F: arch/arm/boot/dts/mstar-* F: arch/arm/mach-mstar/ F: drivers/clk/mstar/ +F: drivers/clocksource/timer-msc313e.c F: drivers/gpio/gpio-msc313.c F: drivers/rtc/rtc-msc313.c F: drivers/watchdog/msc313e_wdt.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 821ea4aa5c86..cfb8ea0df3b1 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -672,6 +672,15 @@ config MILBEAUT_TIMER help Enables the support for Milbeaut timer driver. +config MSC313E_TIMER + bool "MSC313E timer driver" if COMPILE_TEST + select TIMER_OF + select CLKSRC_MMIO + help + Enables support for the MStar MSC313E timer driver. + This provides access to multiple interrupt generating + programmable 32-bit free running incrementing counters. + config INGENIC_TIMER bool "Clocksource/timer using the TCU in Ingenic JZ SoCs" default MACH_INGENIC diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index c17ee32a7151..fa5f624eadb6 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -88,3 +88,4 @@ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o +obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o diff --git a/drivers/clocksource/timer-msc313e.c b/drivers/clocksource/timer-msc313e.c new file mode 100644 index 000000000000..154e73444a0c --- /dev/null +++ b/drivers/clocksource/timer-msc313e.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MStar timer driver + * + * Copyright (C) 2021 Daniel Palmer + * Copyright (C) 2021 Romain Perier + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ARM +#include +#endif + +#include "timer-of.h" + +#define TIMER_NAME "msc313e_timer" + +#define MSC313E_REG_CTRL 0x00 +#define MSC313E_REG_CTRL_TIMER_EN BIT(0) +#define MSC313E_REG_CTRL_TIMER_TRIG BIT(1) +#define MSC313E_REG_CTRL_TIMER_INT_EN BIT(8) +#define MSC313E_REG_TIMER_MAX_LOW 0x08 +#define MSC313E_REG_TIMER_MAX_HIGH 0x0c +#define MSC313E_REG_COUNTER_LOW 0x10 +#define MSC313E_REG_COUNTER_HIGH 0x14 + +#define TIMER_SYNC_TICKS 3 + +#ifdef CONFIG_ARM +struct msc313e_delay { + void __iomem *base; + struct delay_timer delay; +}; +static struct msc313e_delay msc313e_delay; +#endif + +static void __iomem *msc313e_clksrc; + +static void msc313e_timer_stop(void __iomem *base) +{ + writew(0, base + MSC313E_REG_CTRL); +} + +static void msc313e_timer_start(void __iomem *base, bool periodic) +{ + u16 reg; + + reg = readw(base + MSC313E_REG_CTRL); + if (periodic) + reg |= MSC313E_REG_CTRL_TIMER_EN; + else + reg |= MSC313E_REG_CTRL_TIMER_TRIG; + writew(reg | MSC313E_REG_CTRL_TIMER_INT_EN, base + MSC313E_REG_CTRL); +} + +static void msc313e_timer_setup(void __iomem *base, unsigned long delay) +{ + unsigned long flags; + + local_irq_save(flags); + writew(delay >> 16, base + MSC313E_REG_TIMER_MAX_HIGH); + writew(delay & 0xffff, base + MSC313E_REG_TIMER_MAX_LOW); + local_irq_restore(flags); +} + +static unsigned long msc313e_timer_current_value(void __iomem *base) +{ + unsigned long flags; + u16 l, h; + + local_irq_save(flags); + l = readw(base + MSC313E_REG_COUNTER_LOW); + h = readw(base + MSC313E_REG_COUNTER_HIGH); + local_irq_restore(flags); + + return (((u32)h) << 16 | l); +} + +static int msc313e_timer_clkevt_shutdown(struct clock_event_device *evt) +{ + struct timer_of *timer = to_timer_of(evt); + + msc313e_timer_stop(timer_of_base(timer)); + + return 0; +} + +static int msc313e_timer_clkevt_set_oneshot(struct clock_event_device *evt) +{ + struct timer_of *timer = to_timer_of(evt); + + msc313e_timer_stop(timer_of_base(timer)); + msc313e_timer_start(timer_of_base(timer), false); + + return 0; +} + +static int msc313e_timer_clkevt_set_periodic(struct clock_event_device *evt) +{ + struct timer_of *timer = to_timer_of(evt); + + msc313e_timer_stop(timer_of_base(timer)); + msc313e_timer_setup(timer_of_base(timer), timer_of_period(timer)); + msc313e_timer_start(timer_of_base(timer), true); + + return 0; +} + +static int msc313e_timer_clkevt_next_event(unsigned long evt, struct clock_event_device *clkevt) +{ + struct timer_of *timer = to_timer_of(clkevt); + + msc313e_timer_stop(timer_of_base(timer)); + msc313e_timer_setup(timer_of_base(timer), evt); + msc313e_timer_start(timer_of_base(timer), false); + + return 0; +} + +static irqreturn_t msc313e_timer_clkevt_irq(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static u64 msc313e_timer_clksrc_read(struct clocksource *cs) +{ + return msc313e_timer_current_value(msc313e_clksrc) & cs->mask; +} + +#ifdef CONFIG_ARM +static unsigned long msc313e_read_delay_timer_read(void) +{ + return msc313e_timer_current_value(msc313e_delay.base); +} +#endif + +static u64 msc313e_timer_sched_clock_read(void) +{ + return msc313e_timer_current_value(msc313e_clksrc); +} + +static struct clock_event_device msc313e_clkevt = { + .name = TIMER_NAME, + .rating = 300, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_state_shutdown = msc313e_timer_clkevt_shutdown, + .set_state_periodic = msc313e_timer_clkevt_set_periodic, + .set_state_oneshot = msc313e_timer_clkevt_set_oneshot, + .tick_resume = msc313e_timer_clkevt_shutdown, + .set_next_event = msc313e_timer_clkevt_next_event, +}; + +static int __init msc313e_clkevt_init(struct device_node *np) +{ + int ret; + struct timer_of *to; + + to = kzalloc(sizeof(*to), GFP_KERNEL); + if (!to) + return -ENOMEM; + + to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE; + to->of_irq.handler = msc313e_timer_clkevt_irq; + ret = timer_of_init(np, to); + if (ret) + return ret; + + msc313e_clkevt.cpumask = cpu_possible_mask; + msc313e_clkevt.irq = to->of_irq.irq; + to->clkevt = msc313e_clkevt; + + clockevents_config_and_register(&to->clkevt, timer_of_rate(to), + TIMER_SYNC_TICKS, 0xffffffff); + return 0; +} + +static int __init msc313e_clksrc_init(struct device_node *np) +{ + struct timer_of to = { 0 }; + int ret; + u16 reg; + + to.flags = TIMER_OF_BASE | TIMER_OF_CLOCK; + ret = timer_of_init(np, &to); + if (ret) + return ret; + + msc313e_clksrc = timer_of_base(&to); + reg = readw(msc313e_clksrc + MSC313E_REG_CTRL); + reg |= MSC313E_REG_CTRL_TIMER_EN; + writew(reg, msc313e_clksrc + MSC313E_REG_CTRL); + +#ifdef CONFIG_ARM + msc313e_delay.base = timer_of_base(&to); + msc313e_delay.delay.read_current_timer = msc313e_read_delay_timer_read; + msc313e_delay.delay.freq = timer_of_rate(&to); + + register_current_timer_delay(&msc313e_delay.delay); +#endif + + sched_clock_register(msc313e_timer_sched_clock_read, 32, timer_of_rate(&to)); + return clocksource_mmio_init(timer_of_base(&to), TIMER_NAME, timer_of_rate(&to), 300, 32, + msc313e_timer_clksrc_read); +} + +static int __init msc313e_timer_init(struct device_node *np) +{ + int ret = 0; + static int num_called; + + switch (num_called) { + case 0: + ret = msc313e_clksrc_init(np); + if (ret) + return ret; + break; + + default: + ret = msc313e_clkevt_init(np); + if (ret) + return ret; + break; + } + + num_called++; + + return 0; +} + +TIMER_OF_DECLARE(msc313, "mstar,msc313e-timer", msc313e_timer_init); -- cgit v1.2.3 From e64da64f410cf4f9697e25ab76cdfc679f4fb6db Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Fri, 17 Dec 2021 20:57:23 +0100 Subject: clocksource/drivers/msc313e: Add support for ssd20xd-based platforms On SSD20X family SoCs the timers are connected to a 432MHz clock instead of 12MHz that all the previous chips used. There is no way to reduce or divide these clocks in the clktree yet as we do not know exactly where the 432MHz clock comes from but it is enabled at boot. The SSD20X timers have an input clock divider within the timer itself to configure the frequency. timer0 is preconfigured at power up to run at 12MHz so it is backwards compatible and doesn't need special handling right now. timer1 and timer2 run at 432Mhz at power up so are not backward compatible. This commit adds support for the input clock divider register and sets timer1 and timer2 to run at 48Mhz for clockevents. Signed-off-by: Romain Perier Link: https://lore.kernel.org/r/20211217195727.8955-3-romain.perier@gmail.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-msc313e.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/clocksource/timer-msc313e.c b/drivers/clocksource/timer-msc313e.c index 154e73444a0c..54c54ca7c786 100644 --- a/drivers/clocksource/timer-msc313e.c +++ b/drivers/clocksource/timer-msc313e.c @@ -33,7 +33,9 @@ #define MSC313E_REG_TIMER_MAX_HIGH 0x0c #define MSC313E_REG_COUNTER_LOW 0x10 #define MSC313E_REG_COUNTER_HIGH 0x14 +#define MSC313E_REG_TIMER_DIVIDE 0x18 +#define MSC313E_CLK_DIVIDER 9 #define TIMER_SYNC_TICKS 3 #ifdef CONFIG_ARM @@ -179,6 +181,12 @@ static int __init msc313e_clkevt_init(struct device_node *np) if (ret) return ret; + if (of_device_is_compatible(np, "sstar,ssd20xd-timer")) { + to->of_clk.rate = clk_get_rate(to->of_clk.clk) / MSC313E_CLK_DIVIDER; + to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ); + writew(MSC313E_CLK_DIVIDER - 1, timer_of_base(to) + MSC313E_REG_TIMER_DIVIDE); + } + msc313e_clkevt.cpumask = cpu_possible_mask; msc313e_clkevt.irq = to->of_irq.irq; to->clkevt = msc313e_clkevt; @@ -242,3 +250,4 @@ static int __init msc313e_timer_init(struct device_node *np) } TIMER_OF_DECLARE(msc313, "mstar,msc313e-timer", msc313e_timer_init); +TIMER_OF_DECLARE(ssd20xd, "sstar,ssd20xd-timer", msc313e_timer_init); -- cgit v1.2.3 From 7647204c2e81b28b4a7c4eec7d539f998d48eaf0 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Fri, 17 Dec 2021 20:57:25 +0100 Subject: dt-bindings: timer: Add Mstar MSC313e timer devicetree bindings documentation This adds the documentation for the devicetree bindings of the Mstar MSC313e timer driver, found from MSC313e SoCs and newer. Signed-off-by: Romain Perier Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211217195727.8955-5-romain.perier@gmail.com Signed-off-by: Daniel Lezcano --- .../bindings/timer/mstar,msc313e-timer.yaml | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml diff --git a/Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml b/Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml new file mode 100644 index 000000000000..03d5dba5d5b3 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/mstar,msc313e-timer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mstar MSC313e Timer Device Tree Bindings + +maintainers: + - Daniel Palmer + - Romain Perier + +properties: + compatible: + enum: + - mstar,msc313e-timer + - sstar,ssd20xd-timer + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + + timer@6040 { + compatible = "mstar,msc313e-timer"; + reg = <0x6040 0x40>; + clocks = <&xtal_div2>; + interrupts-extended = <&intc_fiq GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + }; +... -- cgit v1.2.3