1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp>
9 #include <linux/errno.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/clocksource.h>
13 #include <linux/clk.h>
16 #include <linux/of_address.h>
17 #include <linux/of_irq.h>
26 struct clocksource cs
;
27 void __iomem
*mapbase1
;
28 void __iomem
*mapbase2
;
30 unsigned int cs_enabled
;
33 static inline unsigned long read_tcnt32(struct tpu_priv
*p
)
37 tcnt
= ioread16be(p
->mapbase1
+ TCNT
) << 16;
38 tcnt
|= ioread16be(p
->mapbase2
+ TCNT
);
42 static int tpu_get_counter(struct tpu_priv
*p
, unsigned long long *val
)
44 unsigned long v1
, v2
, v3
;
47 o1
= ioread8(p
->mapbase1
+ TSR
) & TCFV
;
49 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
55 o1
= ioread8(p
->mapbase1
+ TSR
) & TCFV
;
56 } while (unlikely((o1
!= o2
) || (v1
> v2
&& v1
< v3
)
57 || (v2
> v3
&& v2
< v1
) || (v3
> v1
&& v3
< v2
)));
63 static inline struct tpu_priv
*cs_to_priv(struct clocksource
*cs
)
65 return container_of(cs
, struct tpu_priv
, cs
);
68 static u64
tpu_clocksource_read(struct clocksource
*cs
)
70 struct tpu_priv
*p
= cs_to_priv(cs
);
72 unsigned long long value
;
74 raw_spin_lock_irqsave(&p
->lock
, flags
);
75 if (tpu_get_counter(p
, &value
))
77 raw_spin_unlock_irqrestore(&p
->lock
, flags
);
82 static int tpu_clocksource_enable(struct clocksource
*cs
)
84 struct tpu_priv
*p
= cs_to_priv(cs
);
86 WARN_ON(p
->cs_enabled
);
88 iowrite16be(0, p
->mapbase1
+ TCNT
);
89 iowrite16be(0, p
->mapbase2
+ TCNT
);
90 iowrite8(0x0f, p
->mapbase1
+ TCR
);
91 iowrite8(0x03, p
->mapbase2
+ TCR
);
97 static void tpu_clocksource_disable(struct clocksource
*cs
)
99 struct tpu_priv
*p
= cs_to_priv(cs
);
101 WARN_ON(!p
->cs_enabled
);
103 iowrite8(0, p
->mapbase1
+ TCR
);
104 iowrite8(0, p
->mapbase2
+ TCR
);
105 p
->cs_enabled
= false;
108 static struct tpu_priv tpu_priv
= {
112 .read
= tpu_clocksource_read
,
113 .enable
= tpu_clocksource_enable
,
114 .disable
= tpu_clocksource_disable
,
115 .mask
= CLOCKSOURCE_MASK(sizeof(unsigned long) * 8),
116 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
123 static int __init
h8300_tpu_init(struct device_node
*node
)
125 void __iomem
*base
[2];
129 clk
= of_clk_get(node
, 0);
131 pr_err("failed to get clock for clocksource\n");
135 base
[CH_L
] = of_iomap(node
, CH_L
);
137 pr_err("failed to map registers for clocksource\n");
140 base
[CH_H
] = of_iomap(node
, CH_H
);
142 pr_err("failed to map registers for clocksource\n");
146 tpu_priv
.mapbase1
= base
[CH_L
];
147 tpu_priv
.mapbase2
= base
[CH_H
];
149 return clocksource_register_hz(&tpu_priv
.cs
, clk_get_rate(clk
) / 64);
158 TIMER_OF_DECLARE(h8300_tpu
, "renesas,tpu", h8300_tpu_init
);