summaryrefslogtreecommitdiff
path: root/src/soc/mediatek/mt8183
diff options
context:
space:
mode:
authorRan Bi <ran.bi@mediatek.com>2019-03-19 11:47:21 +0800
committerPatrick Georgi <pgeorgi@google.com>2019-04-02 10:25:42 +0000
commitb197808852a51243ebbcca502319b1e3e4cb4ddb (patch)
treea516fe057c6b173f685f9b869d1034fed7f2f3c6 /src/soc/mediatek/mt8183
parent274613303e31bae9bbfdf0994ffd9bd040e38a1a (diff)
mediatek/mt8183: Fix RTC initialization flow
1. Fix RTC lpd settings. Rewrite powerkeys after lpd init to enable low power detect function. 2. Rearrange RTC initialization flow. 3. Add return status for rtc_init. 4. Add log if calling pwrap_write or pwrap_read fail. 5. Increase timeout time to resolve unexpected timeout. BUG=b:127405695 BRANCH=none TEST=Boots correctly on Kukui Change-Id: I6f26edd6699c2f6d9af80c285b70742b44407136 Signed-off-by: Ran Bi <ran.bi@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/31968 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'src/soc/mediatek/mt8183')
-rw-r--r--src/soc/mediatek/mt8183/include/soc/rtc.h10
-rw-r--r--src/soc/mediatek/mt8183/rtc.c222
2 files changed, 152 insertions, 80 deletions
diff --git a/src/soc/mediatek/mt8183/include/soc/rtc.h b/src/soc/mediatek/mt8183/include/soc/rtc.h
index 08ebe98913..3d115fec41 100644
--- a/src/soc/mediatek/mt8183/include/soc/rtc.h
+++ b/src/soc/mediatek/mt8183/include/soc/rtc.h
@@ -77,7 +77,7 @@ enum {
RTC_BBPU_RELOAD = 1U << 5,
RTC_BBPU_CBUSY = 1U << 6,
- RTC_CBUSY_TIMEOUT_US = 800
+ RTC_CBUSY_TIMEOUT_US = 8000
};
enum {
@@ -106,6 +106,14 @@ enum {
RTC_REG_XOSC32_ENB = 1 << 15
};
+enum {
+ RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0 << 13,
+ RTC_LPD_OPT_EOSC_LPD = 1 << 13,
+ RTC_LPD_OPT_XOSC_LPD = 2 << 13,
+ RTC_LPD_OPT_F32K_CK_ALIVE = 3 << 13,
+ RTC_LPD_OPT_MASK = 3 << 13
+};
+
/* PMIC TOP Register Definition */
enum {
PMIC_RG_SCK_TOP_CON0 = 0x050C
diff --git a/src/soc/mediatek/mt8183/rtc.c b/src/soc/mediatek/mt8183/rtc.c
index d67315b23a..df7501a111 100644
--- a/src/soc/mediatek/mt8183/rtc.c
+++ b/src/soc/mediatek/mt8183/rtc.c
@@ -22,31 +22,37 @@
#define RTC_GPIO_USER_MASK ((1 << 13) - (1 << 8))
/* initialize rtc setting of using dcxo clock */
-static void rtc_enable_dcxo(void)
+static int rtc_enable_dcxo(void)
{
u16 bbpu, con, osc32con, sec;
- pwrap_read(RTC_BBPU, &bbpu);
- pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
+ rtc_read(RTC_BBPU, &bbpu);
+ rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
rtc_write_trigger();
mdelay(1);
- if (!rtc_writeif_unlock()) /* Unlock for reload */
- printk(BIOS_INFO,
- "[RTC] %s rtc_writeif_unlock() fail\n", __func__);
-
- pwrap_read(RTC_OSC32CON, &osc32con);
- rtc_xosc_write((osc32con & ~RTC_EMBCK_SRC_SEL)
- | RTC_XOSC32_ENB | RTC_REG_XOSC32_ENB);
- pwrap_read(RTC_BBPU, &bbpu);
- pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
+ if (!rtc_writeif_unlock()) { /* Unlock for reload */
+ rtc_info("rtc_writeif_unlock() fail\n");
+ return 0;
+ }
+
+ rtc_read(RTC_OSC32CON, &osc32con);
+ osc32con &= ~RTC_EMBCK_SRC_SEL;
+ osc32con |= RTC_XOSC32_ENB | RTC_REG_XOSC32_ENB;
+ if (!rtc_xosc_write(osc32con)) {
+ rtc_info("rtc_xosc_write() fail\n");
+ return 0;
+ }
+ rtc_read(RTC_BBPU, &bbpu);
+ rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
rtc_write_trigger();
- pwrap_read(RTC_CON, &con);
- pwrap_read(RTC_OSC32CON, &osc32con);
- pwrap_read(RTC_AL_SEC, &sec);
- printk(BIOS_INFO, "[RTC] %s con = 0x%x, osc32con = 0x%x, sec = 0x%x\n",
- __func__, con, osc32con, sec);
+ rtc_read(RTC_CON, &con);
+ rtc_read(RTC_OSC32CON, &osc32con);
+ rtc_read(RTC_AL_SEC, &sec);
+ rtc_info("con=0x%x, osc32con=0x%x, sec=0x%x\n", con, osc32con, sec);
+
+ return 1;
}
/* initialize rtc related gpio */
@@ -63,11 +69,13 @@ static int rtc_gpio_init(void)
pwrap_write_field(PMIC_RG_TOP_CKPDN_CON1_CLR, 0x1, 0x1, 1);
/* Export 32K clock RTC_32K2V8 */
- pwrap_read(RTC_CON, &con);
- con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN);
+ rtc_read(RTC_CON, &con);
+ con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN
+ | RTC_CON_XOSC32_LPEN);
con |= (RTC_CON_GPEN | RTC_CON_GOE);
con &= ~(RTC_CON_F32KOB);
- pwrap_write(RTC_CON, con);
+ rtc_write(RTC_CON, con);
+
return rtc_write_trigger();
}
@@ -78,40 +86,60 @@ void rtc_osc_init(void)
rtc_gpio_init();
}
-/* low power detect setting */
-static int rtc_lpd_init(void)
+/* enable lpd subroutine */
+static int rtc_lpen(u16 con)
{
- u16 con;
-
- con = pwrap_read(RTC_CON, &con) | RTC_CON_XOSC32_LPEN;
con &= ~RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
+ rtc_write(RTC_CON, con);
if (!rtc_write_trigger())
return 0;
con |= RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
+ rtc_write(RTC_CON, con);
if (!rtc_write_trigger())
return 0;
con &= ~RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
+ rtc_write(RTC_CON, con);
if (!rtc_write_trigger())
return 0;
- con = pwrap_read(RTC_CON, &con) | RTC_CON_EOSC32_LPEN;
- con &= ~RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
+ return 1;
+}
+
+/* low power detect setting */
+static int rtc_lpd_init(void)
+{
+ u16 con, sec;
+
+ /* set RTC_LPD_OPT */
+ rtc_read(RTC_AL_SEC, &sec);
+ sec |= RTC_LPD_OPT_F32K_CK_ALIVE;
+ rtc_write(RTC_AL_SEC, sec);
if (!rtc_write_trigger())
return 0;
- con |= RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
- if (!rtc_write_trigger())
+ /* init XOSC32 to detect 32k clock stop */
+ rtc_read(RTC_CON, &con);
+ con |= RTC_CON_XOSC32_LPEN;
+ if (!rtc_lpen(con))
return 0;
- con &= ~RTC_CON_LPRST;
- pwrap_write(RTC_CON, con);
+ /* init EOSC32 to detect rtc low power */
+ rtc_read(RTC_CON, &con);
+ con |= RTC_CON_EOSC32_LPEN;
+ if (!rtc_lpen(con))
+ return 0;
+
+ rtc_read(RTC_CON, &con);
+ con &= ~RTC_CON_XOSC32_LPEN;
+ rtc_write(RTC_CON, con);
+
+ /* set RTC_LPD_OPT */
+ rtc_read(RTC_AL_SEC, &sec);
+ sec &= ~RTC_LPD_OPT_MASK;
+ sec |= RTC_LPD_OPT_EOSC_LPD;
+ rtc_write(RTC_AL_SEC, sec);
if (!rtc_write_trigger())
return 0;
@@ -122,56 +150,93 @@ static bool rtc_hw_init(void)
{
u16 bbpu;
- pwrap_read(RTC_BBPU, &bbpu);
- pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_INIT);
+ rtc_read(RTC_BBPU, &bbpu);
+ rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_INIT);
rtc_write_trigger();
udelay(500);
- pwrap_read(RTC_BBPU, &bbpu);
- pwrap_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
+ rtc_read(RTC_BBPU, &bbpu);
+ rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
rtc_write_trigger();
- pwrap_read(RTC_BBPU, &bbpu);
+ rtc_read(RTC_BBPU, &bbpu);
if (bbpu & RTC_BBPU_INIT) {
- printk(BIOS_INFO, "[RTC] %s:%d timeout\n", __func__, __LINE__);
+ rtc_info("timeout\n");
return false;
}
return true;
}
+/* write powerkeys to enable rtc functions */
+static int rtc_powerkey_init(void)
+{
+ rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
+ rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
+ return rtc_write_trigger();
+}
+
/* rtc init check */
int rtc_init(u8 recover)
{
- printk(BIOS_INFO, "[RTC] %s recovery: %d\n", __func__, recover);
+ int ret;
- if (!rtc_writeif_unlock())
- return 0;
+ rtc_info("recovery: %d\n", recover);
- if (!rtc_gpio_init())
- return 0;
+ /* write powerkeys to enable rtc functions */
+ if (!rtc_powerkey_init()) {
+ ret = -RTC_STATUS_POWERKEY_INIT_FAIL;
+ goto err;
+ }
+
+ /* write interface unlock need to be set after powerkey match */
+ if (!rtc_writeif_unlock()) {
+ ret = -RTC_STATUS_WRITEIF_UNLOCK_FAIL;
+ goto err;
+ }
/* using dcxo 32K clock */
- rtc_enable_dcxo();
+ if (!rtc_enable_dcxo()) {
+ ret = -RTC_STATUS_OSC_SETTING_FAIL;
+ goto err;
+ }
if (recover)
mdelay(20);
- /* write powerkeys */
- pwrap_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
- pwrap_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
- if (!rtc_write_trigger())
- return 0;
+ if (!rtc_gpio_init()) {
+ ret = -RTC_STATUS_GPIO_INIT_FAIL;
+ goto err;
+ }
- if (!rtc_reg_init())
- return 0;
- if (!rtc_lpd_init())
- return 0;
- if (!rtc_hw_init())
- return 0;
+ if (!rtc_hw_init()) {
+ ret = -RTC_STATUS_HW_INIT_FAIL;
+ goto err;
+ }
- return 1;
+ if (!rtc_reg_init()) {
+ ret = -RTC_STATUS_REG_INIT_FAIL;
+ goto err;
+ }
+
+ if (!rtc_lpd_init()) {
+ ret = -RTC_STATUS_LPD_INIT_FAIL;
+ goto err;
+ }
+
+ /* After lpd init, powerkeys need to be written again to enable
+ * low power detect function.
+ */
+ if (!rtc_powerkey_init()) {
+ ret = -RTC_STATUS_POWERKEY_INIT_FAIL;
+ goto err;
+ }
+
+ return RTC_STATUS_OK;
+err:
+ rtc_info("init fail: ret=%d\n", ret);
+ return ret;
}
/* enable rtc bbpu */
@@ -185,12 +250,12 @@ void rtc_bbpu_power_on(void)
/* pull PWRBB high */
bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_RELOAD | RTC_BBPU_PWREN;
- pwrap_write(RTC_BBPU, bbpu);
+ rtc_write(RTC_BBPU, bbpu);
ret = rtc_write_trigger();
- printk(BIOS_INFO, "[RTC] %s rtc_write_trigger=%d\n", __func__, ret);
+ rtc_info("rtc_write_trigger=%d\n", ret);
- pwrap_read(RTC_BBPU, &bbpu);
- printk(BIOS_INFO, "[RTC] %s done BBPU=%#x\n", __func__, bbpu);
+ rtc_read(RTC_BBPU, &bbpu);
+ rtc_info("done BBPU=%#x\n", bbpu);
}
void poweroff(void)
@@ -198,11 +263,10 @@ void poweroff(void)
u16 bbpu;
if (!rtc_writeif_unlock())
- printk(BIOS_INFO,
- "[RTC] %s rtc_writeif_unlock() fail\n", __func__);
+ rtc_info("rtc_writeif_unlock() fail\n");
/* pull PWRBB low */
bbpu = RTC_BBPU_KEY | RTC_BBPU_RELOAD | RTC_BBPU_PWREN;
- pwrap_write(RTC_BBPU, bbpu);
+ rtc_write(RTC_BBPU, bbpu);
pmic_set_power_hold(false);
halt();
@@ -211,28 +275,28 @@ void poweroff(void)
static void dcxo_init(void)
{
/* Buffer setting */
- pwrap_write(PMIC_RG_DCXO_CW15, 0xA2AA);
- pwrap_write(PMIC_RG_DCXO_CW13, 0x98E9);
- pwrap_write(PMIC_RG_DCXO_CW16, 0x9855);
+ rtc_write(PMIC_RG_DCXO_CW15, 0xA2AA);
+ rtc_write(PMIC_RG_DCXO_CW13, 0x98E9);
+ rtc_write(PMIC_RG_DCXO_CW16, 0x9855);
/* 26M enable control */
/* Enable clock buffer XO_SOC, XO_CEL */
- pwrap_write(PMIC_RG_DCXO_CW00, 0x4805);
- pwrap_write(PMIC_RG_DCXO_CW11, 0x8000);
+ rtc_write(PMIC_RG_DCXO_CW00, 0x4805);
+ rtc_write(PMIC_RG_DCXO_CW11, 0x8000);
/* Load thermal coefficient */
- pwrap_write(PMIC_RG_TOP_TMA_KEY, 0x9CA7);
- pwrap_write(PMIC_RG_DCXO_CW21, 0x12A7);
- pwrap_write(PMIC_RG_DCXO_ELR0, 0xD004);
- pwrap_write(PMIC_RG_TOP_TMA_KEY, 0x0000);
+ rtc_write(PMIC_RG_TOP_TMA_KEY, 0x9CA7);
+ rtc_write(PMIC_RG_DCXO_CW21, 0x12A7);
+ rtc_write(PMIC_RG_DCXO_ELR0, 0xD004);
+ rtc_write(PMIC_RG_TOP_TMA_KEY, 0x0000);
/* Adjust OSC FPM setting */
- pwrap_write(PMIC_RG_DCXO_CW07, 0x8FFE);
+ rtc_write(PMIC_RG_DCXO_CW07, 0x8FFE);
/* Re-Calibrate OSC current */
- pwrap_write(PMIC_RG_DCXO_CW09, 0x008F);
+ rtc_write(PMIC_RG_DCXO_CW09, 0x008F);
udelay(100);
- pwrap_write(PMIC_RG_DCXO_CW09, 0x408F);
+ rtc_write(PMIC_RG_DCXO_CW09, 0x408F);
mdelay(5);
}