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