]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/amlogic/aml8726/aml8726_rtc.c
Update compiler-rt to 3.9.0 release, and update the build glue for
[FreeBSD/FreeBSD.git] / sys / arm / amlogic / aml8726 / aml8726_rtc.c
1 /*-
2  * Copyright 2013-2015 John Wehle <john@feith.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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
24  * SUCH DAMAGE.
25  */
26
27 /*
28  * Amlogic aml8726 RTC driver.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/clock.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/resource.h>
43 #include <sys/rman.h>
44
45 #include <sys/time.h>
46
47 #include <machine/bus.h>
48 #include <machine/cpu.h>
49
50 #include <dev/fdt/fdt_common.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53
54 #include <arm/amlogic/aml8726/aml8726_soc.h>
55
56 #include "clock_if.h"
57
58 /*
59  * The RTC initialization various slightly between the different chips.
60  *
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
65  */
66
67 struct aml8726_rtc_init {
68         boolean_t       always;
69         uint16_t        xo;
70         uint32_t        gpo;
71 };
72
73 struct aml8726_rtc_softc {
74         device_t                dev;
75         struct aml8726_rtc_init init;
76         struct resource *       res[2];
77         struct mtx              mtx;
78 };
79
80 static struct resource_spec aml8726_rtc_spec[] = {
81         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
82         { SYS_RES_IRQ,          0,      RF_ACTIVE },
83         { -1, 0 }
84 };
85
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),        \
90     "rtc", MTX_SPIN)
91 #define AML_RTC_LOCK_DESTROY(sc)        mtx_destroy(&(sc)->mtx);
92
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
111
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
124
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))
129
130 static int
131 aml8726_rtc_start_transfer(struct aml8726_rtc_softc *sc)
132 {
133         unsigned i;
134
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)));
138
139         CSR_BARRIER(sc, AML_RTC_0_REG);
140
141         /* see if it is ready for a new cycle */
142         for (i = 40; i; i--) {
143                 DELAY(5);
144                 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
145                         break;
146         }
147
148         if (i == 0)
149                 return (EIO);
150
151         /* start the cycle */
152         CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
153             AML_RTC_SEN));
154
155         return (0);
156 }
157
158 static inline void
159 aml8726_rtc_sclk_pulse(struct aml8726_rtc_softc *sc)
160 {
161
162         DELAY(5);
163
164         CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
165             AML_RTC_SCLK));
166
167         CSR_BARRIER(sc, AML_RTC_0_REG);
168
169         DELAY(5);
170
171         CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
172             ~AML_RTC_SCLK));
173
174         CSR_BARRIER(sc, AML_RTC_0_REG);
175 }
176
177 static inline void
178 aml8726_rtc_send_bit(struct aml8726_rtc_softc *sc, unsigned bit)
179 {
180
181         if (bit) {
182                 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) |
183                     AML_RTC_SDI));
184         } else {
185                 CSR_WRITE_4(sc, AML_RTC_0_REG, (CSR_READ_4(sc, AML_RTC_0_REG) &
186                     ~AML_RTC_SDI));
187         }
188
189         aml8726_rtc_sclk_pulse(sc);
190 }
191
192 static inline void
193 aml8726_rtc_send_addr(struct aml8726_rtc_softc *sc, u_char addr)
194 {
195         unsigned mask;
196
197         for (mask = 1 << 3; mask; mask >>= 1) {
198                 if (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));
202                 }
203                 aml8726_rtc_send_bit(sc, (addr & mask));
204         }
205 }
206
207 static inline void
208 aml8726_rtc_send_data(struct aml8726_rtc_softc *sc, uint32_t data)
209 {
210         unsigned mask;
211
212         for (mask = 1U << 31; mask; mask >>= 1)
213                 aml8726_rtc_send_bit(sc, (data & mask));
214 }
215
216 static inline void
217 aml8726_rtc_recv_data(struct aml8726_rtc_softc *sc, uint32_t *dp)
218 {
219         uint32_t data;
220         unsigned i;
221
222         data = 0;
223
224         for (i = 0; i < 32; i++) {
225                 aml8726_rtc_sclk_pulse(sc);
226                 data <<= 1;
227                 data |= (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SDO) ? 1 : 0;
228         }
229
230         *dp = data;
231 }
232
233 static int
234 aml8726_rtc_sreg_read(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t *val)
235 {
236         u_char addr;
237         int error;
238
239         /* read is indicated by lsb = 0 */
240         addr = (sreg << 1) | 0;
241
242         error = aml8726_rtc_start_transfer(sc);
243
244         if (error)
245                 return (error);
246
247         aml8726_rtc_send_addr(sc, addr);
248         aml8726_rtc_recv_data(sc, val);
249
250         return (0);
251 }
252
253 static int
254 aml8726_rtc_sreg_write(struct aml8726_rtc_softc *sc, u_char sreg, uint32_t val)
255 {
256         u_char addr;
257         int error;
258
259         /* write is indicated by lsb = 1 */
260         addr = (sreg << 1) | 1;
261
262         error = aml8726_rtc_start_transfer(sc);
263
264         if (error)
265                 return (error);
266
267         aml8726_rtc_send_data(sc, val);
268         aml8726_rtc_send_addr(sc, addr);
269
270         return (0);
271 }
272
273 static int
274 aml8726_rtc_initialize(struct aml8726_rtc_softc *sc)
275 {
276         int error;
277         unsigned i;
278
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)));
282
283         CSR_BARRIER(sc, AML_RTC_0_REG);
284
285         /* see if it is ready for a new cycle */
286         for (i = 40; i; i--) {
287                 DELAY(5);
288                 if ( (CSR_READ_4(sc, AML_RTC_1_REG) & AML_RTC_SRDY) )
289                         break;
290         }
291
292         if (sc->init.always == TRUE || (CSR_READ_4(sc, AML_RTC_1_REG) &
293             AML_RTC_SRDY) == 0) {
294
295                 /*
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.
299                  */
300
301                 CSR_WRITE_4(sc, AML_RTC_4_REG, ((sc->init.xo >> 8) & 0xff));
302
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 |
306                     AML_RTC_IRQ_DIS));
307
308                 while ((CSR_READ_4(sc, AML_RTC_0_REG) & AML_RTC_ABSY) != 0)
309                         cpu_spinwait();
310
311                 DELAY(2);
312
313                 error = aml8726_rtc_sreg_write(sc, AML_RTC_GPO_SREG,
314                     sc->init.gpo);
315
316                 if (error)
317                         return (error);
318         }
319
320         return (0);
321 }
322
323 static int
324 aml8726_rtc_check_xo(struct aml8726_rtc_softc *sc)
325 {
326         uint32_t now, previous;
327         int i;
328
329         /*
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).
335          */
336
337         CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) |
338             AML_RTC_MSR_CA));
339
340         previous = CSR_READ_4(sc, AML_RTC_2_REG);
341
342         for (i = 0; i < 4; i++) {
343                 DELAY(50);
344                 now = CSR_READ_4(sc, AML_RTC_2_REG);
345                 if (now != previous)
346                         break;
347         }
348
349         CSR_WRITE_4(sc, AML_RTC_3_REG, (CSR_READ_4(sc, AML_RTC_3_REG) &
350             ~AML_RTC_MSR_CA));
351
352         if (now == previous)
353                 return (EINVAL);
354
355         return (0);
356 }
357
358 static int
359 aml8726_rtc_probe(device_t dev)
360 {
361
362         if (!ofw_bus_status_okay(dev))
363                 return (ENXIO);
364
365         if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-rtc"))
366                 return (ENXIO);
367
368         device_set_desc(dev, "Amlogic aml8726 RTC");
369
370         return (BUS_PROBE_DEFAULT);
371 }
372
373 static int
374 aml8726_rtc_attach(device_t dev)
375 {
376         struct aml8726_rtc_softc *sc = device_get_softc(dev);
377
378         sc->dev = dev;
379
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;
385                 break;
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;
392                 break;
393         default:
394                 device_printf(dev, "unsupported SoC\n");
395                 return (ENXIO);
396                 /* NOTREACHED */
397         }
398
399         if (bus_alloc_resources(dev, aml8726_rtc_spec, sc->res)) {
400                 device_printf(dev, "can not allocate resources for device\n");
401                 return (ENXIO);
402         }
403
404         aml8726_rtc_initialize(sc);
405
406         if (aml8726_rtc_check_xo(sc) != 0) {
407                 device_printf(dev, "crystal oscillator check failed\n");
408
409                 bus_release_resources(dev, aml8726_rtc_spec, sc->res);
410
411                 return (ENXIO);
412         }
413
414         AML_RTC_LOCK_INIT(sc);
415
416         clock_register(dev, 1000000);
417
418         return (0);
419 }
420
421 static int
422 aml8726_rtc_detach(device_t dev)
423 {
424
425         return (EBUSY);
426 }
427
428 static int
429 aml8726_rtc_gettime(device_t dev, struct timespec *ts)
430 {
431         struct aml8726_rtc_softc *sc = device_get_softc(dev);
432         uint32_t sec;
433         int error;
434
435         AML_RTC_LOCK(sc);
436
437         error = aml8726_rtc_sreg_read(sc, AML_RTC_TIME_SREG, &sec);
438
439         AML_RTC_UNLOCK(sc);
440
441         ts->tv_sec = sec;
442         ts->tv_nsec = 0;
443
444         return (error);
445 }
446
447 static int
448 aml8726_rtc_settime(device_t dev, struct timespec *ts)
449 {
450         struct aml8726_rtc_softc *sc = device_get_softc(dev);
451         uint32_t sec;
452         int error;
453
454         sec = ts->tv_sec;
455
456         /* Accuracy is only one second. */
457         if (ts->tv_nsec >= 500000000)
458                 sec++;
459
460         AML_RTC_LOCK(sc);
461
462         error = aml8726_rtc_sreg_write(sc, AML_RTC_TIME_SREG, sec);
463
464         AML_RTC_UNLOCK(sc);
465
466         return (error); 
467 }
468
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),
474
475         /* Clock interface */
476         DEVMETHOD(clock_gettime,        aml8726_rtc_gettime),
477         DEVMETHOD(clock_settime,        aml8726_rtc_settime),
478
479         DEVMETHOD_END
480 };
481
482 static driver_t aml8726_rtc_driver = {
483         "rtc",
484         aml8726_rtc_methods,
485         sizeof(struct aml8726_rtc_softc),
486 };
487
488 static devclass_t aml8726_rtc_devclass;
489
490 DRIVER_MODULE(rtc, simplebus, aml8726_rtc_driver, aml8726_rtc_devclass, 0, 0);