Home | History | Annotate | Line # | Download | only in sbmips
rtc.c revision 1.1
      1  1.1  mrg /* $NetBSD: rtc.c,v 1.1 2017/07/24 08:56:29 mrg Exp $ */
      2  1.1  mrg 
      3  1.1  mrg /*
      4  1.1  mrg  * Copyright 2002 Wasabi Systems, Inc.
      5  1.1  mrg  * All rights reserved.
      6  1.1  mrg  *
      7  1.1  mrg  * Written by Simon Burge for Wasabi Systems, Inc.
      8  1.1  mrg  *
      9  1.1  mrg  * Redistribution and use in source and binary forms, with or without
     10  1.1  mrg  * modification, are permitted provided that the following conditions
     11  1.1  mrg  * are met:
     12  1.1  mrg  * 1. Redistributions of source code must retain the above copyright
     13  1.1  mrg  *    notice, this list of conditions and the following disclaimer.
     14  1.1  mrg  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1  mrg  *    notice, this list of conditions and the following disclaimer in the
     16  1.1  mrg  *    documentation and/or other materials provided with the distribution.
     17  1.1  mrg  * 3. All advertising materials mentioning features or use of this software
     18  1.1  mrg  *    must display the following acknowledgement:
     19  1.1  mrg  *      This product includes software developed for the NetBSD Project by
     20  1.1  mrg  *      Wasabi Systems, Inc.
     21  1.1  mrg  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  1.1  mrg  *    or promote products derived from this software without specific prior
     23  1.1  mrg  *    written permission.
     24  1.1  mrg  *
     25  1.1  mrg  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  1.1  mrg  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  1.1  mrg  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  1.1  mrg  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  1.1  mrg  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  1.1  mrg  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  1.1  mrg  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  1.1  mrg  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  1.1  mrg  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  1.1  mrg  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  1.1  mrg  * POSSIBILITY OF SUCH DAMAGE.
     36  1.1  mrg  */
     37  1.1  mrg 
     38  1.1  mrg #include <sys/cdefs.h>
     39  1.1  mrg __KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.1 2017/07/24 08:56:29 mrg Exp $");
     40  1.1  mrg 
     41  1.1  mrg #include <sys/param.h>
     42  1.1  mrg #include <sys/device.h>
     43  1.1  mrg #include <sys/kernel.h>
     44  1.1  mrg #include <sys/systm.h>
     45  1.1  mrg #include <sys/cpu.h>
     46  1.1  mrg 
     47  1.1  mrg #include <dev/clock_subr.h>
     48  1.1  mrg 
     49  1.1  mrg #include <sbmips/swarm.h>
     50  1.1  mrg #include <sbmips/systemsw.h>
     51  1.1  mrg 
     52  1.1  mrg #include <mips/locore.h>
     53  1.1  mrg #include <mips/sibyte/dev/sbsmbusvar.h>
     54  1.1  mrg 
     55  1.1  mrg #include <dev/smbus/m41t81reg.h>
     56  1.1  mrg #include <dev/smbus/x1241reg.h>
     57  1.1  mrg 
     58  1.1  mrg struct rtc_softc {
     59  1.1  mrg 	device_t		sc_dev;
     60  1.1  mrg 	int			sc_smbus_chan;
     61  1.1  mrg 	int			sc_smbus_addr;
     62  1.1  mrg 	int			sc_type;
     63  1.1  mrg 	struct todr_chip_handle	sc_ct;
     64  1.1  mrg };
     65  1.1  mrg 
     66  1.1  mrg /* "types" for RTCs we support */
     67  1.1  mrg #define	SMB_1BYTE_ADDR	1
     68  1.1  mrg #define	SMB_2BYTE_ADDR	2
     69  1.1  mrg 
     70  1.1  mrg static int xirtc_match(device_t, cfdata_t , void *);
     71  1.1  mrg static void xirtc_attach(device_t, device_t, void *);
     72  1.1  mrg static int xirtc_gettime(todr_chip_handle_t, struct clock_ymdhms *);
     73  1.1  mrg static int xirtc_settime(todr_chip_handle_t, struct clock_ymdhms *);
     74  1.1  mrg 
     75  1.1  mrg static int strtc_match(device_t, cfdata_t , void *);
     76  1.1  mrg static void strtc_attach(device_t, device_t, void *);
     77  1.1  mrg static int strtc_gettime(todr_chip_handle_t, struct clock_ymdhms *);
     78  1.1  mrg static int strtc_settime(todr_chip_handle_t, struct clock_ymdhms *);
     79  1.1  mrg 
     80  1.1  mrg static void rtc_cal_timer(void);
     81  1.1  mrg 
     82  1.1  mrg static void time_smbus_init(int);
     83  1.1  mrg static int time_waitready(int);
     84  1.1  mrg static int time_readrtc(int, int, int, int);
     85  1.1  mrg static int time_writertc(int, int, int, int, int);
     86  1.1  mrg 
     87  1.1  mrg #define	WRITERTC(sc, dev, val)	\
     88  1.1  mrg 	time_writertc((sc)->sc_smbus_chan, (sc)->sc_smbus_addr, (dev), (sc)->sc_type, (val))
     89  1.1  mrg #define	READRTC(sc, dev)	\
     90  1.1  mrg 	time_readrtc((sc)->sc_smbus_chan, (sc)->sc_smbus_addr, (dev), (sc)->sc_type)
     91  1.1  mrg 
     92  1.1  mrg 
     93  1.1  mrg CFATTACH_DECL_NEW(xirtc, sizeof(struct rtc_softc),
     94  1.1  mrg     xirtc_match, xirtc_attach, NULL, NULL);
     95  1.1  mrg 
     96  1.1  mrg CFATTACH_DECL_NEW(m41t81rtc, sizeof(struct rtc_softc),
     97  1.1  mrg     strtc_match, strtc_attach, NULL, NULL);
     98  1.1  mrg 
     99  1.1  mrg static int rtcfound = 0;
    100  1.1  mrg struct rtc_softc *the_rtc;
    101  1.1  mrg 
    102  1.1  mrg /*
    103  1.1  mrg  * Xicor X1241 RTC support.
    104  1.1  mrg  */
    105  1.1  mrg static int
    106  1.1  mrg xirtc_match(device_t parent, cfdata_t cf, void *aux)
    107  1.1  mrg {
    108  1.1  mrg 	struct smbus_attach_args *sa = aux;
    109  1.1  mrg 	int ret;
    110  1.1  mrg 
    111  1.1  mrg 	time_smbus_init(sa->sa_interface);
    112  1.1  mrg 
    113  1.1  mrg 	if ((sa->sa_interface != X1241_SMBUS_CHAN) ||
    114  1.1  mrg 	    (sa->sa_device != X1241_RTC_SLAVEADDR))
    115  1.1  mrg 		return (0);
    116  1.1  mrg 
    117  1.1  mrg 	ret = time_readrtc(sa->sa_interface, sa->sa_device, SMB_2BYTE_ADDR, X1241REG_SC);
    118  1.1  mrg 	if (ret < 0)
    119  1.1  mrg 		return (0);
    120  1.1  mrg 
    121  1.1  mrg 	return (!rtcfound);
    122  1.1  mrg }
    123  1.1  mrg 
    124  1.1  mrg static void
    125  1.1  mrg xirtc_attach(device_t parent, device_t self, void *aux)
    126  1.1  mrg {
    127  1.1  mrg 	struct smbus_attach_args *sa = aux;
    128  1.1  mrg 	struct rtc_softc *sc = device_private(self);
    129  1.1  mrg 
    130  1.1  mrg 	rtcfound = 1;
    131  1.1  mrg 	the_rtc = sc;
    132  1.1  mrg 
    133  1.1  mrg 	sc->sc_dev = self;
    134  1.1  mrg 	sc->sc_smbus_chan = sa->sa_interface;
    135  1.1  mrg 	sc->sc_smbus_addr = sa->sa_device;
    136  1.1  mrg 	sc->sc_type = SMB_2BYTE_ADDR;	/* Two-byte register addresses on the Xicor */
    137  1.1  mrg 
    138  1.1  mrg 
    139  1.1  mrg 	/* Set up MI todr(9) stuff */
    140  1.1  mrg 	sc->sc_ct.cookie = sc;
    141  1.1  mrg 	sc->sc_ct.todr_settime_ymdhms = xirtc_settime;
    142  1.1  mrg 	sc->sc_ct.todr_gettime_ymdhms = xirtc_gettime;
    143  1.1  mrg 
    144  1.1  mrg 	todr_attach(&sc->sc_ct);
    145  1.1  mrg 
    146  1.1  mrg 	aprint_normal("\n");
    147  1.1  mrg 	rtc_cal_timer();	/* XXX */
    148  1.1  mrg }
    149  1.1  mrg 
    150  1.1  mrg static int
    151  1.1  mrg xirtc_settime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms)
    152  1.1  mrg {
    153  1.1  mrg 	struct rtc_softc *sc = handle->cookie;
    154  1.1  mrg 	uint8_t year, y2k;
    155  1.1  mrg 
    156  1.1  mrg 	time_smbus_init(sc->sc_smbus_chan);
    157  1.1  mrg 
    158  1.1  mrg 	/* unlock writes to the CCR */
    159  1.1  mrg 	WRITERTC(sc, X1241REG_SR, X1241REG_SR_WEL);
    160  1.1  mrg 	WRITERTC(sc, X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
    161  1.1  mrg 
    162  1.1  mrg 	/* set the time */
    163  1.1  mrg 	WRITERTC(sc, X1241REG_HR, bintobcd(ymdhms->dt_hour) | X1241REG_HR_MIL);
    164  1.1  mrg 	WRITERTC(sc, X1241REG_MN, bintobcd(ymdhms->dt_min));
    165  1.1  mrg 	WRITERTC(sc, X1241REG_SC, bintobcd(ymdhms->dt_sec));
    166  1.1  mrg 
    167  1.1  mrg 	/* set the date */
    168  1.1  mrg 	y2k = (ymdhms->dt_year >= 2000) ? 0x20 : 0x19;
    169  1.1  mrg 	year = ymdhms->dt_year % 100;
    170  1.1  mrg 
    171  1.1  mrg 	WRITERTC(sc, X1241REG_MO, bintobcd(ymdhms->dt_mon));
    172  1.1  mrg 	WRITERTC(sc, X1241REG_DT, bintobcd(ymdhms->dt_day));
    173  1.1  mrg 	WRITERTC(sc, X1241REG_YR, bintobcd(year));
    174  1.1  mrg 	WRITERTC(sc, X1241REG_Y2K, bintobcd(y2k));
    175  1.1  mrg 
    176  1.1  mrg 	/* lock writes again */
    177  1.1  mrg 	WRITERTC(sc, X1241REG_SR, 0);
    178  1.1  mrg 
    179  1.1  mrg 	return (0);
    180  1.1  mrg }
    181  1.1  mrg 
    182  1.1  mrg static int
    183  1.1  mrg xirtc_gettime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms)
    184  1.1  mrg {
    185  1.1  mrg 	struct rtc_softc *sc = handle->cookie;
    186  1.1  mrg 	uint8_t hour, year, y2k;
    187  1.1  mrg 	uint8_t status;
    188  1.1  mrg 
    189  1.1  mrg 	time_smbus_init(sc->sc_smbus_chan);
    190  1.1  mrg 	ymdhms->dt_day = bcdtobin(READRTC(sc, X1241REG_DT));
    191  1.1  mrg 	ymdhms->dt_mon =  bcdtobin(READRTC(sc, X1241REG_MO));
    192  1.1  mrg 	year =  READRTC(sc, X1241REG_YR);
    193  1.1  mrg 	y2k = READRTC(sc, X1241REG_Y2K);
    194  1.1  mrg 	ymdhms->dt_year = bcdtobin(y2k) * 100 + bcdtobin(year);
    195  1.1  mrg 
    196  1.1  mrg 
    197  1.1  mrg 	ymdhms->dt_sec = bcdtobin(READRTC(sc, X1241REG_SC));
    198  1.1  mrg 	ymdhms->dt_min = bcdtobin(READRTC(sc, X1241REG_MN));
    199  1.1  mrg 	hour = READRTC(sc, X1241REG_HR);
    200  1.1  mrg 	ymdhms->dt_hour = bcdtobin(hour & ~X1241REG_HR_MIL);
    201  1.1  mrg 
    202  1.1  mrg 	status = READRTC(sc, X1241REG_SR);
    203  1.1  mrg 
    204  1.1  mrg 	if (status & X1241REG_SR_RTCF) {
    205  1.1  mrg 		printf("%s: battery has failed, clock setting is not accurate\n",
    206  1.1  mrg 		    device_xname(sc->sc_dev));
    207  1.1  mrg 		return (EIO);
    208  1.1  mrg 	}
    209  1.1  mrg 
    210  1.1  mrg 	return (0);
    211  1.1  mrg }
    212  1.1  mrg 
    213  1.1  mrg /*
    214  1.1  mrg  * ST M41T81 RTC support.
    215  1.1  mrg  */
    216  1.1  mrg static int
    217  1.1  mrg strtc_match(device_t parent, cfdata_t cf, void *aux)
    218  1.1  mrg {
    219  1.1  mrg 	struct smbus_attach_args *sa = aux;
    220  1.1  mrg 	int ret;
    221  1.1  mrg 
    222  1.1  mrg 	if ((sa->sa_interface != M41T81_SMBUS_CHAN) ||
    223  1.1  mrg 	    (sa->sa_device != M41T81_SLAVEADDR))
    224  1.1  mrg 		return (0);
    225  1.1  mrg 
    226  1.1  mrg 	time_smbus_init(sa->sa_interface);
    227  1.1  mrg 
    228  1.1  mrg 	ret = time_readrtc(sa->sa_interface, sa->sa_device, SMB_1BYTE_ADDR, M41T81_SEC);
    229  1.1  mrg 	if (ret < 0)
    230  1.1  mrg 		return (0);
    231  1.1  mrg 
    232  1.1  mrg 	return (!rtcfound);
    233  1.1  mrg }
    234  1.1  mrg 
    235  1.1  mrg static void
    236  1.1  mrg strtc_attach(device_t parent, device_t self, void *aux)
    237  1.1  mrg {
    238  1.1  mrg 	struct smbus_attach_args *sa = aux;
    239  1.1  mrg 	struct rtc_softc *sc = device_private(self);
    240  1.1  mrg 
    241  1.1  mrg 	rtcfound = 1;
    242  1.1  mrg 	the_rtc = sc;
    243  1.1  mrg 
    244  1.1  mrg 	sc->sc_dev = self;
    245  1.1  mrg 	sc->sc_smbus_chan = sa->sa_interface;
    246  1.1  mrg 	sc->sc_smbus_addr = sa->sa_device;
    247  1.1  mrg 	sc->sc_type = SMB_1BYTE_ADDR;	/* One-byte register addresses on the ST */
    248  1.1  mrg 
    249  1.1  mrg 	/* Set up MI todr(9) stuff */
    250  1.1  mrg 	sc->sc_ct.cookie = sc;
    251  1.1  mrg 	sc->sc_ct.todr_settime_ymdhms = strtc_settime;
    252  1.1  mrg 	sc->sc_ct.todr_gettime_ymdhms = strtc_gettime;
    253  1.1  mrg 
    254  1.1  mrg 	todr_attach(&sc->sc_ct);
    255  1.1  mrg 
    256  1.1  mrg 	aprint_normal("\n");
    257  1.1  mrg 	rtc_cal_timer();	/* XXX */
    258  1.1  mrg }
    259  1.1  mrg 
    260  1.1  mrg static int
    261  1.1  mrg strtc_settime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms)
    262  1.1  mrg {
    263  1.1  mrg 	struct rtc_softc *sc = handle->cookie;
    264  1.1  mrg 	uint8_t hour;
    265  1.1  mrg 
    266  1.1  mrg 	time_smbus_init(sc->sc_smbus_chan);
    267  1.1  mrg 
    268  1.1  mrg 	hour = bintobcd(ymdhms->dt_hour);
    269  1.1  mrg 	if (ymdhms->dt_year >= 2000)	/* Should be always true! */
    270  1.1  mrg 		hour |= M41T81_HOUR_CB | M41T81_HOUR_CEB;
    271  1.1  mrg 
    272  1.1  mrg 	/* set the time */
    273  1.1  mrg 	WRITERTC(sc, M41T81_SEC, bintobcd(ymdhms->dt_sec));
    274  1.1  mrg 	WRITERTC(sc, M41T81_MIN, bintobcd(ymdhms->dt_min));
    275  1.1  mrg 	WRITERTC(sc, M41T81_HOUR, hour);
    276  1.1  mrg 
    277  1.1  mrg 	/* set the date */
    278  1.1  mrg 	WRITERTC(sc, M41T81_DATE, bintobcd(ymdhms->dt_day));
    279  1.1  mrg 	WRITERTC(sc, M41T81_MON, bintobcd(ymdhms->dt_mon));
    280  1.1  mrg 	WRITERTC(sc, M41T81_YEAR, bintobcd(ymdhms->dt_year % 100));
    281  1.1  mrg 
    282  1.1  mrg 	return (0);
    283  1.1  mrg }
    284  1.1  mrg 
    285  1.1  mrg static int
    286  1.1  mrg strtc_gettime(todr_chip_handle_t handle, struct clock_ymdhms *ymdhms)
    287  1.1  mrg {
    288  1.1  mrg 	struct rtc_softc *sc = handle->cookie;
    289  1.1  mrg 	uint8_t hour;
    290  1.1  mrg 
    291  1.1  mrg 	time_smbus_init(sc->sc_smbus_chan);
    292  1.1  mrg 
    293  1.1  mrg 	ymdhms->dt_sec = bcdtobin(READRTC(sc, M41T81_SEC));
    294  1.1  mrg 	ymdhms->dt_min = bcdtobin(READRTC(sc, M41T81_MIN));
    295  1.1  mrg 	hour = READRTC(sc, M41T81_HOUR & M41T81_HOUR_MASK);
    296  1.1  mrg 	ymdhms->dt_hour = bcdtobin(hour & M41T81_HOUR_MASK);
    297  1.1  mrg 
    298  1.1  mrg 	ymdhms->dt_day = bcdtobin(READRTC(sc, M41T81_DATE));
    299  1.1  mrg 	ymdhms->dt_mon =  bcdtobin(READRTC(sc, M41T81_MON));
    300  1.1  mrg 	ymdhms->dt_year =  1900 + bcdtobin(READRTC(sc, M41T81_YEAR));
    301  1.1  mrg 	if (hour & M41T81_HOUR_CB)
    302  1.1  mrg 		ymdhms->dt_year += 100;
    303  1.1  mrg 
    304  1.1  mrg 	return (0);
    305  1.1  mrg }
    306  1.1  mrg 
    307  1.1  mrg #define	NITERS			3
    308  1.1  mrg #define	RTC_SECONDS(rtc)	bcdtobin(READRTC((rtc), X1241REG_SC))
    309  1.1  mrg 
    310  1.1  mrg /*
    311  1.1  mrg  * Since it takes so long to read the complete time/date values from
    312  1.1  mrg  * the RTC over the SMBus, we only read the seconds value.
    313  1.1  mrg  * Later versions of the SWARM will hopefully have the RTC interrupt
    314  1.1  mrg  * attached so we can do the clock calibration much more quickly and
    315  1.1  mrg  * with a higher resolution.
    316  1.1  mrg  */
    317  1.1  mrg static void
    318  1.1  mrg rtc_cal_timer(void)
    319  1.1  mrg {
    320  1.1  mrg 	uint32_t ctrdiff[NITERS], startctr, endctr;
    321  1.1  mrg 	int sec, lastsec, i;
    322  1.1  mrg 
    323  1.1  mrg 	if (rtcfound == 0) {
    324  1.1  mrg 		printf("rtc_cal_timer before rtc attached\n");
    325  1.1  mrg 		return;
    326  1.1  mrg 	}
    327  1.1  mrg return;	/* XXX XXX */
    328  1.1  mrg 
    329  1.1  mrg 	printf("%s: calibrating CPU clock", device_xname(the_rtc->sc_dev));
    330  1.1  mrg 
    331  1.1  mrg 	/*
    332  1.1  mrg 	 * Run the loop an extra time to wait for the second to tick over
    333  1.1  mrg 	 * and to prime the cache.
    334  1.1  mrg 	 */
    335  1.1  mrg 	time_smbus_init(the_rtc->sc_smbus_chan);
    336  1.1  mrg 	sec = RTC_SECONDS(the_rtc);
    337  1.1  mrg 	endctr = mips3_cp0_count_read();
    338  1.1  mrg 
    339  1.1  mrg 	for (i = 0; i < NITERS; i++) {
    340  1.1  mrg 		int diff;
    341  1.1  mrg 
    342  1.1  mrg  again:
    343  1.1  mrg 		lastsec = sec;
    344  1.1  mrg 		startctr = endctr;
    345  1.1  mrg 
    346  1.1  mrg 		/* Wait for the timer to tick over. */
    347  1.1  mrg 		do {
    348  1.1  mrg 			// time_smbus_init(the_rtc->sc_smbus_chan);
    349  1.1  mrg 			sec = RTC_SECONDS(the_rtc);
    350  1.1  mrg 		} while (lastsec == sec);
    351  1.1  mrg 		endctr = mips3_cp0_count_read();
    352  1.1  mrg 
    353  1.1  mrg 		diff = sec - lastsec;
    354  1.1  mrg 		if (diff < 0)
    355  1.1  mrg 			diff += 60;
    356  1.1  mrg 
    357  1.1  mrg 		/* Sometimes we appear to skip a second.  Clock jitter? */
    358  1.1  mrg 		if (diff > 1)
    359  1.1  mrg 			goto again;
    360  1.1  mrg 
    361  1.1  mrg 		if (endctr < startctr)
    362  1.1  mrg 			ctrdiff[i] = 0xffffffff - startctr + endctr;
    363  1.1  mrg 		else
    364  1.1  mrg 			ctrdiff[i] = endctr - startctr;
    365  1.1  mrg 	}
    366  1.1  mrg 	printf("\n");
    367  1.1  mrg 
    368  1.1  mrg 	/* Compute the number of cycles per second. */
    369  1.1  mrg 	curcpu()->ci_cpu_freq = ((ctrdiff[1] + ctrdiff[2]) / 2);
    370  1.1  mrg 
    371  1.1  mrg 	/* Compute the delay divisor. */
    372  1.1  mrg 	curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / 1000000;
    373  1.1  mrg 
    374  1.1  mrg 	/* Compute clock cycles per hz */
    375  1.1  mrg 	curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / hz;
    376  1.1  mrg 
    377  1.1  mrg 	printf("%s: timer calibration: %lu cycles/sec [(%u, %u)]\n",
    378  1.1  mrg 	    device_xname(the_rtc->sc_dev), curcpu()->ci_cpu_freq,
    379  1.1  mrg 	    ctrdiff[1], ctrdiff[2]);
    380  1.1  mrg }
    381  1.1  mrg #undef RTC_SECONDS
    382  1.1  mrg 
    383  1.1  mrg /* XXX eville direct-access-to-the-device code follows... */
    384  1.1  mrg 
    385  1.1  mrg /*
    386  1.1  mrg  * Copyright 2000,2001
    387  1.1  mrg  * Broadcom Corporation. All rights reserved.
    388  1.1  mrg  *
    389  1.1  mrg  * This software is furnished under license and may be used and copied only
    390  1.1  mrg  * in accordance with the following terms and conditions.  Subject to these
    391  1.1  mrg  * conditions, you may download, copy, install, use, modify and distribute
    392  1.1  mrg  * modified or unmodified copies of this software in source and/or binary
    393  1.1  mrg  * form. No title or ownership is transferred hereby.
    394  1.1  mrg  *
    395  1.1  mrg  * 1) Any source code used, modified or distributed must reproduce and
    396  1.1  mrg  *    retain this copyright notice and list of conditions as they appear in
    397  1.1  mrg  *    the source file.
    398  1.1  mrg  *
    399  1.1  mrg  * 2) No right is granted to use any trade name, trademark, or logo of
    400  1.1  mrg  *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
    401  1.1  mrg  *    used to endorse or promote products derived from this software
    402  1.1  mrg  *    without the prior written permission of Broadcom Corporation.
    403  1.1  mrg  *
    404  1.1  mrg  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
    405  1.1  mrg  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
    406  1.1  mrg  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
    407  1.1  mrg  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
    408  1.1  mrg  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
    409  1.1  mrg  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    410  1.1  mrg  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    411  1.1  mrg  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    412  1.1  mrg  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    413  1.1  mrg  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
    414  1.1  mrg  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    415  1.1  mrg  */
    416  1.1  mrg 
    417  1.1  mrg #include <mips/sibyte/include/sb1250_regs.h>
    418  1.1  mrg #include <mips/sibyte/include/sb1250_smbus.h>
    419  1.1  mrg 
    420  1.1  mrg #define	READ_REG(rp)		mips3_ld((register_t)(MIPS_PHYS_TO_KSEG1(rp)))
    421  1.1  mrg #define	WRITE_REG(rp, val)	mips3_sd((register_t)(MIPS_PHYS_TO_KSEG1(rp)), (val))
    422  1.1  mrg 
    423  1.1  mrg static void
    424  1.1  mrg time_smbus_init(int chan)
    425  1.1  mrg {
    426  1.1  mrg 	uint32_t reg;
    427  1.1  mrg 
    428  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_FREQ);
    429  1.1  mrg 	WRITE_REG(reg, K_SMB_FREQ_100KHZ);
    430  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_CONTROL);
    431  1.1  mrg 	WRITE_REG(reg, 0);	/* not in direct mode, no interrupts, will poll */
    432  1.1  mrg }
    433  1.1  mrg 
    434  1.1  mrg static int
    435  1.1  mrg time_waitready(int chan)
    436  1.1  mrg {
    437  1.1  mrg 	uint32_t reg;
    438  1.1  mrg 	uint64_t status;
    439  1.1  mrg 
    440  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_STATUS);
    441  1.1  mrg 
    442  1.1  mrg 	for (;;) {
    443  1.1  mrg 		status = READ_REG(reg);
    444  1.1  mrg 		if (status & M_SMB_BUSY)
    445  1.1  mrg 			continue;
    446  1.1  mrg 		break;
    447  1.1  mrg 	}
    448  1.1  mrg 
    449  1.1  mrg 	if (status & M_SMB_ERROR) {
    450  1.1  mrg 		WRITE_REG(reg, (status & M_SMB_ERROR));
    451  1.1  mrg 		return (-1);
    452  1.1  mrg 	}
    453  1.1  mrg 	return (0);
    454  1.1  mrg }
    455  1.1  mrg 
    456  1.1  mrg static int
    457  1.1  mrg time_readrtc(int chan, int slaveaddr, int devaddr, int type)
    458  1.1  mrg {
    459  1.1  mrg 	uint32_t reg;
    460  1.1  mrg 	int err;
    461  1.1  mrg 
    462  1.1  mrg 	/*
    463  1.1  mrg 	 * Make sure the bus is idle (probably should
    464  1.1  mrg 	 * ignore error here)
    465  1.1  mrg 	 */
    466  1.1  mrg 
    467  1.1  mrg 	if (time_waitready(chan) < 0)
    468  1.1  mrg 		return (-1);
    469  1.1  mrg 
    470  1.1  mrg 	if (type == SMB_2BYTE_ADDR) {
    471  1.1  mrg 		/*
    472  1.1  mrg 		 * Write the device address to the controller. There are two
    473  1.1  mrg 		 * parts, the high part goes in the "CMD" field, and the
    474  1.1  mrg 		 * low part is the data field.
    475  1.1  mrg 		 */
    476  1.1  mrg 
    477  1.1  mrg 		reg = A_SMB_REGISTER(chan, R_SMB_CMD);
    478  1.1  mrg 		WRITE_REG(reg, (devaddr >> 8) & 0x7);
    479  1.1  mrg 
    480  1.1  mrg 		/*
    481  1.1  mrg 		 * Write the data to the controller
    482  1.1  mrg 		 */
    483  1.1  mrg 
    484  1.1  mrg 		reg = A_SMB_REGISTER(chan, R_SMB_DATA);
    485  1.1  mrg 		WRITE_REG(reg, (devaddr & 0xff) & 0xff);
    486  1.1  mrg 	} else { /* SMB_1BYTE_ADDR */
    487  1.1  mrg 		/*
    488  1.1  mrg 		 * Write the device address to the controller.
    489  1.1  mrg 		 */
    490  1.1  mrg 
    491  1.1  mrg 		reg = A_SMB_REGISTER(chan, R_SMB_CMD);
    492  1.1  mrg 		WRITE_REG(reg, devaddr & 0xff);
    493  1.1  mrg 	}
    494  1.1  mrg 
    495  1.1  mrg 	/*
    496  1.1  mrg 	 * Start the command
    497  1.1  mrg 	 */
    498  1.1  mrg 
    499  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_START);
    500  1.1  mrg 	if (type == SMB_2BYTE_ADDR)
    501  1.1  mrg 		WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR2BYTE) | V_SMB_ADDR(slaveaddr));
    502  1.1  mrg 	else /* SMB_1BYTE_ADDR */
    503  1.1  mrg 		WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR1BYTE) | V_SMB_ADDR(slaveaddr));
    504  1.1  mrg 
    505  1.1  mrg 	/*
    506  1.1  mrg 	 * Wait till done
    507  1.1  mrg 	 */
    508  1.1  mrg 
    509  1.1  mrg 	err = time_waitready(chan);
    510  1.1  mrg 	if (err < 0)
    511  1.1  mrg 		return (err);
    512  1.1  mrg 
    513  1.1  mrg 	/*
    514  1.1  mrg 	 * Read the data byte
    515  1.1  mrg 	 */
    516  1.1  mrg 
    517  1.1  mrg 	WRITE_REG(reg, V_SMB_TT(K_SMB_TT_RD1BYTE) | V_SMB_ADDR(slaveaddr));
    518  1.1  mrg 
    519  1.1  mrg 	err = time_waitready(chan);
    520  1.1  mrg 	if (err < 0)
    521  1.1  mrg 		return (err);
    522  1.1  mrg 
    523  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_DATA);
    524  1.1  mrg 	err = READ_REG(reg);
    525  1.1  mrg 
    526  1.1  mrg 	return (err & 0xff);
    527  1.1  mrg }
    528  1.1  mrg 
    529  1.1  mrg static int
    530  1.1  mrg time_writertc(int chan, int slaveaddr, int devaddr, int type, int b)
    531  1.1  mrg {
    532  1.1  mrg 	uint32_t reg;
    533  1.1  mrg 	int err, timer;
    534  1.1  mrg 
    535  1.1  mrg 	/*
    536  1.1  mrg 	 * Make sure the bus is idle (probably should
    537  1.1  mrg 	 * ignore error here)
    538  1.1  mrg 	 */
    539  1.1  mrg 
    540  1.1  mrg 	if (time_waitready(chan) < 0)
    541  1.1  mrg 		return (-1);
    542  1.1  mrg 
    543  1.1  mrg 	/*
    544  1.1  mrg 	 * Write the device address to the controller. There are two
    545  1.1  mrg 	 * parts, the high part goes in the "CMD" field, and the
    546  1.1  mrg 	 * low part is the data field.
    547  1.1  mrg 	 */
    548  1.1  mrg 
    549  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_CMD);
    550  1.1  mrg 	if (type == SMB_2BYTE_ADDR)
    551  1.1  mrg 		WRITE_REG(reg, (devaddr >> 8) & 0x7);
    552  1.1  mrg 	else /* SMB_1BYTE_ADDR */
    553  1.1  mrg 		WRITE_REG(reg, devaddr & 0xff);
    554  1.1  mrg 
    555  1.1  mrg 	/*
    556  1.1  mrg 	 * Write the data to the controller
    557  1.1  mrg 	 */
    558  1.1  mrg 
    559  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_DATA);
    560  1.1  mrg 	if (type == SMB_2BYTE_ADDR)
    561  1.1  mrg 		WRITE_REG(reg, (devaddr & 0xff) | ((b & 0xff) << 8));
    562  1.1  mrg 	else /* SMB_1BYTE_ADDR */
    563  1.1  mrg 		WRITE_REG(reg, b & 0xff);
    564  1.1  mrg 
    565  1.1  mrg 	/*
    566  1.1  mrg 	 * Start the command.  Keep pounding on the device until it
    567  1.1  mrg 	 * submits or the timer expires, whichever comes first.  The
    568  1.1  mrg 	 * datasheet says writes can take up to 10ms, so we'll give it 500.
    569  1.1  mrg 	 */
    570  1.1  mrg 
    571  1.1  mrg 	reg = A_SMB_REGISTER(chan, R_SMB_START);
    572  1.1  mrg 	if (type == SMB_2BYTE_ADDR)
    573  1.1  mrg 		WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR3BYTE) | V_SMB_ADDR(slaveaddr));
    574  1.1  mrg 	else /* SMB_1BYTE_ADDR */
    575  1.1  mrg 		WRITE_REG(reg, V_SMB_TT(K_SMB_TT_WR2BYTE) | V_SMB_ADDR(slaveaddr));
    576  1.1  mrg 
    577  1.1  mrg 	/*
    578  1.1  mrg 	 * Wait till the SMBus interface is done
    579  1.1  mrg 	 */
    580  1.1  mrg 
    581  1.1  mrg 	err = time_waitready(chan);
    582  1.1  mrg 	if (err < 0)
    583  1.1  mrg 		return (err);
    584  1.1  mrg 
    585  1.1  mrg 	/*
    586  1.1  mrg 	 * Pound on the device with a current address read
    587  1.1  mrg 	 * to poll for the write complete
    588  1.1  mrg 	 */
    589  1.1  mrg 
    590  1.1  mrg 	err = -1;
    591  1.1  mrg 	timer = 100000000;	/* XXX */
    592  1.1  mrg 
    593  1.1  mrg 	while (timer-- > 0) {
    594  1.1  mrg 		WRITE_REG(reg, V_SMB_TT(K_SMB_TT_RD1BYTE) | V_SMB_ADDR(slaveaddr));
    595  1.1  mrg 
    596  1.1  mrg 		err = time_waitready(chan);
    597  1.1  mrg 		if (err == 0)
    598  1.1  mrg 			break;
    599  1.1  mrg 	}
    600  1.1  mrg 
    601  1.1  mrg 	return (err);
    602  1.1  mrg }
    603