2021-06-28 06:14:59

by Sanil, Shruthi

[permalink] [raw]
Subject: [PATCH v4 0/2] Add the driver for Intel Keem Bay SoC timer block

From: Shruthi Sanil <[email protected]>

The timer block supports 1 64-bit free running counter
and 8 32-bit general purpose timers.

Patch 1 holds the device tree binding documentation.
Patch 2 holds the device driver.

This driver is tested on the Keem Bay evaluation module board.

Changes since v3:
- Update in KConfig file to support COMPILE_TEST for Keem Bay timer.
- Update in device tree bindings to remove status field.
- Update in device tree bindings to remove 64-bit address space for
the child nodes by using non-empty ranges.

Changes since v2:
- Add multi timer support.
- Update in the device tree binding to support multi timers.
- Code optimization.

Changes since v1:
- Add support for KEEMBAY_TIMER to get selected through Kconfig.platforms.
- Add CLOCK_EVT_FEAT_DYNIRQ as part of clockevent feature.
- Avoid overlapping reg regions across 2 device nodes.
- Simplify 2 device nodes as 1 because both are from same IP block.
- Adapt the driver code according to the new simplified devicetree.

Shruthi Sanil (2):
dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer
clocksource: Add Intel Keem Bay timer support

.../bindings/timer/intel,keembay-timer.yaml | 170 ++++++++++++
MAINTAINERS | 5 +
drivers/clocksource/Kconfig | 11 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-keembay.c | 255 ++++++++++++++++++
5 files changed, 442 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
create mode 100644 drivers/clocksource/timer-keembay.c


base-commit: 62fb9874f5da54fdb243003b386128037319b219
--
2.17.1


2021-06-28 06:15:33

by Sanil, Shruthi

[permalink] [raw]
Subject: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

From: Shruthi Sanil <[email protected]>

Add Device Tree bindings for the Timer IP, which can be used as
clocksource and clockevent device in the Intel Keem Bay SoC.

Reviewed-by: Andy Shevchenko <[email protected]>
Signed-off-by: Shruthi Sanil <[email protected]>
---
.../bindings/timer/intel,keembay-timer.yaml | 170 ++++++++++++++++++
1 file changed, 170 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml

