diff mbox

[3/6] ARM: bcm476x: Add sched clock

Message ID 20121007015406.809888002@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Domenico Andreoli Oct. 7, 2012, 1:53 a.m. UTC
From: Domenico Andreoli <domenico.andreoli@linux.com>

Sched clock implementation based on the BCM476x's free runner counter.

Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
 Documentation/devicetree/bindings/timer/brcm,bcm476x-sched-clock.txt |   18 +++
 arch/arm/boot/dts/bcm476x.dtsi                                       |    6 +
 drivers/clocksource/bcm476x_timer.c                                  |   52 ++++++++++
 3 files changed, 76 insertions(+)

Comments

Stephen Warren Oct. 9, 2012, 2:54 a.m. UTC | #1
On 10/06/2012 07:53 PM, Domenico Andreoli wrote:
> Sched clock implementation based on the BCM476x's free runner counter.

> Index: b/Documentation/devicetree/bindings/timer/brcm,bcm476x-sched-clock.txt
> ===================================================================
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/brcm,bcm476x-sched-clock.txt
> @@ -0,0 +1,18 @@
> +BCM476x Sched clock
> +
> +The BCM476x provides a 63-bit free running counter driven by a separate
> +32KHz clock line.

Is "sched clock" really the name of the HW module in the Broadcom
documentation (well, assuming you have any access to that). DT names
should derived from HW manuals/... where possible.
diff mbox

Patch

Index: b/Documentation/devicetree/bindings/timer/brcm,bcm476x-sched-clock.txt
===================================================================
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/brcm,bcm476x-sched-clock.txt
@@ -0,0 +1,18 @@ 
+BCM476x Sched clock
+
+The BCM476x provides a 63-bit free running counter driven by a separate
+32KHz clock line.
+
+Required properties:
+
+- compatible : should be "brcm,bcm476x-sched-clock"
+- reg : Specifies base physical address and size of the registers.
+- clock-frequency : The frequency of the clock that drives the counter, in Hz.
+
+Example:
+
+sched-clock {
+	compatible = "brcm,bcm476x-sched-clock";
+	reg = <0xbc000 0x1000>;
+	clock-frequency = <32000>;
+};
Index: b/drivers/clocksource/bcm476x_timer.c
===================================================================
--- a/drivers/clocksource/bcm476x_timer.c
+++ b/drivers/clocksource/bcm476x_timer.c
@@ -54,6 +54,21 @@  struct bcm476x_timer {
 	struct irqaction act;
 };
 
+static void __iomem *system_clock __read_mostly;
+
+static u32 notrace bcm476x_sched_read(void)
+{
+	u32 hi, lo;
+
+	/* access to the counter must happen in the lo-hi order even if
+	 * only the lower 32-bit part is of interest
+	 */
+	lo = readl(system_clock);
+	hi = readl(system_clock + 4);
+
+	return lo;
+}
+
 static inline void __iomem *to_load(struct bcm476x_timer *timer)
 {
 	return timer->base + TIMER_LOAD_OFFSET;
@@ -131,6 +146,42 @@  static irqreturn_t bcm476x_timer_interru
 	return IRQ_HANDLED;
 }
 
+static struct of_device_id bcm476x_sched_clock_match[] __initconst = {
+	{ .compatible = "brcm,bcm476x-sched-clock" },
+	{}
+};
+
+static void __init bcm476x_sched_clock_init(void)
+{
+	struct device_node *node;
+	void __iomem *base;
+	u32 freq;
+
+	node = of_find_matching_node(NULL, bcm476x_sched_clock_match);
+	if (!node) {
+		pr_info("No bcm476x sched clock node");
+		return;
+	}
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("Can't remap sched clock registers");
+		return;
+	}
+
+	if (of_property_read_u32(node, "clock-frequency", &freq)) {
+		pr_err("Can't read sched clock frequency");
+		return;
+	}
+	if (freq != 32000) {
+		pr_err("Invalid sched clock frequency");
+		return;
+	}
+
+	system_clock = base;
+	setup_sched_clock(bcm476x_sched_read, 32, freq);
+}
+
 static struct of_device_id bcm476x_timer_match[] __initconst = {
 	{ .compatible = "brcm,bcm476x-system-timer" },
 	{}
@@ -180,6 +231,7 @@  static void __init bcm476x_timer_init(vo
 	if (setup_irq(irq, &timer->act))
 		panic("Can't set up timer IRQ\n");
 
+	bcm476x_sched_clock_init();
 	clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
 }
 
Index: b/arch/arm/boot/dts/bcm476x.dtsi
===================================================================
--- a/arch/arm/boot/dts/bcm476x.dtsi
+++ b/arch/arm/boot/dts/bcm476x.dtsi
@@ -22,6 +22,12 @@ 
 			clock-frequency = <24000000>;
 		};
 
+		sched-clock {
+			compatible = "brcm,bcm476x-sched-clock";
+			reg = <0xbc000 0x1000>;
+			clock-frequency = <32000>;
+		};
+
 		vic0: interrupt-controller@80000 {
 			compatible = "brcm,bcm476x-pl192", "arm,pl192-vic", "arm,primecell";
 			reg = <0x80000 0x1000>;