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/fdt/fdt_common.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
54 #include <arm/amlogic/aml8726/aml8726_soc.h>
59 * The RTC initialization various slightly between the different chips.
61 * aml8726-m1 aml8726-m3 aml8726-m6 (and later)
62 * init-always true true false
63 * xo-init 0x0004 0x3c0a 0x180a
64 * gpo-init 0x100000 0x100000 0x500000
67 struct aml8726_rtc_init {
73 struct aml8726_rtc_softc {
75 struct aml8726_rtc_init init;
76 struct resource * res[2];
80 static struct resource_spec aml8726_rtc_spec[] = {
81 { SYS_RES_MEMORY, 0, RF_ACTIVE },
82 { SYS_RES_IRQ, 0, RF_ACTIVE },
86 #define AML_RTC_LOCK(sc) mtx_lock_spin(&(sc)->mtx)
87 #define AML_RTC_UNLOCK(sc) mtx_unlock_spin(&(sc)->mtx)
88 #define AML_RTC_LOCK_INIT(sc) \
89 mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
91 #define AML_RTC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx);
93 #define AML_RTC_0_REG 0
94 #define AML_RTC_SCLK (1 << 0)
95 #define AML_RTC_SDI (1 << 2)
96 #define AML_RTC_SEN (1 << 1)
97 #define AML_RTC_AS (1 << 17)
98 #define AML_RTC_ABSY (1 << 22)
99 #define AML_RTC_IRQ_DIS (1 << 12)
100 #define AML_RTC_1_REG 4
101 #define AML_RTC_SDO (1 << 0)
102 #define AML_RTC_SRDY (1 << 1)
103 #define AML_RTC_2_REG 8
104 #define AML_RTC_3_REG 12
105 #define AML_RTC_MSR_BUSY (1 << 20)
106 #define AML_RTC_MSR_CA (1 << 17)
107 #define AML_RTC_MSR_DURATION_EN (1 << 16)
108 #define AML_RTC_MSR_DURATION_MASK 0xffff
109 #define AML_RTC_MSR_DURATION_SHIFT 0
110 #define AML_RTC_4_REG 16
112 #define AML_RTC_TIME_SREG 0
113 #define AML_RTC_GPO_SREG 1
114 #define AML_RTC_GPO_LEVEL (1 << 24)
115 #define AML_RTC_GPO_BUSY (1 << 23)
116 #define AML_RTC_GPO_ACTIVE_HIGH (1 << 22)
117 #define AML_RTC_GPO_CMD_MASK (3 << 20)
118 #define AML_RTC_GPO_CMD_SHIFT 20
119 #define AML_RTC_GPO_CMD_NOW (1 << 20)
120 #define AML_RTC_GPO_CMD_COUNT (2 << 20)
121 #define AML_RTC_GPO_CMD_PULSE (3 << 20)
122 #define AML_RTC_GPO_CNT_MASK 0xfffff
123 #define AML_RTC_GPO_CNT_SHIFT 0
125 #define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val))
126 #define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg)
127 #define CSR_BARRIER(sc, reg) bus_barrier((sc)->res[0], reg, 4, \
128 (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE))
131 aml8726_rtc_start_transfer(struct aml8726_rtc_softc *sc)
135 /* idle the serial interface */
136 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
137 ~(AML_RTC_SCLK | AML_RTC_SEN | AML_RTC_SDI)));
139 CSR_BARRIER(sc, AML_RTC_0_REG);
141 /* see if it is ready for a new cycle */
142 for (i = 40; i; i--) {
144 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
151 /* start the cycle */
152 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
159 aml8726_rtc_sclk_pulse(struct aml8726_rtc_softc *sc)
164 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
167 CSR_BARRIER(sc, AML_RTC_0_REG);
171 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
174 CSR_BARRIER(sc, AML_RTC_0_REG);
178 aml8726_rtc_send_bit(struct aml8726_rtc_softc *sc, unsigned bit)
182 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
185 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
189 aml8726_rtc_sclk_pulse(sc);
193 aml8726_rtc_send_addr(struct aml8726_rtc_softc *sc, u_char addr)
197 for (mask = 1 << 3; mask; mask >>= 1) {
199 /* final bit indicates read / write mode */
200 CSR_WRITE_4(sc, AML_RTC_0_REG,
201 (CSR_READ_4(sc, AML_RTC_0_REG) & ~AML_RTC_SEN));
203 aml8726_rtc_send_bit(sc, (addr & mask));
208 aml8726_rtc_send_data(struct aml8726_rtc_softc *sc, uint32_t data)
212 for (mask = 1U << 31; mask; mask >>= 1)
213 aml8726_rtc_send_bit(sc, (data & mask));
217 aml8726_rtc_recv_data(struct aml8726_rtc_softc *sc, uint32_t *dp)
224 for (i = 0; i < 32; i++) {
225 aml8726_rtc_sclk_pulse(sc);
227 data |= (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SDO) ? 1 : 0;
234 aml8726_rtc_sreg_read(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t *val)
239 /* read is indicated by lsb = 0 */
240 addr = (sreg << 1) | 0;
242 error = aml8726_rtc_start_transfer(sc);
247 aml8726_rtc_send_addr(sc, addr);
248 aml8726_rtc_recv_data(sc, val);
254 aml8726_rtc_sreg_write(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t val)
259 /* write is indicated by lsb = 1 */
260 addr = (sreg << 1) | 1;
262 error = aml8726_rtc_start_transfer(sc);
267 aml8726_rtc_send_data(sc, val);
268 aml8726_rtc_send_addr(sc, addr);
274 aml8726_rtc_initialize(struct aml8726_rtc_softc *sc)
279 /* idle the serial interface */
280 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
281 ~(AML_RTC_SCLK | AML_RTC_SEN | AML_RTC_SDI)));
283 CSR_BARRIER(sc, AML_RTC_0_REG);
285 /* see if it is ready for a new cycle */
286 for (i = 40; i; i--) {
288 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
292 if (sc->init.always == TRUE || (CSR_READ_4(sc, AML_RTC_1_REG) &
293 AML_RTC_SRDY) == 0) {
296 * The RTC has a 16 bit initialization register. The upper
297 * bits can be written directly. The lower bits are written
298 * through a shift register.
301 CSR_WRITE_4(sc, AML_RTC_4_REG, ((sc->init.xo >> 8) & 0xff));
303 CSR_WRITE_4(sc, AML_RTC_0_REG,
304 ((CSR_READ_4(sc, AML_RTC_0_REG) & 0xffffff) |
305 ((uint32_t)(sc->init.xo & 0xff) << 24) | AML_RTC_AS |
308 while ((CSR_READ_4(sc, AML_RTC_0_REG) & AML_RTC_ABSY) != 0)
313 error = aml8726_rtc_sreg_write(sc, AML_RTC_GPO_SREG,
324 aml8726_rtc_check_xo(struct aml8726_rtc_softc *sc)
326 uint32_t now, previous;
330 * The RTC is driven by a 32.768khz clock meaning it's period
331 * is roughly 30.5 us. Check that it's working (implying the
332 * RTC could contain a valid value) by enabling count always
333 * and seeing if the value changes after 200 us (per RTC User
334 * Guide ... presumably the extra time is to cover XO startup).
337 CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) |
340 previous = CSR_READ_4(sc, AML_RTC_2_REG);
342 for (i = 0; i < 4; i++) {
344 now = CSR_READ_4(sc, AML_RTC_2_REG);
349 CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) &
359 aml8726_rtc_probe(device_t dev)
362 if (!ofw_bus_status_okay(dev))
365 if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-rtc"))
368 device_set_desc(dev, "Amlogic aml8726 RTC");
370 return (BUS_PROBE_DEFAULT);
374 aml8726_rtc_attach(device_t dev)
376 struct aml8726_rtc_softc *sc = device_get_softc(dev);
380 switch (aml8726_soc_hw_rev) {
381 case AML_SOC_HW_REV_M3:
382 sc->init.always = true;
383 sc->init.xo = 0x3c0a;
384 sc->init.gpo = 0x100000;
386 case AML_SOC_HW_REV_M6:
387 case AML_SOC_HW_REV_M8:
388 case AML_SOC_HW_REV_M8B:
389 sc->init.always = false;
390 sc->init.xo = 0x180a;
391 sc->init.gpo = 0x500000;
394 device_printf(dev, "unsupported SoC\n");
399 if (bus_alloc_resources(dev, aml8726_rtc_spec, sc->res)) {
400 device_printf(dev, "can not allocate resources for device\n");
404 aml8726_rtc_initialize(sc);
406 if (aml8726_rtc_check_xo(sc) != 0) {
407 device_printf(dev, "crystal oscillator check failed\n");
409 bus_release_resources(dev, aml8726_rtc_spec, sc->res);
414 AML_RTC_LOCK_INIT(sc);
416 clock_register(dev, 1000000);
422 aml8726_rtc_detach(device_t dev)
429 aml8726_rtc_gettime(device_t dev, struct timespec *ts)
431 struct aml8726_rtc_softc *sc = device_get_softc(dev);
437 error = aml8726_rtc_sreg_read(sc, AML_RTC_TIME_SREG, &sec);
448 aml8726_rtc_settime(device_t dev, struct timespec *ts)
450 struct aml8726_rtc_softc *sc = device_get_softc(dev);
456 /* Accuracy is only one second. */
457 if (ts->tv_nsec >= 500000000)
462 error = aml8726_rtc_sreg_write(sc, AML_RTC_TIME_SREG, sec);
469 static device_method_t aml8726_rtc_methods[] = {
470 /* Device interface */
471 DEVMETHOD(device_probe, aml8726_rtc_probe),
472 DEVMETHOD(device_attach, aml8726_rtc_attach),
473 DEVMETHOD(device_detach, aml8726_rtc_detach),
475 /* Clock interface */
476 DEVMETHOD(clock_gettime, aml8726_rtc_gettime),
477 DEVMETHOD(clock_settime, aml8726_rtc_settime),
482 static driver_t aml8726_rtc_driver = {
485 sizeof(struct aml8726_rtc_softc),
488 static devclass_t aml8726_rtc_devclass;
490 DRIVER_MODULE(rtc, simplebus, aml8726_rtc_driver, aml8726_rtc_devclass, 0, 0);