4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp>
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/clocksource.h>
12 #include <linux/clk.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
25 struct clocksource cs
;
26 void __iomem
*mapbase1
;
27 void __iomem
*mapbase2
;
29 unsigned int cs_enabled
;
32 static inline unsigned long read_tcnt32(struct tpu_priv
*p
)
36 tcnt
= ioread16be(p
->mapbase1
+ TCNT
) << 16;
37 tcnt
|= ioread16be(p
->mapbase2
+ TCNT
);
41 static int tpu_get_counter(struct tpu_priv
*p
, unsigned long long *val
)
43 unsigned long v1
, v2
, v3
;
46 o1
= ioread8(p
->mapbase1
+ TSR
) & TCFV
;
48 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
54 o1
= ioread8(p
->mapbase1
+ TSR
) & TCFV
;
55 } while (unlikely((o1
!= o2
) || (v1
> v2
&& v1
< v3
)
56 || (v2
> v3
&& v2
< v1
) || (v3
> v1
&& v3
< v2
)));
62 static inline struct tpu_priv
*cs_to_priv(struct clocksource
*cs
)
64 return container_of(cs
, struct tpu_priv
, cs
);
67 static cycle_t
tpu_clocksource_read(struct clocksource
*cs
)
69 struct tpu_priv
*p
= cs_to_priv(cs
);
71 unsigned long long value
;
73 raw_spin_lock_irqsave(&p
->lock
, flags
);
74 if (tpu_get_counter(p
, &value
))
76 raw_spin_unlock_irqrestore(&p
->lock
, flags
);
81 static int tpu_clocksource_enable(struct clocksource
*cs
)
83 struct tpu_priv
*p
= cs_to_priv(cs
);
85 WARN_ON(p
->cs_enabled
);
87 iowrite16be(0, p
->mapbase1
+ TCNT
);
88 iowrite16be(0, p
->mapbase2
+ TCNT
);
89 iowrite8(0x0f, p
->mapbase1
+ TCR
);
90 iowrite8(0x03, p
->mapbase2
+ TCR
);
96 static void tpu_clocksource_disable(struct clocksource
*cs
)
98 struct tpu_priv
*p
= cs_to_priv(cs
);
100 WARN_ON(!p
->cs_enabled
);
102 iowrite8(0, p
->mapbase1
+ TCR
);
103 iowrite8(0, p
->mapbase2
+ TCR
);
104 p
->cs_enabled
= false;
107 static struct tpu_priv tpu_priv
= {
111 .read
= tpu_clocksource_read
,
112 .enable
= tpu_clocksource_enable
,
113 .disable
= tpu_clocksource_disable
,
114 .mask
= CLOCKSOURCE_MASK(sizeof(unsigned long) * 8),
115 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
122 static int __init
h8300_tpu_init(struct device_node
*node
)
124 void __iomem
*base
[2];
128 clk
= of_clk_get(node
, 0);
130 pr_err("failed to get clock for clocksource\n");
134 base
[CH_L
] = of_iomap(node
, CH_L
);
136 pr_err("failed to map registers for clocksource\n");
139 base
[CH_H
] = of_iomap(node
, CH_H
);
141 pr_err("failed to map registers for clocksource\n");
145 tpu_priv
.mapbase1
= base
[CH_L
];
146 tpu_priv
.mapbase2
= base
[CH_H
];
148 return clocksource_register_hz(&tpu_priv
.cs
, clk_get_rate(clk
) / 64);
157 CLOCKSOURCE_OF_DECLARE(h8300_tpu
, "renesas,tpu", h8300_tpu_init
);