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