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