xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/rtc/rtc.c (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
17d116dccSCC Ma /*
27d116dccSCC Ma  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
37d116dccSCC Ma  *
4*82cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
57d116dccSCC Ma  */
67d116dccSCC Ma #include <assert.h>
77d116dccSCC Ma #include <debug.h>
87d116dccSCC Ma #include <delay_timer.h>
97d116dccSCC Ma #include <mt8173_def.h>
107d116dccSCC Ma #include <pmic_wrap_init.h>
117d116dccSCC Ma #include <rtc.h>
127d116dccSCC Ma 
137d116dccSCC Ma /* RTC busy status polling interval and retry count */
147d116dccSCC Ma enum {
157d116dccSCC Ma 	RTC_WRTGR_POLLING_DELAY_MS	= 10,
167d116dccSCC Ma 	RTC_WRTGR_POLLING_CNT		= 100
177d116dccSCC Ma };
187d116dccSCC Ma 
197d116dccSCC Ma static uint16_t RTC_Read(uint32_t addr)
207d116dccSCC Ma {
217d116dccSCC Ma 	uint32_t rdata = 0;
227d116dccSCC Ma 
237d116dccSCC Ma 	pwrap_read((uint32_t)addr, &rdata);
247d116dccSCC Ma 	return (uint16_t)rdata;
257d116dccSCC Ma }
267d116dccSCC Ma 
277d116dccSCC Ma static void RTC_Write(uint32_t addr, uint16_t data)
287d116dccSCC Ma {
297d116dccSCC Ma 	pwrap_write((uint32_t)addr, (uint32_t)data);
307d116dccSCC Ma }
317d116dccSCC Ma 
327d116dccSCC Ma static inline int32_t rtc_busy_wait(void)
337d116dccSCC Ma {
347d116dccSCC Ma 	uint64_t retry = RTC_WRTGR_POLLING_CNT;
357d116dccSCC Ma 
367d116dccSCC Ma 	do {
377d116dccSCC Ma 		mdelay(RTC_WRTGR_POLLING_DELAY_MS);
387d116dccSCC Ma 		if (!(RTC_Read(RTC_BBPU) & RTC_BBPU_CBUSY))
397d116dccSCC Ma 			return 1;
407d116dccSCC Ma 		retry--;
417d116dccSCC Ma 	} while (retry);
427d116dccSCC Ma 
437d116dccSCC Ma 	ERROR("[RTC] rtc cbusy time out!\n");
447d116dccSCC Ma 	return 0;
457d116dccSCC Ma }
467d116dccSCC Ma 
477d116dccSCC Ma static int32_t Write_trigger(void)
487d116dccSCC Ma {
497d116dccSCC Ma 	RTC_Write(RTC_WRTGR, 1);
507d116dccSCC Ma 	return rtc_busy_wait();
517d116dccSCC Ma }
527d116dccSCC Ma 
537d116dccSCC Ma static int32_t Writeif_unlock(void)
547d116dccSCC Ma {
557d116dccSCC Ma 	RTC_Write(RTC_PROT, RTC_PROT_UNLOCK1);
567d116dccSCC Ma 	if (!Write_trigger())
577d116dccSCC Ma 		return 0;
587d116dccSCC Ma 	RTC_Write(RTC_PROT, RTC_PROT_UNLOCK2);
597d116dccSCC Ma 	if (!Write_trigger())
607d116dccSCC Ma 		return 0;
617d116dccSCC Ma 
627d116dccSCC Ma 	return 1;
637d116dccSCC Ma }
647d116dccSCC Ma 
657d116dccSCC Ma void rtc_bbpu_power_down(void)
667d116dccSCC Ma {
677d116dccSCC Ma 	uint16_t bbpu;
687d116dccSCC Ma 
697d116dccSCC Ma 	/* pull PWRBB low */
707d116dccSCC Ma 	bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_PWREN;
717d116dccSCC Ma 	if (Writeif_unlock()) {
727d116dccSCC Ma 		RTC_Write(RTC_BBPU, bbpu);
737d116dccSCC Ma 		if (!Write_trigger())
74b99d961cSJimmy Huang 			assert(0);
757d116dccSCC Ma 	} else {
76b99d961cSJimmy Huang 		assert(0);
777d116dccSCC Ma 	}
787d116dccSCC Ma }
79