2 * Copyright 2013-2015 John Wehle <john@feith.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Amlogic aml8726 RTC driver.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <sys/clock.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/resource.h>
47 #include <machine/bus.h>
48 #include <machine/cpu.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
53 #include <arm/amlogic/aml8726/aml8726_soc.h>
58 * The RTC initialization various slightly between the different chips.
60 * aml8726-m1 aml8726-m3 aml8726-m6 (and later)
61 * init-always true true false
62 * xo-init 0x0004 0x3c0a 0x180a
63 * gpo-init 0x100000 0x100000 0x500000
66 struct aml8726_rtc_init {
72 struct aml8726_rtc_softc {
74 struct aml8726_rtc_init init;
75 struct resource * res[2];
79 static struct resource_spec aml8726_rtc_spec[] = {
80 { SYS_RES_MEMORY, 0, RF_ACTIVE },
81 { SYS_RES_IRQ, 0, RF_ACTIVE },
85 #define AML_RTC_LOCK(sc) mtx_lock_spin(&(sc)->mtx)
86 #define AML_RTC_UNLOCK(sc) mtx_unlock_spin(&(sc)->mtx)
87 #define AML_RTC_LOCK_INIT(sc) \
88 mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
90 #define AML_RTC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx);
92 #define AML_RTC_0_REG 0
93 #define AML_RTC_SCLK (1 << 0)
94 #define AML_RTC_SDI (1 << 2)
95 #define AML_RTC_SEN (1 << 1)
96 #define AML_RTC_AS (1 << 17)
97 #define AML_RTC_ABSY (1 << 22)
98 #define AML_RTC_IRQ_DIS (1 << 12)
99 #define AML_RTC_1_REG 4
100 #define AML_RTC_SDO (1 << 0)
101 #define AML_RTC_SRDY (1 << 1)
102 #define AML_RTC_2_REG 8
103 #define AML_RTC_3_REG 12
104 #define AML_RTC_MSR_BUSY (1 << 20)
105 #define AML_RTC_MSR_CA (1 << 17)
106 #define AML_RTC_MSR_DURATION_EN (1 << 16)
107 #define AML_RTC_MSR_DURATION_MASK 0xffff
108 #define AML_RTC_MSR_DURATION_SHIFT 0
109 #define AML_RTC_4_REG 16
111 #define AML_RTC_TIME_SREG 0
112 #define AML_RTC_GPO_SREG 1
113 #define AML_RTC_GPO_LEVEL (1 << 24)
114 #define AML_RTC_GPO_BUSY (1 << 23)
115 #define AML_RTC_GPO_ACTIVE_HIGH (1 << 22)
116 #define AML_RTC_GPO_CMD_MASK (3 << 20)
117 #define AML_RTC_GPO_CMD_SHIFT 20
118 #define AML_RTC_GPO_CMD_NOW (1 << 20)
119 #define AML_RTC_GPO_CMD_COUNT (2 << 20)
120 #define AML_RTC_GPO_CMD_PULSE (3 << 20)
121 #define AML_RTC_GPO_CNT_MASK 0xfffff
122 #define AML_RTC_GPO_CNT_SHIFT 0
124 #define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val))
125 #define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg)
126 #define CSR_BARRIER(sc, reg) bus_barrier((sc)->res[0], reg, 4, \
127 (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE))
130 aml8726_rtc_start_transfer(struct aml8726_rtc_softc *sc)
134 /* idle the serial interface */
135 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
136 ~(AML_RTC_SCLK | AML_RTC_SEN | AML_RTC_SDI)));
138 CSR_BARRIER(sc, AML_RTC_0_REG);
140 /* see if it is ready for a new cycle */
141 for (i = 40; i; i--) {
143 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
150 /* start the cycle */
151 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
158 aml8726_rtc_sclk_pulse(struct aml8726_rtc_softc *sc)
163 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
166 CSR_BARRIER(sc, AML_RTC_0_REG);
170 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
173 CSR_BARRIER(sc, AML_RTC_0_REG);
177 aml8726_rtc_send_bit(struct aml8726_rtc_softc *sc, unsigned bit)
181 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
184 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
188 aml8726_rtc_sclk_pulse(sc);
192 aml8726_rtc_send_addr(struct aml8726_rtc_softc *sc, u_char addr)
196 for (mask = 1 << 3; mask; mask >>= 1) {
198 /* final bit indicates read / write mode */
199 CSR_WRITE_4(sc, AML_RTC_0_REG,
200 (CSR_READ_4(sc, AML_RTC_0_REG) & ~AML_RTC_SEN));
202 aml8726_rtc_send_bit(sc, (addr & mask));
207 aml8726_rtc_send_data(struct aml8726_rtc_softc *sc, uint32_t data)
211 for (mask = 1U << 31; mask; mask >>= 1)
212 aml8726_rtc_send_bit(sc, (data & mask));
216 aml8726_rtc_recv_data(struct aml8726_rtc_softc *sc, uint32_t *dp)
223 for (i = 0; i < 32; i++) {
224 aml8726_rtc_sclk_pulse(sc);
226 data |= (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SDO) ? 1 : 0;
233 aml8726_rtc_sreg_read(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t *val)
238 /* read is indicated by lsb = 0 */
239 addr = (sreg << 1) | 0;
241 error = aml8726_rtc_start_transfer(sc);
246 aml8726_rtc_send_addr(sc, addr);
247 aml8726_rtc_recv_data(sc, val);
253 aml8726_rtc_sreg_write(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t val)
258 /* write is indicated by lsb = 1 */
259 addr = (sreg << 1) | 1;
261 error = aml8726_rtc_start_transfer(sc);
266 aml8726_rtc_send_data(sc, val);
267 aml8726_rtc_send_addr(sc, addr);
273 aml8726_rtc_initialize(struct aml8726_rtc_softc *sc)
278 /* idle the serial interface */
279 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
280 ~(AML_RTC_SCLK | AML_RTC_SEN | AML_RTC_SDI)));
282 CSR_BARRIER(sc, AML_RTC_0_REG);
284 /* see if it is ready for a new cycle */
285 for (i = 40; i; i--) {
287 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
291 if (sc->init.always == TRUE || (CSR_READ_4(sc, AML_RTC_1_REG) &
292 AML_RTC_SRDY) == 0) {
295 * The RTC has a 16 bit initialization register. The upper
296 * bits can be written directly. The lower bits are written
297 * through a shift register.
300 CSR_WRITE_4(sc, AML_RTC_4_REG, ((sc->init.xo >> 8) & 0xff));
302 CSR_WRITE_4(sc, AML_RTC_0_REG,
303 ((CSR_READ_4(sc, AML_RTC_0_REG) & 0xffffff) |
304 ((uint32_t)(sc->init.xo & 0xff) << 24) | AML_RTC_AS |
307 while ((CSR_READ_4(sc, AML_RTC_0_REG) & AML_RTC_ABSY) != 0)
312 error = aml8726_rtc_sreg_write(sc, AML_RTC_GPO_SREG,
323 aml8726_rtc_check_xo(struct aml8726_rtc_softc *sc)
325 uint32_t now, previous;
329 * The RTC is driven by a 32.768khz clock meaning it's period
330 * is roughly 30.5 us. Check that it's working (implying the
331 * RTC could contain a valid value) by enabling count always
332 * and seeing if the value changes after 200 us (per RTC User
333 * Guide ... presumably the extra time is to cover XO startup).
336 CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) |
339 previous = CSR_READ_4(sc, AML_RTC_2_REG);
341 for (i = 0; i < 4; i++) {
343 now = CSR_READ_4(sc, AML_RTC_2_REG);
348 CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) &
358 aml8726_rtc_probe(device_t dev)
361 if (!ofw_bus_status_okay(dev))
364 if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-rtc"))
367 device_set_desc(dev, "Amlogic aml8726 RTC");
369 return (BUS_PROBE_DEFAULT);
373 aml8726_rtc_attach(device_t dev)
375 struct aml8726_rtc_softc *sc = device_get_softc(dev);
379 switch (aml8726_soc_hw_rev) {
380 case AML_SOC_HW_REV_M3:
381 sc->init.always = true;
382 sc->init.xo = 0x3c0a;
383 sc->init.gpo = 0x100000;
385 case AML_SOC_HW_REV_M6:
386 case AML_SOC_HW_REV_M8:
387 case AML_SOC_HW_REV_M8B:
388 sc->init.always = false;
389 sc->init.xo = 0x180a;
390 sc->init.gpo = 0x500000;
393 device_printf(dev, "unsupported SoC\n");
398 if (bus_alloc_resources(dev, aml8726_rtc_spec, sc->res)) {
399 device_printf(dev, "can not allocate resources for device\n");
403 aml8726_rtc_initialize(sc);
405 if (aml8726_rtc_check_xo(sc) != 0) {
406 device_printf(dev, "crystal oscillator check failed\n");
408 bus_release_resources(dev, aml8726_rtc_spec, sc->res);
413 AML_RTC_LOCK_INIT(sc);
415 clock_register(dev, 1000000);
421 aml8726_rtc_detach(device_t dev)
428 aml8726_rtc_gettime(device_t dev, struct timespec *ts)
430 struct aml8726_rtc_softc *sc = device_get_softc(dev);
436 error = aml8726_rtc_sreg_read(sc, AML_RTC_TIME_SREG, &sec);
447 aml8726_rtc_settime(device_t dev, struct timespec *ts)
449 struct aml8726_rtc_softc *sc = device_get_softc(dev);
455 /* Accuracy is only one second. */
456 if (ts->tv_nsec >= 500000000)
461 error = aml8726_rtc_sreg_write(sc, AML_RTC_TIME_SREG, sec);
468 static device_method_t aml8726_rtc_methods[] = {
469 /* Device interface */
470 DEVMETHOD(device_probe, aml8726_rtc_probe),
471 DEVMETHOD(device_attach, aml8726_rtc_attach),
472 DEVMETHOD(device_detach, aml8726_rtc_detach),
474 /* Clock interface */
475 DEVMETHOD(clock_gettime, aml8726_rtc_gettime),
476 DEVMETHOD(clock_settime, aml8726_rtc_settime),
481 static driver_t aml8726_rtc_driver = {
484 sizeof(struct aml8726_rtc_softc),
487 static devclass_t aml8726_rtc_devclass;
489 DRIVER_MODULE(rtc, simplebus, aml8726_rtc_driver, aml8726_rtc_devclass, 0, 0);