diff --git a/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml b/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
new file mode 100644
index 000000000000..24c149a4d220
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/intel,keembay-timer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel Keem Bay SoC Timers
+
+maintainers:
+ - Shruthi Sanil <[email protected]>
+
+description: |
+ The Intel Keem Bay timer driver supports clocksource and clockevent
+ features for the timer IP used in Intel Keembay SoC.
+ The timer block supports 1 free running counter and 8 timers.
+ The free running counter can be used as a clocksouce and
+ the timers can be used as clockevent. Each timer is capable of
+ generating inividual interrupt.
+ Both the features are enabled through the timer general config register.
+
+ The parent node represents the common general configuration details and
+ the child nodes represents the counter and timers.
+
+properties:
+ reg:
+ description: General configuration register address and length.
+ maxItems: 1
+
+ ranges: true
+
+ "#address-cells":
+ const: 2
+
+ "#size-cells":
+ const: 2
+
+required:
+ - reg
+ - ranges
+ - "#address-cells"
+ - "#size-cells"
+
+patternProperties:
+ "^counter@[0-9a-f]+$":
+ type: object
+ description: Properties for Intel Keem Bay counter
+
+ properties:
+ compatible:
+ enum:
+ - intel,keembay-counter
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ required:
+ - compatible
+ - reg
+ - clocks
+
+ "^timer@[0-9a-f]+$":
+ type: object
+ description: Properties for Intel Keem Bay timer
+
+ properties:
+ compatible:
+ enum:
+ - intel,keembay-timer
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #define KEEM_BAY_A53_TIM
+
+ soc {
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ gpt@20331000 {
+ reg = <0x0 0x20331000 0x0 0xc>;
+ ranges = <0x0 0x0 0x20330000 0xF0>;
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+
+ counter@203300e8 {
+ compatible = "intel,keembay-counter";
+ reg = <0xe8 0x8>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330010 {
+ compatible = "intel,keembay-timer";
+ reg = <0x10 0xc>;
+ interrupts = <GIC_SPI 0x3 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330020 {
+ compatible = "intel,keembay-timer";
+ reg = <0x20 0xc>;
+ interrupts = <GIC_SPI 0x4 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330030 {
+ compatible = "intel,keembay-timer";
+ reg = <0x30 0xc>;
+ interrupts = <GIC_SPI 0x5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330040 {
+ compatible = "intel,keembay-timer";
+ reg = <0x40 0xc>;
+ interrupts = <GIC_SPI 0x6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330050 {
+ compatible = "intel,keembay-timer";
+ reg = <0x50 0xc>;
+ interrupts = <GIC_SPI 0x7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330060 {
+ compatible = "intel,keembay-timer";
+ reg = <0x60 0xc>;
+ interrupts = <GIC_SPI 0x8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330070 {
+ compatible = "intel,keembay-timer";
+ reg = <0x70 0xc>;
+ interrupts = <GIC_SPI 0x9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+
+ timer@20330080 {
+ compatible = "intel,keembay-timer";
+ reg = <0x80 0xc>;
+ interrupts = <GIC_SPI 0xa IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
+ };
+ };
+ };
+
+...
--
2.17.1

2021-06-28 06:16:13

by Sanil, Shruthi

[permalink] [raw]
Subject: [PATCH v4 2/2] clocksource: Add Intel Keem Bay timer support

From: Shruthi Sanil <[email protected]>

The Intel Keem Bay timer driver supports clocksource and clockevent
features for the timer IP used in Intel Keem Bay SoC.
The timer block supports 1 free running counter and 8 timers.
The free running counter can be used as a clocksource and
the timers can be used as clockevent. Each timer is capable of
generating individual interrupt.
Both the features are enabled through the timer general config register.

Reviewed-by: Andy Shevchenko <[email protected]>
Signed-off-by: Shruthi Sanil <[email protected]>
---
MAINTAINERS | 5 +
drivers/clocksource/Kconfig | 11 ++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-keembay.c | 255 ++++++++++++++++++++++++++++
4 files changed, 272 insertions(+)
create mode 100644 drivers/clocksource/timer-keembay.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0cce91cd5624..1e7826979064 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9286,6 +9286,11 @@ F: drivers/crypto/keembay/keembay-ocs-hcu-core.c
F: drivers/crypto/keembay/ocs-hcu.c
F: drivers/crypto/keembay/ocs-hcu.h

+INTEL KEEM BAY TIMER SUPPORT
+M: Shruthi Sanil <[email protected]>
+S: Maintained
+F: drivers/clocksource/timer-keembay.c
+
INTEL MANAGEMENT ENGINE (mei)
M: Tomas Winkler <[email protected]>
L: [email protected]
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 39aa21d01e05..70596ec72851 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -693,4 +693,15 @@ config MICROCHIP_PIT64B
modes and high resolution. It is used as a clocksource
and a clockevent.

+config KEEMBAY_TIMER
+ bool "Intel Keem Bay timer"
+ depends on ARCH_KEEMBAY || COMPILE_TEST
+ select TIMER_OF
+ help
+ This option enables the support for the Intel Keem Bay
+ general purpose timer and free running counter driver.
+ Each timer can generate an individual interrupt and
+ supports oneshot and periodic modes.
+ The 64-bit counter can be used as a clock source.
+
endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c17ee32a7151..ea319063ba47 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_KEEMBAY_TIMER) += timer-keembay.o
diff --git a/drivers/clocksource/timer-keembay.c b/drivers/clocksource/timer-keembay.c
new file mode 100644
index 000000000000..e62187eeb4f6
--- /dev/null
+++ b/drivers/clocksource/timer-keembay.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel Keem Bay Timer driver
+ *
+ * Copyright (C) 2020 Intel Corporation
+ */
+
+#include <linux/bitops.h>
+#include <linux/idr.h>
+#include <linux/interrupt.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+
+#include "timer-of.h"
+
+/* Timer register offset */
+#define TIM_CNT_VAL_OFFSET 0x0
+#define TIM_RELOAD_VAL_OFFSET 0x4
+#define TIM_CONFIG_OFFSET 0x8
+
+/* Bit fields of timer general config register */
+#define TIM_CONFIG_PRESCALER_ENABLE BIT(2)
+#define TIM_CONFIG_COUNTER_ENABLE BIT(0)
+
+/* Bit fields of timer config register */
+#define TIM_CONFIG_INTERRUPT_PENDING BIT(4)
+#define TIM_CONFIG_INTERRUPT_ENABLE BIT(2)
+#define TIM_CONFIG_RESTART BIT(1)
+#define TIM_CONFIG_ENABLE BIT(0)
+
+#define TIM_GEN_MASK GENMASK(31, 12)
+#define TIM_RATING 200
+#define TIM_CLKSRC_MASK_BITS 64
+
+#define TIMER_NAME_SIZE 25
+
+/* Provides a unique ID for each timer */
+static DEFINE_IDA(keembay_timer_ida);
+
+static inline void keembay_timer_enable(void __iomem *base, u32 flags)
+{
+ writel(TIM_CONFIG_ENABLE | flags, base + TIM_CONFIG_OFFSET);
+}
+
+static inline void keembay_timer_disable(void __iomem *base)
+{
+ writel(0x0, base + TIM_CONFIG_OFFSET);
+}
+
+static inline void keembay_timer_update_counter(void __iomem *base, u32 val)
+{
+ writel(val, base + TIM_CNT_VAL_OFFSET);
+ writel(val, base + TIM_RELOAD_VAL_OFFSET);
+}
+
+static inline void keembay_timer_clear_pending_int(void __iomem *base)
+{
+ u32 val;
+
+ val = readl(base + TIM_CONFIG_OFFSET);
+ val &= ~TIM_CONFIG_INTERRUPT_PENDING;
+ writel(val, base + TIM_CONFIG_OFFSET);
+}
+
+static int keembay_timer_set_next_event(unsigned long evt, struct clock_event_device *ce)
+{
+ u32 flags = TIM_CONFIG_INTERRUPT_ENABLE;
+ struct timer_of *to = to_timer_of(ce);
+ void __iomem *tim_base = timer_of_base(to);
+
+ keembay_timer_disable(tim_base);
+ keembay_timer_update_counter(tim_base, evt);
+ keembay_timer_enable(tim_base, flags);
+
+ return 0;
+}
+
+static int keembay_timer_periodic(struct clock_event_device *ce)
+{
+ u32 flags = TIM_CONFIG_INTERRUPT_ENABLE | TIM_CONFIG_RESTART;
+ struct timer_of *to = to_timer_of(ce);
+ void __iomem *tim_base = timer_of_base(to);
+
+ keembay_timer_disable(tim_base);
+ keembay_timer_update_counter(tim_base, timer_of_period(to));
+ keembay_timer_enable(tim_base, flags);
+
+ return 0;
+}
+
+static int keembay_timer_shutdown(struct clock_event_device *ce)
+{
+ struct timer_of *to = to_timer_of(ce);
+
+ keembay_timer_disable(timer_of_base(to));
+
+ return 0;
+}
+
+static irqreturn_t keembay_timer_isr(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+ struct timer_of *to = to_timer_of(evt);
+ void __iomem *tim_base = timer_of_base(to);
+ u32 val;
+
+ val = readl(tim_base + TIM_CONFIG_OFFSET);
+
+ if (val & TIM_CONFIG_RESTART) {
+ /* Clear interrupt for periodic timer*/
+ keembay_timer_clear_pending_int(tim_base);
+ } else {
+ /* Disable the timer for one shot timer */
+ keembay_timer_disable(tim_base);
+ }
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static int __init keembay_clockevent_init(struct device_node *np)
+{
+ struct device_node *gpt_node = np->parent;
+ struct timer_of *keembay_ce_to;
+ void __iomem *gpt_base;
+ char *timer_name;
+ int timer_id;
+ int ret;
+ u32 val;
+
+ gpt_base = of_iomap(gpt_node, 0);
+ if (!gpt_base) {
+ pr_err("%pOF: Failed to get general config base address\n", np);
+ return -ENXIO;
+ }
+
+ /* Prescaler must be enabled for the timer to operate */
+ val = readl(gpt_base + TIM_CONFIG_OFFSET);
+ if (!(val & TIM_CONFIG_PRESCALER_ENABLE)) {
+ pr_err("%pOF: Prescaler is not enabled\n", np);
+ ret = -ENODEV;
+ goto err_iounmap;
+ }
+
+ keembay_ce_to = kzalloc(sizeof(*keembay_ce_to), GFP_KERNEL);
+ if (!keembay_ce_to) {
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+
+ timer_id = ida_alloc(&keembay_timer_ida, GFP_KERNEL);
+ if (timer_id < 0) {
+ ret = timer_id;
+ goto err_keembay_ce_to_free;
+ }
+
+ timer_name = kasprintf(GFP_KERNEL, "keembay_timer%d", timer_id);
+ if (!timer_name) {
+ ret = -ENOMEM;
+ goto err_free_ida;
+ }
+
+ keembay_ce_to->flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK;
+ keembay_ce_to->clkevt.name = timer_name;
+ keembay_ce_to->clkevt.cpumask = cpumask_of(0);
+ keembay_ce_to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_DYNIRQ;
+ keembay_ce_to->clkevt.rating = TIM_RATING;
+ keembay_ce_to->clkevt.set_next_event = keembay_timer_set_next_event;
+ keembay_ce_to->clkevt.set_state_periodic = keembay_timer_periodic;
+ keembay_ce_to->clkevt.set_state_shutdown = keembay_timer_shutdown;
+ keembay_ce_to->of_irq.handler = keembay_timer_isr;
+ keembay_ce_to->of_irq.flags = IRQF_TIMER;
+
+ ret = timer_of_init(np, keembay_ce_to);
+ if (ret)
+ goto err_timer_name_free;
+
+ val = readl(gpt_base + TIM_RELOAD_VAL_OFFSET);
+ iounmap(gpt_base);
+
+ keembay_ce_to->of_clk.rate = keembay_ce_to->of_clk.rate / (val + 1);
+
+ clockevents_config_and_register(&keembay_ce_to->clkevt,
+ timer_of_rate(keembay_ce_to),
+ 1,
+ U32_MAX);
+
+ return 0;
+
+err_timer_name_free:
+ kfree(timer_name);
+err_free_ida:
+ ida_free(&keembay_timer_ida, timer_id);
+err_keembay_ce_to_free:
+ kfree(keembay_ce_to);
+err_iounmap:
+ iounmap(gpt_base);
+
+ return ret;
+}
+
+static struct timer_of keembay_cs_to = {
+ .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
+};
+
+static u64 notrace keembay_clocksource_read(struct clocksource *cs)
+{
+ return lo_hi_readq(timer_of_base(&keembay_cs_to));
+}
+
+static struct clocksource keembay_counter = {
+ .name = "keembay_sys_counter",
+ .rating = TIM_RATING,
+ .read = keembay_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(TIM_CLKSRC_MASK_BITS),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ CLOCK_SOURCE_SUSPEND_NONSTOP,
+};
+
+static int __init keembay_clocksource_init(struct device_node *np)
+{
+ struct device_node *gpt_node = np->parent;
+ void __iomem *gpt_base;
+ u32 val;
+ int ret;
+
+ gpt_base = of_iomap(gpt_node, 0);
+ if (!gpt_base) {
+ pr_err("%pOF: Failed to get general config base address\n", np);
+ return -ENXIO;
+ }
+
+ /* Free Running Counter must be enabled */
+ val = readl(gpt_base + TIM_CONFIG_OFFSET);
+ iounmap(gpt_base);
+ if (!(val & TIM_CONFIG_COUNTER_ENABLE)) {
+ pr_err("%pOF: free running counter is not enabled\n", np);
+ return -ENODEV;
+ }
+
+ ret = timer_of_init(np, &keembay_cs_to);
+ if (ret)
+ return ret;
+
+ return clocksource_register_hz(&keembay_counter, timer_of_rate(&keembay_cs_to));
+}
+
+TIMER_OF_DECLARE(keembay_clockevent, "intel,keembay-timer", keembay_clockevent_init);
+TIMER_OF_DECLARE(keembay_clocksource, "intel,keembay-counter", keembay_clocksource_init);
--
2.17.1

2021-07-13 05:10:10

by Sanil, Shruthi

[permalink] [raw]
Subject: RE: [PATCH v4 0/2] Add the driver for Intel Keem Bay SoC timer block

Gentle Reminder!

Regards,
Shruthi

> -----Original Message-----
> From: Sanil, Shruthi <[email protected]>
> Sent: Monday, June 28, 2021 11:44 AM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Cc: [email protected]; [email protected];
> [email protected]; Thokala, Srikanth <[email protected]>;
> Raja Subramanian, Lakshmi Bai <[email protected]>;
> Sangannavar, Mallikarjunappa <[email protected]>;
> Sanil, Shruthi <[email protected]>
> Subject: [PATCH v4 0/2] Add the driver for Intel Keem Bay SoC timer block
>
> From: Shruthi Sanil <[email protected]>
>
> The timer block supports 1 64-bit free running counter and 8 32-bit general
> purpose timers.
>
> Patch 1 holds the device tree binding documentation.
> Patch 2 holds the device driver.
>
> This driver is tested on the Keem Bay evaluation module board.
>
> Changes since v3:
> - Update in KConfig file to support COMPILE_TEST for Keem Bay timer.
> - Update in device tree bindings to remove status field.
> - Update in device tree bindings to remove 64-bit address space for
> the child nodes by using non-empty ranges.
>
> Changes since v2:
> - Add multi timer support.
> - Update in the device tree binding to support multi timers.
> - Code optimization.
>
> Changes since v1:
> - Add support for KEEMBAY_TIMER to get selected through
> Kconfig.platforms.
> - Add CLOCK_EVT_FEAT_DYNIRQ as part of clockevent feature.
> - Avoid overlapping reg regions across 2 device nodes.
> - Simplify 2 device nodes as 1 because both are from same IP block.
> - Adapt the driver code according to the new simplified devicetree.
>
> Shruthi Sanil (2):
> dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer
> clocksource: Add Intel Keem Bay timer support
>
> .../bindings/timer/intel,keembay-timer.yaml | 170 ++++++++++++
> MAINTAINERS | 5 +
> drivers/clocksource/Kconfig | 11 +
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/timer-keembay.c | 255 ++++++++++++++++++
> 5 files changed, 442 insertions(+)
> create mode 100644
> Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
> create mode 100644 drivers/clocksource/timer-keembay.c
>
>
> base-commit: 62fb9874f5da54fdb243003b386128037319b219
> --
> 2.17.1

2021-07-14 02:49:45

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

On Mon, Jun 28, 2021 at 11:44:09AM +0530, [email protected] wrote:
> From: Shruthi Sanil <[email protected]>
>
> Add Device Tree bindings for the Timer IP, which can be used as
> clocksource and clockevent device in the Intel Keem Bay SoC.
>
> Reviewed-by: Andy Shevchenko <[email protected]>
> Signed-off-by: Shruthi Sanil <[email protected]>
> ---
> .../bindings/timer/intel,keembay-timer.yaml | 170 ++++++++++++++++++
> 1 file changed, 170 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
>
> diff --git a/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml b/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
> new file mode 100644
> index 000000000000..24c149a4d220
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/intel,keembay-timer.yaml
> @@ -0,0 +1,170 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/timer/intel,keembay-timer.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Intel Keem Bay SoC Timers
> +
> +maintainers:
> + - Shruthi Sanil <[email protected]>
> +
> +description: |
> + The Intel Keem Bay timer driver supports clocksource and clockevent
> + features for the timer IP used in Intel Keembay SoC.
> + The timer block supports 1 free running counter and 8 timers.
> + The free running counter can be used as a clocksouce and
> + the timers can be used as clockevent. Each timer is capable of
> + generating inividual interrupt.

clockevent and clocksource are Linuxisms. Don't use them in bindings.

> + Both the features are enabled through the timer general config register.
> +
> + The parent node represents the common general configuration details and
> + the child nodes represents the counter and timers.

I don't think all the child nodes are necessary. Are the counters and
timers configurable (say on another SoC)? If not, then a single node
here would suffice.

> +
> +properties:
> + reg:
> + description: General configuration register address and length.
> + maxItems: 1
> +
> + ranges: true
> +
> + "#address-cells":
> + const: 2
> +
> + "#size-cells":
> + const: 2
> +
> +required:
> + - reg
> + - ranges
> + - "#address-cells"
> + - "#size-cells"
> +
> +patternProperties:
> + "^counter@[0-9a-f]+$":
> + type: object
> + description: Properties for Intel Keem Bay counter
> +
> + properties:
> + compatible:
> + enum:
> + - intel,keembay-counter
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + required:
> + - compatible
> + - reg
> + - clocks
> +
> + "^timer@[0-9a-f]+$":
> + type: object
> + description: Properties for Intel Keem Bay timer
> +
> + properties:
> + compatible:
> + enum:
> + - intel,keembay-timer
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + required:
> + - compatible
> + - reg
> + - interrupts
> + - clocks
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + #define KEEM_BAY_A53_TIM
> +
> + soc {
> + #address-cells = <0x2>;
> + #size-cells = <0x2>;
> +
> + gpt@20331000 {
> + reg = <0x0 0x20331000 0x0 0xc>;
> + ranges = <0x0 0x0 0x20330000 0xF0>;
> + #address-cells = <0x1>;
> + #size-cells = <0x1>;
> +
> + counter@203300e8 {

The unit address here is wrong. Should be 'e8'.

> + compatible = "intel,keembay-counter";
> + reg = <0xe8 0x8>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330010 {
> + compatible = "intel,keembay-timer";
> + reg = <0x10 0xc>;
> + interrupts = <GIC_SPI 0x3 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330020 {
> + compatible = "intel,keembay-timer";
> + reg = <0x20 0xc>;
> + interrupts = <GIC_SPI 0x4 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330030 {
> + compatible = "intel,keembay-timer";
> + reg = <0x30 0xc>;
> + interrupts = <GIC_SPI 0x5 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330040 {
> + compatible = "intel,keembay-timer";
> + reg = <0x40 0xc>;
> + interrupts = <GIC_SPI 0x6 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330050 {
> + compatible = "intel,keembay-timer";
> + reg = <0x50 0xc>;
> + interrupts = <GIC_SPI 0x7 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330060 {
> + compatible = "intel,keembay-timer";
> + reg = <0x60 0xc>;
> + interrupts = <GIC_SPI 0x8 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330070 {
> + compatible = "intel,keembay-timer";
> + reg = <0x70 0xc>;
> + interrupts = <GIC_SPI 0x9 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> +
> + timer@20330080 {
> + compatible = "intel,keembay-timer";
> + reg = <0x80 0xc>;
> + interrupts = <GIC_SPI 0xa IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&scmi_clk KEEM_BAY_A53_TIM>;
> + };
> + };
> + };
> +
> +...
> --
> 2.17.1
>
>

2021-07-14 09:05:29

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

On Tue, Jul 13, 2021 at 08:47:56PM -0600, Rob Herring wrote:
> On Mon, Jun 28, 2021 at 11:44:09AM +0530, [email protected] wrote:

> > + The parent node represents the common general configuration details and
> > + the child nodes represents the counter and timers.
>
> I don't think all the child nodes are necessary. Are the counters and
> timers configurable (say on another SoC)? If not, then a single node
> here would suffice.

If you may notice the children may have different properties that can't be
known ahead, such as IRQ line. On some platforms it may be this mapping, on
another it maybe different.

With all respect for the simplification I think we can't do it here.

--
With Best Regards,
Andy Shevchenko


2021-07-14 14:09:38

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

On Wed, Jul 14, 2021 at 3:04 AM Andy Shevchenko
<[email protected]> wrote:
>
> On Tue, Jul 13, 2021 at 08:47:56PM -0600, Rob Herring wrote:
> > On Mon, Jun 28, 2021 at 11:44:09AM +0530, [email protected] wrote:
>
> > > + The parent node represents the common general configuration details and
> > > + the child nodes represents the counter and timers.
> >
> > I don't think all the child nodes are necessary. Are the counters and
> > timers configurable (say on another SoC)? If not, then a single node
> > here would suffice.
>
> If you may notice the children may have different properties that can't be
> known ahead, such as IRQ line. On some platforms it may be this mapping, on
> another it maybe different.

What I noticed is it's all the same clock and 1 interrupt for each
timer can be just a single 'interrupts' property with 8 entries.

Is there a platform that's different or that's a hypothetical? Because
hypothetically, every aspect of every IP could change. But we don't
try to parameterize everything in DT. It's a judgement call between
implying things from compatible and explicit DT properties.

> With all respect for the simplification I think we can't do it here.

You can. Any data in DT could be in the kernel. It's a question of
balance, not can or can't.

Rob

2021-07-14 14:23:19

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

On Wed, Jul 14, 2021 at 08:07:44AM -0600, Rob Herring wrote:
> On Wed, Jul 14, 2021 at 3:04 AM Andy Shevchenko
> <[email protected]> wrote:
> > On Tue, Jul 13, 2021 at 08:47:56PM -0600, Rob Herring wrote:
> > > On Mon, Jun 28, 2021 at 11:44:09AM +0530, [email protected] wrote:
> >
> > > > + The parent node represents the common general configuration details and
> > > > + the child nodes represents the counter and timers.
> > >
> > > I don't think all the child nodes are necessary. Are the counters and
> > > timers configurable (say on another SoC)? If not, then a single node
> > > here would suffice.
> >
> > If you may notice the children may have different properties that can't be
> > known ahead, such as IRQ line. On some platforms it may be this mapping, on
> > another it maybe different.
>
> What I noticed is it's all the same clock and 1 interrupt for each
> timer can be just a single 'interrupts' property with 8 entries.

This may work.

> Is there a platform that's different or that's a hypothetical? Because
> hypothetically, every aspect of every IP could change. But we don't
> try to parameterize everything in DT. It's a judgement call between
> implying things from compatible and explicit DT properties.
>
> > With all respect for the simplification I think we can't do it here.
>
> You can. Any data in DT could be in the kernel. It's a question of
> balance, not can or can't.

Not only, it's also matters of what exactly hardware is: 8 timers or timer with
8 channels. If it's the former one, I prefer to have DT exactly like originally
suggested, otherwise I will agree on your proposal.

--
With Best Regards,
Andy Shevchenko


2021-07-15 10:46:40

by Sanil, Shruthi

[permalink] [raw]
Subject: RE: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

> -----Original Message-----
> From: Andy Shevchenko <[email protected]>
> Sent: Wednesday, July 14, 2021 7:51 PM
> To: Rob Herring <[email protected]>
> Cc: Sanil, Shruthi <[email protected]>; Daniel Lezcano
> <[email protected]>; Thomas Gleixner <[email protected]>; linux-
> [email protected]; [email protected];
> [email protected]; Mark Gross <[email protected]>; Thokala,
> Srikanth <[email protected]>; Raja Subramanian, Lakshmi Bai
> <[email protected]>; Sangannavar, Mallikarjunappa
> <[email protected]>
> Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem
> Bay SoC Timer
>
> On Wed, Jul 14, 2021 at 08:07:44AM -0600, Rob Herring wrote:
> > On Wed, Jul 14, 2021 at 3:04 AM Andy Shevchenko
> > <[email protected]> wrote:
> > > On Tue, Jul 13, 2021 at 08:47:56PM -0600, Rob Herring wrote:
> > > > On Mon, Jun 28, 2021 at 11:44:09AM +0530, [email protected]
> wrote:
> > >
> > > > > + The parent node represents the common general configuration
> > > > > + details and the child nodes represents the counter and timers.
> > > >
> > > > I don't think all the child nodes are necessary. Are the counters
> > > > and timers configurable (say on another SoC)? If not, then a
> > > > single node here would suffice.
> > >
> > > If you may notice the children may have different properties that
> > > can't be known ahead, such as IRQ line. On some platforms it may be
> > > this mapping, on another it maybe different.
> >
> > What I noticed is it's all the same clock and 1 interrupt for each
> > timer can be just a single 'interrupts' property with 8 entries.
>
> This may work.
>
> > Is there a platform that's different or that's a hypothetical? Because
> > hypothetically, every aspect of every IP could change. But we don't
> > try to parameterize everything in DT. It's a judgement call between
> > implying things from compatible and explicit DT properties.
> >
> > > With all respect for the simplification I think we can't do it here.
> >
> > You can. Any data in DT could be in the kernel. It's a question of
> > balance, not can or can't.
>
> Not only, it's also matters of what exactly hardware is: 8 timers or timer with
> 8 channels. If it's the former one, I prefer to have DT exactly like originally
> suggested, otherwise I will agree on your proposal.

Yes Andy, its correct, we have 8 timers in the hardware which are independent.
Also the timer framework provides option to parse all the device tree details. In this case we would pass the timer node to the framework and get the base, IRQ and clock. If we go for a single node approach then all these need to be handled in the driver, hence making it complicated.

Regards,
Shruthi

>
> --
> With Best Regards,
> Andy Shevchenko
>

2021-07-22 10:00:15

by Sanil, Shruthi

[permalink] [raw]
Subject: RE: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem Bay SoC Timer

> -----Original Message-----
> From: Sanil, Shruthi
> Sent: Thursday, July 15, 2021 1:32 PM
> To: Andy Shevchenko <[email protected]>; Rob Herring
> <[email protected]>
> Cc: Daniel Lezcano <[email protected]>; Thomas Gleixner
> <[email protected]>; [email protected];
> [email protected]; [email protected]; Mark Gross
> <[email protected]>; Thokala, Srikanth <[email protected]>;
> Raja Subramanian, Lakshmi Bai <[email protected]>;
> Sangannavar, Mallikarjunappa <[email protected]>
> Subject: RE: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel Keem
> Bay SoC Timer
>
> > -----Original Message-----
> > From: Andy Shevchenko <[email protected]>
> > Sent: Wednesday, July 14, 2021 7:51 PM
> > To: Rob Herring <[email protected]>
> > Cc: Sanil, Shruthi <[email protected]>; Daniel Lezcano
> > <[email protected]>; Thomas Gleixner <[email protected]>;
> > linux- [email protected]; [email protected];
> > [email protected]; Mark Gross <[email protected]>;
> > Thokala, Srikanth <[email protected]>; Raja Subramanian,
> > Lakshmi Bai <[email protected]>; Sangannavar,
> > Mallikarjunappa <[email protected]>
> > Subject: Re: [PATCH v4 1/2] dt-bindings: timer: Add bindings for Intel
> > Keem Bay SoC Timer
> >
> > On Wed, Jul 14, 2021 at 08:07:44AM -0600, Rob Herring wrote:
> > > On Wed, Jul 14, 2021 at 3:04 AM Andy Shevchenko
> > > <[email protected]> wrote:
> > > > On Tue, Jul 13, 2021 at 08:47:56PM -0600, Rob Herring wrote:
> > > > > On Mon, Jun 28, 2021 at 11:44:09AM +0530,
> > > > > [email protected]
> > wrote:
> > > >
> > > > > > + The parent node represents the common general configuration
> > > > > > + details and the child nodes represents the counter and timers.
> > > > >
> > > > > I don't think all the child nodes are necessary. Are the
> > > > > counters and timers configurable (say on another SoC)? If not,
> > > > > then a single node here would suffice.
> > > >
> > > > If you may notice the children may have different properties that
> > > > can't be known ahead, such as IRQ line. On some platforms it may
> > > > be this mapping, on another it maybe different.
> > >
> > > What I noticed is it's all the same clock and 1 interrupt for each
> > > timer can be just a single 'interrupts' property with 8 entries.
> >
> > This may work.
> >
> > > Is there a platform that's different or that's a hypothetical?
> > > Because hypothetically, every aspect of every IP could change. But
> > > we don't try to parameterize everything in DT. It's a judgement call
> > > between implying things from compatible and explicit DT properties.
> > >
> > > > With all respect for the simplification I think we can't do it here.
> > >
> > > You can. Any data in DT could be in the kernel. It's a question of
> > > balance, not can or can't.
> >
> > Not only, it's also matters of what exactly hardware is: 8 timers or
> > timer with
> > 8 channels. If it's the former one, I prefer to have DT exactly like
> > originally suggested, otherwise I will agree on your proposal.
>
> Yes Andy, its correct, we have 8 timers in the hardware which are
> independent.
> Also the timer framework provides option to parse all the device tree details.
> In this case we would pass the timer node to the framework and get the
> base, IRQ and clock. If we go for a single node approach then all these need
> to be handled in the driver, hence making it complicated.
>

Hi Rob,
Yes, the counter and timers are configurable on another SoC. Do you give a nod on the current design?
Shall I proceed with submitting the next version addressing the other 2 comments of yours regarding the description and the unit address update?

> Regards,
> Shruthi
>
> >
> > --
> > With Best Regards,
> > Andy Shevchenko
> >