summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>2020-12-30 12:15:54 +0800
committerPatrick Georgi <pgeorgi@google.com>2021-01-22 14:26:08 +0000
commitd194081ba60a2541062b9cc6d131a0eddd3335d1 (patch)
treef625ebfe1e1252f82adbaa376d8f024d898f84cc
parentd6375cf556fb7a4612a441c4d32f93fa57556f3a (diff)
soc/mediatek/mt8192: pmic: Set efuses manually
Some efuse settings would not be applied automatically, so we need set the settings manually. The low power consumption would not be optimal without correct efuse settings. BUG=b:172636735 BRANCH=none TEST=see 'pmic_efuse_setting: Set efuses in 11 msecs' Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com> Change-Id: Ideb862c3cb0f1fee183804aed74fcf141bf1f5df Reviewed-on: https://review.coreboot.org/c/coreboot/+/49006 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
-rw-r--r--src/soc/mediatek/mt8192/include/soc/mt6359p.h21
-rw-r--r--src/soc/mediatek/mt8192/mt6359p.c91
2 files changed, 112 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8192/include/soc/mt6359p.h b/src/soc/mediatek/mt8192/include/soc/mt6359p.h
index b90e0f55ed..5519cc2383 100644
--- a/src/soc/mediatek/mt8192/include/soc/mt6359p.h
+++ b/src/soc/mediatek/mt8192/include/soc/mt6359p.h
@@ -8,14 +8,23 @@
enum {
PMIC_HWCID = 0x0008,
PMIC_SWCID = 0x000a,
+ PMIC_TOP_CKPDN_CON0 = 0x010c,
+ PMIC_TOP_CKHWEN_CON0 = 0x012a,
PMIC_TOP_RST_MISC_SET = 0x014c,
PMIC_TOP_RST_MISC_CLR = 0x014e,
+ PMIC_OTP_CON0 = 0x038a,
+ PMIC_OTP_CON8 = 0x039a,
+ PMIC_OTP_CON11 = 0x03a0,
+ PMIC_OTP_CON12 = 0x03a2,
+ PMIC_OTP_CON13 = 0x03a4,
PMIC_PWRHOLD = 0x0a08,
PMIC_VGPU11_DBG0 = 0x15a6,
PMIC_VGPU11_ELR0 = 0x15b4,
PMIC_VS2_VOTER = 0x18aa,
PMIC_VS2_VOTER_CFG = 0x18b0,
PMIC_VS2_ELR0 = 0x18b4,
+ PMIC_BUCK_VPA_DLC_CON0 = 0x1918,
+ PMIC_BUCK_VPA_DLC_CON1 = 0x191a,
PMIC_VSRAM_PROC1_ELR = 0x1b44,
PMIC_VSRAM_PROC2_ELR = 0x1b46,
PMIC_VSRAM_PROC1_VOSEL1 = 0x1e90,
@@ -30,6 +39,13 @@ struct pmic_setting {
unsigned char shift;
};
+struct pmic_efuse {
+ unsigned short efuse_bit;
+ unsigned short addr;
+ unsigned short mask;
+ unsigned char shift;
+};
+
enum {
MT6359P_GPU11 = 0,
MT6359P_SRAM_PROC1,
@@ -40,6 +56,11 @@ enum {
#define VM18_VOL_REG_SHIFT 8
#define VM18_VOL_OFFSET 600
+#define EFUSE_WAIT_US 5000
+#define EFUSE_BUSY 1
+
+#define EFUSE_RG_VPA_OC_FT 78
+
void mt6359p_init(void);
void mt6359p_romstage_init(void);
void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv);
diff --git a/src/soc/mediatek/mt8192/mt6359p.c b/src/soc/mediatek/mt8192/mt6359p.c
index c93b66a426..e9dadc0d74 100644
--- a/src/soc/mediatek/mt8192/mt6359p.c
+++ b/src/soc/mediatek/mt8192/mt6359p.c
@@ -5,6 +5,7 @@
#include <delay.h>
#include <soc/pmif.h>
#include <soc/mt6359p.h>
+#include <timer.h>
static const struct pmic_setting key_protect_setting[] = {
{0x3A8, 0x9CA6, 0xFFFF, 0},
@@ -298,6 +299,32 @@ static const struct pmic_setting lp_setting[] = {
{0x1d14, 0x1, 0x1, 0x2},
};
+static const struct pmic_efuse efuse_setting[] = {
+ {79, 0xa0e, 0x1, 0xf},
+ {886, 0x198c, 0xf, 0x8},
+ {890, 0x198e, 0xf, 0x0},
+ {902, 0x1998, 0xf, 0x8},
+ {906, 0x1998, 0xf, 0xc},
+ {918, 0x19a2, 0xf, 0x8},
+ {922, 0x19a2, 0xf, 0xc},
+ {1014, 0x19ae, 0xf, 0x7},
+ {1018, 0x19ae, 0xf, 0xb},
+ {1158, 0x1a0a, 0xf, 0x7},
+ {1162, 0x1a0a, 0xf, 0xb},
+ {1206, 0x1a16, 0xf, 0x7},
+ {1210, 0x1a16, 0xf, 0xb},
+ {1254, 0x1a22, 0xf, 0x7},
+ {1258, 0x1a22, 0xf, 0xb},
+ {1304, 0x1a2c, 0x7, 0x4},
+ {1307, 0x1a32, 0x7, 0x8},
+ {1336, 0x1a34, 0x7, 0x4},
+ {1339, 0x1a3a, 0x7, 0x8},
+ {1683, 0x79c, 0xf, 0x4},
+ {1688, 0xc8a, 0x1, 0x3},
+ {1689, 0xc88, 0x1, 0x3},
+ {1690, 0xc88, 0x7, 0x0},
+};
+
static struct pmif *pmif_arb = NULL;
static void mt6359p_write(u32 reg, u32 data)
{
@@ -336,6 +363,45 @@ static void pmic_protect_key_setting(bool lock)
lock ? 0 : key_protect_setting[i].val);
}
+static int check_idle(u32 timeout, u32 addr, u32 mask)
+{
+ if (!wait_us(timeout, !mt6359p_read_field(addr, mask, 0)))
+ return -1;
+
+ return 0;
+}
+
+static u32 pmic_read_efuse(u32 efuse_bit, u32 mask)
+{
+ u32 efuse_data;
+ int index, shift;
+
+ index = efuse_bit / 16;
+ shift = efuse_bit % 16;
+ mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 0, 0x1, 2);
+ mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 0, 0x1, 4);
+ mt6359p_write_field(PMIC_OTP_CON11, 1, 0x1, 0);
+ mt6359p_write_field(PMIC_OTP_CON0, index * 2, 0xFF, 0);
+ if (mt6359p_read_field(PMIC_OTP_CON8, 1, 0))
+ mt6359p_write_field(PMIC_OTP_CON8, 0, 1, 0);
+ else
+ mt6359p_write_field(PMIC_OTP_CON8, 1, 1, 0);
+
+ udelay(300);
+ if (check_idle(EFUSE_WAIT_US, PMIC_OTP_CON13, EFUSE_BUSY))
+ die("[%s] timeout after %d usecs\n", __func__, EFUSE_WAIT_US);
+
+ udelay(100);
+
+ efuse_data = mt6359p_read_field(PMIC_OTP_CON12, 0xFFFF, 0);
+ efuse_data = (efuse_data >> shift) & mask;
+
+ mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 1, 0x1, 2);
+ mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 1, 0x1, 4);
+
+ return efuse_data;
+}
+
static void pmic_init_setting(void)
{
for (int i = 0; i < ARRAY_SIZE(init_setting); i++)
@@ -350,6 +416,30 @@ static void pmic_lp_setting(void)
lp_setting[i].mask, lp_setting[i].shift);
}
+static void pmic_efuse_setting(void)
+{
+ u32 efuse_data;
+ struct stopwatch sw;
+
+ stopwatch_init(&sw);
+
+ for (int i = 0; i < ARRAY_SIZE(efuse_setting); i++) {
+ efuse_data = pmic_read_efuse(efuse_setting[i].efuse_bit, efuse_setting[i].mask);
+ mt6359p_write_field(efuse_setting[i].addr, efuse_data,
+ efuse_setting[i].mask, efuse_setting[i].shift);
+ }
+
+ efuse_data = pmic_read_efuse(EFUSE_RG_VPA_OC_FT, 0x1);
+ if (efuse_data) {
+ /* restore VPA_DLC initial setting */
+ mt6359p_write(PMIC_BUCK_VPA_DLC_CON0, 0x2810);
+ mt6359p_write(PMIC_BUCK_VPA_DLC_CON1, 0x800);
+ }
+
+ printk(BIOS_DEBUG, "%s: Set efuses in %ld msecs\n",
+ __func__, stopwatch_duration_msecs(&sw));
+}
+
static void pmic_wk_vs2_voter_setting(void)
{
/*
@@ -470,6 +560,7 @@ void mt6359p_init(void)
pmic_protect_key_setting(false);
pmic_init_setting();
pmic_lp_setting();
+ pmic_efuse_setting();
pmic_protect_key_setting(true);
pmic_wk_vs2_voter_setting();
}