xref: /onnv-gate/usr/src/uts/sun4u/io/todm5819p_rmc.c (revision 11752:9c475fee0b48)
14135Sgd78059 /*
24135Sgd78059  * CDDL HEADER START
34135Sgd78059  *
44135Sgd78059  * The contents of this file are subject to the terms of the
54135Sgd78059  * Common Development and Distribution License (the "License").
64135Sgd78059  * You may not use this file except in compliance with the License.
74135Sgd78059  *
84135Sgd78059  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94135Sgd78059  * or http://www.opensolaris.org/os/licensing.
104135Sgd78059  * See the License for the specific language governing permissions
114135Sgd78059  * and limitations under the License.
124135Sgd78059  *
134135Sgd78059  * When distributing Covered Code, include this CDDL HEADER in each
144135Sgd78059  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154135Sgd78059  * If applicable, add the following below this CDDL HEADER, with the
164135Sgd78059  * fields enclosed by brackets "[]" replaced with your own identifying
174135Sgd78059  * information: Portions Copyright [yyyy] [name of copyright owner]
184135Sgd78059  *
194135Sgd78059  * CDDL HEADER END
204135Sgd78059  */
214135Sgd78059 /*
22*11752STrevor.Thompson@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
234135Sgd78059  * Use is subject to license terms.
244135Sgd78059  */
254135Sgd78059 
264135Sgd78059 
274135Sgd78059 /*
284135Sgd78059  * tod driver module for ALI M5819P part
294135Sgd78059  */
304135Sgd78059 
314135Sgd78059 #include <sys/types.h>
324135Sgd78059 #include <sys/conf.h>
334135Sgd78059 #include <sys/kmem.h>
344135Sgd78059 #include <sys/open.h>
354135Sgd78059 #include <sys/ddi.h>
364135Sgd78059 #include <sys/sunddi.h>
374135Sgd78059 
384135Sgd78059 #include <sys/todm5819p.h>
394135Sgd78059 #include <sys/rmc_comm_dp.h>
404135Sgd78059 #include <sys/rmc_comm_drvintf.h>
414135Sgd78059 #include <sys/modctl.h>
424135Sgd78059 #include <sys/stat.h>
434135Sgd78059 #include <sys/clock.h>
444135Sgd78059 #include <sys/reboot.h>
454135Sgd78059 #include <sys/machsystm.h>
464135Sgd78059 
474135Sgd78059 static timestruc_t	todm5819p_rmc_get(void);
484135Sgd78059 static void		todm5819p_rmc_set(timestruc_t);
494135Sgd78059 static uint_t		todm5819p_rmc_set_watchdog_timer(uint_t);
504135Sgd78059 static uint_t		todm5819p_rmc_clear_watchdog_timer(void);
514135Sgd78059 static void		todm5819p_rmc_set_power_alarm(timestruc_t);
524135Sgd78059 static void		todm5819p_rmc_clear_power_alarm(void);
534135Sgd78059 static uint64_t		todm5819p_rmc_get_cpufrequency(void);
544135Sgd78059 
554135Sgd78059 extern uint64_t		find_cpufrequency(volatile uint8_t *);
564135Sgd78059 
574135Sgd78059 /*
584135Sgd78059  * External variables
594135Sgd78059  */
604135Sgd78059 extern int	watchdog_enable;
614135Sgd78059 extern int	watchdog_available;
624135Sgd78059 extern int	boothowto;
634135Sgd78059 
644135Sgd78059 /*
654135Sgd78059  * Global variables
664135Sgd78059  */
674135Sgd78059 int m5819p_debug_flags;
684135Sgd78059 
694135Sgd78059 /*
704135Sgd78059  * Module linkage information for the kernel.
714135Sgd78059  */
724135Sgd78059 static struct modlmisc modlmisc = {
734135Sgd78059 	&mod_miscops, "tod module for ALI M5819P"
744135Sgd78059 };
754135Sgd78059 
764135Sgd78059 static struct modlinkage modlinkage = {
774135Sgd78059 	MODREV_1, (void *)&modlmisc, NULL
784135Sgd78059 };
794135Sgd78059 
804135Sgd78059 static todinfo_t rtc_to_tod(struct rtc_t *);
814135Sgd78059 static void read_rtc(struct rtc_t *);
824135Sgd78059 static void write_rtc_time(struct rtc_t *);
834135Sgd78059 static void write_rtc_alarm(struct rtc_t *);
844135Sgd78059 
854135Sgd78059 
864135Sgd78059 int
_init(void)874135Sgd78059 _init(void)
884135Sgd78059 {
894135Sgd78059 	if (strcmp(tod_module_name, "todm5819p_rmc") == 0) {
904135Sgd78059 		M5819P_ADDR_REG = RTC_B;
914135Sgd78059 		M5819P_DATA_REG = (RTC_DM | RTC_HM);
924135Sgd78059 
934135Sgd78059 		tod_ops.tod_get = todm5819p_rmc_get;
944135Sgd78059 		tod_ops.tod_set = todm5819p_rmc_set;
954135Sgd78059 
964135Sgd78059 		tod_ops.tod_set_watchdog_timer =
974135Sgd78059 		    todm5819p_rmc_set_watchdog_timer;
984135Sgd78059 		tod_ops.tod_clear_watchdog_timer =
994135Sgd78059 		    todm5819p_rmc_clear_watchdog_timer;
1004135Sgd78059 		tod_ops.tod_set_power_alarm = todm5819p_rmc_set_power_alarm;
1014135Sgd78059 		tod_ops.tod_clear_power_alarm = todm5819p_rmc_clear_power_alarm;
1024135Sgd78059 		tod_ops.tod_get_cpufrequency = todm5819p_rmc_get_cpufrequency;
1034135Sgd78059 		if (boothowto & RB_DEBUG) {
1044135Sgd78059 			cmn_err(CE_WARN, "todm5819p_rmc: kernel debugger "
1054135Sgd78059 			    "detected: hardware watchdog disabled");
1064135Sgd78059 		}
1074135Sgd78059 	}
1084135Sgd78059 
1094135Sgd78059 	return (mod_install(&modlinkage));
1104135Sgd78059 }
1114135Sgd78059 
1124135Sgd78059 int
_fini(void)1134135Sgd78059 _fini(void)
1144135Sgd78059 {
1154135Sgd78059 	if (strcmp(tod_module_name, "todm5819p_rmc") == 0)
1164135Sgd78059 		return (EBUSY);
1174135Sgd78059 
1184135Sgd78059 	return (mod_remove(&modlinkage));
1194135Sgd78059 }
1204135Sgd78059 
1214135Sgd78059 /*
1224135Sgd78059  * The loadable-module _info(9E) entry point
1234135Sgd78059  */
1244135Sgd78059 int
_info(struct modinfo * modinfop)1254135Sgd78059 _info(struct modinfo *modinfop)
1264135Sgd78059 {
1274135Sgd78059 	return (mod_info(&modlinkage, modinfop));
1284135Sgd78059 }
1294135Sgd78059 
1304135Sgd78059 
1314135Sgd78059 /*
1324135Sgd78059  * Read the current time from the clock chip and convert to UNIX form.
133*11752STrevor.Thompson@Sun.COM  * Assumes that the year in the clock chip is valid.
1344135Sgd78059  * Must be called with tod_lock held.
1354135Sgd78059  */
1364135Sgd78059 static timestruc_t
todm5819p_rmc_get(void)1374135Sgd78059 todm5819p_rmc_get(void)
1384135Sgd78059 {
1394135Sgd78059 	int i;
1404135Sgd78059 	int s;
1414135Sgd78059 	timestruc_t ts;
1424135Sgd78059 	struct rtc_t rtc;
1434135Sgd78059 
1444135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
1454135Sgd78059 
1464135Sgd78059 	/* set the hw watchdog timer if it's been activated */
1474135Sgd78059 	if (watchdog_activated) {
1484135Sgd78059 		int ret = 0;
1494135Sgd78059 		ret = tod_ops.tod_set_watchdog_timer(0);
1504135Sgd78059 		/*
1514135Sgd78059 		 * The empty set_watchdog routine returns a 0. So if a
1524135Sgd78059 		 * coded routine fails we will look for a -1 for a failure.
1534135Sgd78059 		 */
1544135Sgd78059 		if (ret == -1)
1554135Sgd78059 			cmn_err(CE_WARN, "todm5819p: failed to set hardware "
1567396SJustin.Frank@Sun.COM 			    "watchdog timer.");
1574135Sgd78059 	}
1584135Sgd78059 
1594135Sgd78059 	/*
1604135Sgd78059 	 * Read current time from the tod. If the tod isn't accessible, wait and
1614135Sgd78059 	 * retry.
1624135Sgd78059 	 * Run critical in the time critical section to avoid being interrupted
1634135Sgd78059 	 */
1644135Sgd78059 	for (i = 0; i < TODM5819_UIP_RETRY_THRESH; i++) {
1654135Sgd78059 		s = ddi_enter_critical();
1664135Sgd78059 		M5819P_ADDR_REG = RTC_A;
1674135Sgd78059 		if (!(M5819P_DATA_REG & RTC_UIP)) {
1684135Sgd78059 			read_rtc(&rtc);
1694135Sgd78059 			ddi_exit_critical(s);
1704135Sgd78059 			break;
1714135Sgd78059 		}
1724135Sgd78059 		ddi_exit_critical(s);
1734135Sgd78059 		drv_usecwait(TODM5819_UIP_WAIT_USEC);
1744135Sgd78059 	}
1754135Sgd78059 	if (i == TODM5819_UIP_RETRY_THRESH) {
1764135Sgd78059 		/*
1774135Sgd78059 		 * tod is inaccessible: just return current software time
1784135Sgd78059 		 */
179*11752STrevor.Thompson@Sun.COM 		tod_status_set(TOD_GET_FAILED);
1804135Sgd78059 		return (hrestime);
1814135Sgd78059 	}
1824135Sgd78059 
183*11752STrevor.Thompson@Sun.COM 	/* read was successful so ensure failure flag is clear */
184*11752STrevor.Thompson@Sun.COM 	tod_status_clear(TOD_GET_FAILED);
1857396SJustin.Frank@Sun.COM 
1864135Sgd78059 	ts.tv_sec = tod_to_utc(rtc_to_tod(&rtc));
1874135Sgd78059 	ts.tv_nsec = 0;
1884135Sgd78059 	return (ts);
1894135Sgd78059 }
1904135Sgd78059 
1914135Sgd78059 static todinfo_t
rtc_to_tod(struct rtc_t * rtc)1924135Sgd78059 rtc_to_tod(struct rtc_t *rtc)
1934135Sgd78059 {
1944135Sgd78059 	todinfo_t tod;
1954135Sgd78059 
1964135Sgd78059 	/*
1974135Sgd78059 	 * tod_year is base 1900 so this code needs to adjust the true year
1984135Sgd78059 	 * retrieved from the rtc's century and year fields.
1994135Sgd78059 	 */
2004135Sgd78059 	tod.tod_year	= rtc->rtc_year + (rtc->rtc_century * 100) - 1900;
2014135Sgd78059 	tod.tod_month	= rtc->rtc_mon;
2024135Sgd78059 	tod.tod_day	= rtc->rtc_dom;
2034135Sgd78059 	tod.tod_dow	= rtc->rtc_dow;
2044135Sgd78059 	tod.tod_hour	= rtc->rtc_hrs;
2054135Sgd78059 	tod.tod_min	= rtc->rtc_min;
2064135Sgd78059 	tod.tod_sec	= rtc->rtc_sec;
2074135Sgd78059 
2084135Sgd78059 	return (tod);
2094135Sgd78059 }
2104135Sgd78059 
2114135Sgd78059 static void
read_rtc(struct rtc_t * rtc)2124135Sgd78059 read_rtc(struct rtc_t *rtc)
2134135Sgd78059 {
2144135Sgd78059 	M5819P_ADDR_REG = RTC_SEC;
2154135Sgd78059 	rtc->rtc_sec = M5819P_DATA_REG;
2164135Sgd78059 	M5819P_ADDR_REG = RTC_ASEC;
2174135Sgd78059 	rtc->rtc_asec = M5819P_DATA_REG;
2184135Sgd78059 	M5819P_ADDR_REG = RTC_MIN;
2194135Sgd78059 	rtc->rtc_min = M5819P_DATA_REG;
2204135Sgd78059 	M5819P_ADDR_REG = RTC_AMIN;
2214135Sgd78059 	rtc->rtc_amin = M5819P_DATA_REG;
2224135Sgd78059 	M5819P_ADDR_REG = RTC_HRS;
2234135Sgd78059 	rtc->rtc_hrs = M5819P_DATA_REG;
2244135Sgd78059 	M5819P_ADDR_REG = RTC_AHRS;
2254135Sgd78059 	rtc->rtc_ahrs = M5819P_DATA_REG;
2264135Sgd78059 	M5819P_ADDR_REG = RTC_DOW;
2274135Sgd78059 	rtc->rtc_dow = M5819P_DATA_REG;
2284135Sgd78059 	M5819P_ADDR_REG = RTC_DOM;
2294135Sgd78059 	rtc->rtc_dom = M5819P_DATA_REG;
2304135Sgd78059 	M5819P_ADDR_REG = RTC_MON;
2314135Sgd78059 	rtc->rtc_mon = M5819P_DATA_REG;
2324135Sgd78059 	M5819P_ADDR_REG = RTC_YEAR;
2334135Sgd78059 	rtc->rtc_year = M5819P_DATA_REG;
2344135Sgd78059 	M5819P_ADDR_REG = RTC_CENTURY;
2354135Sgd78059 	rtc->rtc_century = M5819P_DATA_REG;
2364135Sgd78059 
2374135Sgd78059 	/* Read date alarm */
2384135Sgd78059 	M5819P_ADDR_REG = RTC_ADOM_REG;
2394135Sgd78059 	rtc->rtc_adom = (M5819P_DATA_REG) & RTC_ADOM;
2404135Sgd78059 }
2414135Sgd78059 
2424135Sgd78059 /*
2434135Sgd78059  * Write the specified time into the clock chip.
2444135Sgd78059  * Must be called with tod_lock held.
2454135Sgd78059  */
2464135Sgd78059 static void
todm5819p_rmc_set(timestruc_t ts)2474135Sgd78059 todm5819p_rmc_set(timestruc_t ts)
2484135Sgd78059 {
2494135Sgd78059 	struct rtc_t	rtc;
2504135Sgd78059 	todinfo_t tod = utc_to_tod(ts.tv_sec);
2514135Sgd78059 	int year;
2524135Sgd78059 	rmc_comm_msg_t request;
2534135Sgd78059 	dp_set_date_time_t set_time_msg;
2544135Sgd78059 
2554135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
2564135Sgd78059 
2574135Sgd78059 	/* tod_year is base 1900 so this code needs to adjust */
2584135Sgd78059 	year = 1900 + tod.tod_year;
2594135Sgd78059 	rtc.rtc_year	= year % 100;
2604135Sgd78059 	rtc.rtc_century = year / 100;
2614135Sgd78059 	rtc.rtc_mon	= (uint8_t)tod.tod_month;
2624135Sgd78059 	rtc.rtc_dom	= (uint8_t)tod.tod_day;
2634135Sgd78059 	rtc.rtc_dow	= (uint8_t)tod.tod_dow;
2644135Sgd78059 	rtc.rtc_hrs	= (uint8_t)tod.tod_hour;
2654135Sgd78059 	rtc.rtc_min	= (uint8_t)tod.tod_min;
2664135Sgd78059 	rtc.rtc_sec	= (uint8_t)tod.tod_sec;
2674135Sgd78059 
2684135Sgd78059 	write_rtc_time(&rtc);
2694135Sgd78059 
2704135Sgd78059 	set_time_msg.year	= year - 1900;
2714135Sgd78059 	set_time_msg.month	= tod.tod_month - 1;
2724135Sgd78059 	set_time_msg.day	= tod.tod_day;
2734135Sgd78059 	set_time_msg.hour	= tod.tod_hour;
2744135Sgd78059 	set_time_msg.minute	= tod.tod_min;
2754135Sgd78059 	set_time_msg.second	= tod.tod_sec;
2764135Sgd78059 
2774135Sgd78059 	request.msg_type = DP_SET_DATE_TIME;
2784135Sgd78059 	request.msg_len = sizeof (set_time_msg);
2794135Sgd78059 	request.msg_buf = (caddr_t)&set_time_msg;
2804135Sgd78059 
2814135Sgd78059 	(void) rmc_comm_request_nowait(&request, 0);
2824135Sgd78059 }
2834135Sgd78059 
2844135Sgd78059 void
write_rtc_time(struct rtc_t * rtc)2854135Sgd78059 write_rtc_time(struct rtc_t *rtc)
2864135Sgd78059 {
2874135Sgd78059 	uint8_t	regb;
288*11752STrevor.Thompson@Sun.COM 	int	i;
2894135Sgd78059 
2904135Sgd78059 	/*
2914135Sgd78059 	 * Freeze
2924135Sgd78059 	 */
2934135Sgd78059 	M5819P_ADDR_REG = RTC_B;
2944135Sgd78059 	regb = M5819P_DATA_REG;
2954135Sgd78059 	M5819P_DATA_REG = (regb | RTC_SET);
2964135Sgd78059 
297*11752STrevor.Thompson@Sun.COM 	/*
298*11752STrevor.Thompson@Sun.COM 	 * If an update cycle is in progress wait for the UIP flag to
299*11752STrevor.Thompson@Sun.COM 	 * clear.  If we write whilst UIP is still set there is a slight
300*11752STrevor.Thompson@Sun.COM 	 * but real possibility of corrupting the RTC date and time
301*11752STrevor.Thompson@Sun.COM 	 * registers.
302*11752STrevor.Thompson@Sun.COM 	 *
303*11752STrevor.Thompson@Sun.COM 	 * The expected wait is one internal cycle of the chip.  We could
304*11752STrevor.Thompson@Sun.COM 	 * simply spin but this may hang a CPU if we were to have a broken
305*11752STrevor.Thompson@Sun.COM 	 * RTC chip where UIP is stuck, so we use a retry loop instead.
306*11752STrevor.Thompson@Sun.COM 	 * No critical section is needed here as the UIP flag will not be
307*11752STrevor.Thompson@Sun.COM 	 * re-asserted until we clear RTC_SET.
308*11752STrevor.Thompson@Sun.COM 	 */
309*11752STrevor.Thompson@Sun.COM 	M5819P_ADDR_REG = RTC_A;
310*11752STrevor.Thompson@Sun.COM 	for (i = 0; i < TODM5819_UIP_RETRY_THRESH; i++) {
311*11752STrevor.Thompson@Sun.COM 		if (!(M5819P_DATA_REG & RTC_UIP)) {
312*11752STrevor.Thompson@Sun.COM 			break;
313*11752STrevor.Thompson@Sun.COM 		}
314*11752STrevor.Thompson@Sun.COM 		drv_usecwait(TODM5819_UIP_WAIT_USEC);
315*11752STrevor.Thompson@Sun.COM 	}
316*11752STrevor.Thompson@Sun.COM 	if (i < TODM5819_UIP_RETRY_THRESH) {
317*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_SEC;
318*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_sec;
319*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_MIN;
320*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_min;
321*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_HRS;
322*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_hrs;
323*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_DOW;
324*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_dow;
325*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_DOM;
326*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_dom;
327*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_MON;
328*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_mon;
329*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_YEAR;
330*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_year;
331*11752STrevor.Thompson@Sun.COM 		M5819P_ADDR_REG = RTC_CENTURY;
332*11752STrevor.Thompson@Sun.COM 		M5819P_DATA_REG = rtc->rtc_century;
333*11752STrevor.Thompson@Sun.COM 	} else {
334*11752STrevor.Thompson@Sun.COM 		cmn_err(CE_WARN, "todm5819p_rmc: Could not write the RTC\n");
335*11752STrevor.Thompson@Sun.COM 	}
3364135Sgd78059 
3374135Sgd78059 	/*
3384135Sgd78059 	 * Unfreeze
3394135Sgd78059 	 */
3404135Sgd78059 	M5819P_ADDR_REG = RTC_B;
3414135Sgd78059 	M5819P_DATA_REG = regb;
3424135Sgd78059 }
3434135Sgd78059 
3444135Sgd78059 void
write_rtc_alarm(struct rtc_t * rtc)3454135Sgd78059 write_rtc_alarm(struct rtc_t *rtc)
3464135Sgd78059 {
3474135Sgd78059 	M5819P_ADDR_REG = RTC_ASEC;
3484135Sgd78059 	M5819P_DATA_REG = rtc->rtc_asec;
3494135Sgd78059 	M5819P_ADDR_REG = RTC_AMIN;
3504135Sgd78059 	M5819P_DATA_REG = rtc->rtc_amin;
3514135Sgd78059 	M5819P_ADDR_REG = RTC_AHRS;
3524135Sgd78059 	M5819P_DATA_REG = rtc->rtc_ahrs;
3534135Sgd78059 
3544135Sgd78059 	M5819P_ADDR_REG = RTC_ADOM_REG;
3554135Sgd78059 	M5819P_DATA_REG = rtc->rtc_adom;
3564135Sgd78059 }
3574135Sgd78059 
3584135Sgd78059 /*
3594135Sgd78059  * program the rtc registers for alarm to go off at the specified time
3604135Sgd78059  */
3614135Sgd78059 static void
todm5819p_rmc_set_power_alarm(timestruc_t ts)3624135Sgd78059 todm5819p_rmc_set_power_alarm(timestruc_t ts)
3634135Sgd78059 {
3644135Sgd78059 	todinfo_t	tod;
3654135Sgd78059 	uint8_t		regb;
3664135Sgd78059 	struct rtc_t	rtc;
3674135Sgd78059 
3684135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
3694135Sgd78059 	tod = utc_to_tod(ts.tv_sec);
3704135Sgd78059 
3714135Sgd78059 	/*
3724135Sgd78059 	 * disable alarms and clear AF flag by reading reg C
3734135Sgd78059 	 */
3744135Sgd78059 	M5819P_ADDR_REG = RTC_B;
3754135Sgd78059 	regb = M5819P_DATA_REG;
3764135Sgd78059 	M5819P_DATA_REG = regb & ~RTC_AIE;
3774135Sgd78059 	M5819P_ADDR_REG = RTC_C;
3784135Sgd78059 	(void) M5819P_DATA_REG;
3794135Sgd78059 
3804135Sgd78059 	rtc.rtc_asec = (uint8_t)tod.tod_sec;
3814135Sgd78059 	rtc.rtc_amin = (uint8_t)tod.tod_min;
3824135Sgd78059 	rtc.rtc_ahrs = (uint8_t)tod.tod_hour;
3834135Sgd78059 	rtc.rtc_adom = (uint8_t)tod.tod_day;
3844135Sgd78059 
3854135Sgd78059 	/*
3864135Sgd78059 	 * Write alarm values and enable alarm
3874135Sgd78059 	 */
3884135Sgd78059 	write_rtc_alarm(&rtc);
3894135Sgd78059 
3904135Sgd78059 	M5819P_ADDR_REG = RTC_B;
3914135Sgd78059 	M5819P_DATA_REG = regb | RTC_AIE;
3924135Sgd78059 }
3934135Sgd78059 
3944135Sgd78059 /*
3954135Sgd78059  * clear alarm interrupt
3964135Sgd78059  */
3974135Sgd78059 static void
todm5819p_rmc_clear_power_alarm(void)3984135Sgd78059 todm5819p_rmc_clear_power_alarm(void)
3994135Sgd78059 {
4004135Sgd78059 	uint8_t regb;
4014135Sgd78059 
4024135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
4034135Sgd78059 
4044135Sgd78059 	M5819P_ADDR_REG = RTC_B;
4054135Sgd78059 	regb = M5819P_DATA_REG;
4064135Sgd78059 	M5819P_DATA_REG = regb & ~RTC_AIE;
4074135Sgd78059 }
4084135Sgd78059 
4094135Sgd78059 /*
4104135Sgd78059  * Determine the cpu frequency by watching the TOD chip rollover twice.
4114135Sgd78059  * Cpu clock rate is determined by computing the ticks added (in tick register)
4124135Sgd78059  * during one second interval on TOD.
4134135Sgd78059  */
4144135Sgd78059 uint64_t
todm5819p_rmc_get_cpufrequency(void)4154135Sgd78059 todm5819p_rmc_get_cpufrequency(void)
4164135Sgd78059 {
4174135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
4184135Sgd78059 	M5819P_ADDR_REG = RTC_SEC;
4194135Sgd78059 	return (find_cpufrequency(v_rtc_data_reg));
4204135Sgd78059 }
4214135Sgd78059 
4224135Sgd78059 /*ARGSUSED*/
4234135Sgd78059 static uint_t
todm5819p_rmc_set_watchdog_timer(uint_t timeoutval)4244135Sgd78059 todm5819p_rmc_set_watchdog_timer(uint_t timeoutval)
4254135Sgd78059 {
4264135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
4274135Sgd78059 	return (0);
4284135Sgd78059 }
4294135Sgd78059 
4304135Sgd78059 static uint_t
todm5819p_rmc_clear_watchdog_timer(void)4314135Sgd78059 todm5819p_rmc_clear_watchdog_timer(void)
4324135Sgd78059 {
4334135Sgd78059 	ASSERT(MUTEX_HELD(&tod_lock));
4344135Sgd78059 	return (0);
4354135Sgd78059 }
436