Changes in v2:
- Fixed some style issues in patch [18/20]
This is a partial refactoring of the MediaTek Smart Voltage Scaling
driver.
Long story short: this driver never worked as expected on any platform
because of various issues so in this series there are some changes that
will break compatibility with older device trees (of which, only MT8183
ever had the SVS node), but those are acceptable because... it never
really worked fine anyway, so there's no regression.
This series was tested on MT8186, MT8192, MT8195 Chromebooks.
Depends on
MT8192 thermal node:
https://lore.kernel.org/lkml/[email protected]/
MT8186 and MT8195 SVS support:
https://lore.kernel.org/all/[email protected]/
Note: one commit was omitted because I haven't got feedback yet on
the thermal-zones devicetree consumers implementation at [1], but I
still wanted to send this series to the lists to get feedback.
Please keep in mind that the one omitted commit is supposed to go
on top of this series anyway, and that an useful example of how the
SVS node will look with the DT thermal zones is provided at [1].
[1]: https://lore.kernel.org/all/[email protected]/
AngeloGioacchino Del Regno (20):
arm64: dts: mediatek: mt8183: Change iospaces for thermal and svs
soc: mediatek: mtk-svs: Subtract offset from regs_v2 to avoid conflict
soc: mediatek: mtk-svs: Convert sw_id and type to enumerations
soc: mediatek: mtk-svs: Build bank name string dynamically
soc: mediatek: mtk-svs: Reduce memory footprint of struct svs_bank
soc: mediatek: mtk-svs: Change the thermal sensor device name
soc: mediatek: mtk-svs: Add a map to retrieve fused values
soc: mediatek: mtk-svs: Add SVS-Thermal coefficient to SoC platform
data
soc: mediatek: mtk-svs: Move t-calibration-data retrieval to
svs_probe()
soc: mediatek: mtk-svs: Commonize efuse parse function for most SoCs
soc: mediatek: mtk-svs: Drop supplementary svs per-bank pointer
soc: mediatek: mtk-svs: Commonize MT8192 probe function for MT8186
soc: mediatek: mtk-svs: Remove redundant print in svs_get_efuse_data
soc: mediatek: mtk-svs: Compress of_device_id entries
soc: mediatek: mtk-svs: Cleanup of svs_probe() function
soc: mediatek: mtk-svs: Check if SVS mode is available in the
beginning
soc: mediatek: mtk-svs: Use ULONG_MAX to compare floor frequency
soc: mediatek: mtk-svs: Constify runtime-immutable members of svs_bank
arm64: dts: mediatek: mt8192: Add Smart Voltage Scaling node
arm64: dts: mediatek: mt8195: Add SVS node and reduce LVTS_AP iospace
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 26 +-
arch/arm64/boot/dts/mediatek/mt8192.dtsi | 12 +
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 17 +-
drivers/soc/mediatek/mtk-svs.c | 1996 +++++++++++-----------
4 files changed, 993 insertions(+), 1058 deletions(-)
--
2.42.0
Many 32-bit members of this struct can be size reduced to either 16-bit
or even 8-bit, for a total saving of ~61 bytes per bank. Keeping in mind
that one SoC declares at least two banks, this brings a minimum of ~122
bytes saving (depending on compiler optimization).
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 51 +++++++++++++++++-----------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 1c7592fd6ae7..6c27fb523bfa 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -456,13 +456,13 @@ struct svs_bank {
char *buck_name;
char *tzone_name;
enum svsb_phase phase;
- s32 volt_od;
+ short int volt_od;
u32 reg_data[SVSB_PHASE_MAX][SVS_REG_MAX];
u32 pm_runtime_enabled_count;
- u32 mode_support;
+ u8 mode_support;
u32 freq_base;
u32 turn_freq_base;
- u32 vboot;
+ u8 vboot;
u32 opp_dfreq[MAX_OPP_ENTRIES];
u32 opp_dvolt[MAX_OPP_ENTRIES];
u32 freq_pct[MAX_OPP_ENTRIES];
@@ -470,36 +470,36 @@ struct svs_bank {
u32 volt_step;
u32 volt_base;
u32 volt_flags;
- u32 vmax;
- u32 vmin;
+ u8 vmax;
+ u8 vmin;
u32 age_config;
- u32 age_voffset_in;
+ u16 age_voffset_in;
u32 dc_config;
- u32 dc_voffset_in;
- u32 dvt_fixed;
- u32 vco;
- u32 chk_shift;
+ u16 dc_voffset_in;
+ u8 dvt_fixed;
+ u8 vco;
+ u8 chk_shift;
u32 core_sel;
- u32 opp_count;
+ u8 opp_count;
u32 int_st;
- u32 sw_id;
- u32 cpu_id;
+ u8 sw_id;
+ u8 cpu_id;
u32 ctl0;
u32 temp;
u32 tzone_htemp;
- u32 tzone_htemp_voffset;
+ u16 tzone_htemp_voffset;
u32 tzone_ltemp;
- u32 tzone_ltemp_voffset;
- u32 bts;
- u32 mts;
- u32 bdes;
- u32 mdes;
- u32 mtdes;
- u32 dcbdet;
- u32 dcmdet;
+ u16 tzone_ltemp_voffset;
+ u16 bts;
+ u16 mts;
+ u16 bdes;
+ u16 mdes;
+ u8 mtdes;
+ u8 dcbdet;
+ u8 dcmdet;
u32 turn_pt;
u32 vbin_turn_pt;
- u32 type;
+ u8 type;
};
static u32 percent(u32 numerator, u32 denominator)
@@ -1267,6 +1267,7 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
static inline void svs_init01_isr_handler(struct svs_platform *svsp)
{
struct svs_bank *svsb = svsp->pbank;
+ u32 val;
dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n",
__func__, svs_readl_relaxed(svsp, VDESIGN74),
@@ -1276,8 +1277,8 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01);
svsb->phase = SVSB_PHASE_INIT01;
- svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
- GENMASK(15, 0)) + 1;
+ val = ~(svs_readl_relaxed(svsp, DCVALUES) & GENMASK(15, 0)) + 1;
+ svsb->dc_voffset_in = val & GENMASK(15, 0);
if (svsb->volt_flags & SVSB_INIT01_VOLT_IGNORE ||
(svsb->dc_voffset_in & SVSB_DC_SIGNED_BIT &&
svsb->volt_flags & SVSB_INIT01_VOLT_INC_ONLY))
--
2.42.0
The sw_id and type specifiers currently are defined as BIT(x) for
unknown reasons: nothing in this code makes any AND/OR check for
those, and that would never happen anyway because both sw_id and
type are exclusive, as in:
- There will never be a bank that is for both CPU and GPU, or
for CPU and CCI together;
- A bank cannot be contemporarily of one-line and two-line type,
as much as it cannot contemporarily have both HIGH and LOW roles
Change those definitions to enumerations and also add some kerneldoc
to better describe what they are for and what they indicate.
While at it, also change the names adding _SWID or _TYPE to increase
human readability.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 192 ++++++++++++++++++---------------
1 file changed, 106 insertions(+), 86 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 416e9b313c0a..ddbb9ba3e47d 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -32,16 +32,6 @@
#include <linux/spinlock.h>
#include <linux/thermal.h>
-/* svs bank 1-line software id */
-#define SVSB_CPU_LITTLE BIT(0)
-#define SVSB_CPU_BIG BIT(1)
-#define SVSB_CCI BIT(2)
-#define SVSB_GPU BIT(3)
-
-/* svs bank 2-line type */
-#define SVSB_LOW BIT(8)
-#define SVSB_HIGH BIT(9)
-
/* svs bank mode support */
#define SVSB_MODE_ALL_DISABLE 0
#define SVSB_MODE_INIT01 BIT(1)
@@ -174,6 +164,36 @@ static DEFINE_SPINLOCK(svs_lock);
#define svs_dentry_data(name) {__stringify(name), &svs_##name##_debug_fops}
#endif
+/**
+ * enum svsb_sw_id - SVS Bank Software ID
+ * @SVSB_SWID_CPU_LITTLE: CPU little cluster Bank
+ * @SVSB_SWID_CPU_BIG: CPU big cluster Bank
+ * @SVSB_SWID_CCI: Cache Coherent Interconnect Bank
+ * @SVSB_SWID_GPU: GPU Bank
+ * @SVSB_SWID_MAX: Total number of Banks
+ */
+enum svsb_sw_id {
+ SVSB_SWID_CPU_LITTLE,
+ SVSB_SWID_CPU_BIG,
+ SVSB_SWID_CCI,
+ SVSB_SWID_GPU,
+ SVSB_SWID_MAX
+};
+
+/**
+ * enum svsb_type - SVS Bank 2-line: Type and Role
+ * @SVSB_TYPE_NONE: One-line type Bank - Global role
+ * @SVSB_TYPE_LOW: Two-line type Bank - Low bank role
+ * @SVSB_TYPE_HIGH: Two-line type Bank - High bank role
+ * @SVSB_TYPE_MAX: Total number of bank types
+ */
+enum svsb_type {
+ SVSB_TYPE_NONE,
+ SVSB_TYPE_LOW,
+ SVSB_TYPE_HIGH,
+ SVSB_TYPE_MAX
+};
+
/**
* enum svsb_phase - svs bank phase enumeration
* @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
@@ -549,10 +569,10 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
* 2-line bank updates its corresponding opp volts.
* 1-line bank updates all opp volts.
*/
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
opp_start = 0;
opp_stop = svsb->turn_pt;
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
opp_start = svsb->turn_pt;
opp_stop = svsb->opp_count;
} else {
@@ -576,8 +596,8 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
temp_voffset += svsb->tzone_ltemp_voffset;
/* 2-line bank update all opp volts when running mon mode */
- if (svsb->phase == SVSB_PHASE_MON && (svsb->type == SVSB_HIGH ||
- svsb->type == SVSB_LOW)) {
+ if (svsb->phase == SVSB_PHASE_MON && (svsb->type == SVSB_TYPE_HIGH ||
+ svsb->type == SVSB_TYPE_LOW)) {
opp_start = 0;
opp_stop = svsb->opp_count;
}
@@ -881,7 +901,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
/* Target is to set svsb->volt[] by algorithm */
if (turn_pt < middle_index) {
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
/* volt[0] ~ volt[turn_pt - 1] */
for (i = 0; i < turn_pt; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
@@ -890,7 +910,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
shift_byte++;
}
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
j = svsb->opp_count - 7;
svsb->volt[turn_pt] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30);
@@ -912,7 +932,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
svsb->freq_pct[i]);
}
} else {
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
j = turn_pt - 7;
svsb->volt[0] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30);
@@ -932,7 +952,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
svsb->volt[0],
svsb->volt[j],
svsb->freq_pct[i]);
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
/* volt[turn_pt] ~ volt[opp_count - 1] */
for (i = turn_pt; i < svsb->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
@@ -944,10 +964,10 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
}
}
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
opp_start = 0;
opp_stop = svsb->turn_pt;
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
opp_start = svsb->turn_pt;
opp_stop = svsb->opp_count;
}
@@ -998,11 +1018,11 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
if (turn_pt < middle_index) {
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
/*
* If we don't handle this situation,
- * SVSB_HIGH's FREQPCT74 / FREQPCT30 would keep "0"
- * and this leads SVSB_LOW to work abnormally.
+ * SVSB_TYPE_HIGH's FREQPCT74 / FREQPCT30 would keep "0"
+ * and this leads SVSB_TYPE_LOW to work abnormally.
*/
if (turn_pt == 0)
freq_pct30 = svsb->freq_pct[0];
@@ -1015,7 +1035,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
*freq_pct |= (svsb->freq_pct[i] << b_sft);
shift_byte++;
}
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
/*
* freq_pct[turn_pt] +
* freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
@@ -1032,7 +1052,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
}
}
} else {
- if (svsb->type == SVSB_HIGH) {
+ if (svsb->type == SVSB_TYPE_HIGH) {
/*
* freq_pct[0] +
* freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
@@ -1047,7 +1067,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
*freq_pct |= (svsb->freq_pct[i] << b_sft);
shift_byte++;
}
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
for (i = turn_pt; i < svsb->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
@@ -1550,7 +1570,7 @@ static int svs_init02(struct svs_platform *svsp)
if (!(svsb->mode_support & SVSB_MODE_INIT02))
continue;
- if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+ if (svsb->type == SVSB_TYPE_HIGH || svsb->type == SVSB_TYPE_LOW) {
if (svs_sync_bank_volts_from_opp(svsb)) {
dev_err(svsb->dev, "sync volt fail\n");
ret = -EPERM;
@@ -1677,19 +1697,19 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
svsb = &svsp->banks[idx];
switch (svsb->sw_id) {
- case SVSB_CPU_LITTLE:
+ case SVSB_SWID_CPU_LITTLE:
svsb->name = "SVSB_CPU_LITTLE";
break;
- case SVSB_CPU_BIG:
+ case SVSB_SWID_CPU_BIG:
svsb->name = "SVSB_CPU_BIG";
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
svsb->name = "SVSB_CCI";
break;
- case SVSB_GPU:
- if (svsb->type == SVSB_HIGH)
+ case SVSB_SWID_GPU:
+ if (svsb->type == SVSB_TYPE_HIGH)
svsb->name = "SVSB_GPU_HIGH";
- else if (svsb->type == SVSB_LOW)
+ else if (svsb->type == SVSB_TYPE_LOW)
svsb->name = "SVSB_GPU_LOW";
else
svsb->name = "SVSB_GPU";
@@ -1821,13 +1841,13 @@ static bool svs_mt8195_efuse_parsing(struct svs_platform *svsp)
if (ft_pgm == 0)
svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
- if (svsb->type == SVSB_LOW) {
+ if (svsb->type == SVSB_TYPE_LOW) {
svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[8]) & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[8] >> 8) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_HIGH) {
+ } else if (svsb->type == SVSB_TYPE_HIGH) {
svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
@@ -1886,13 +1906,13 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
if (vmin == 0x1)
svsb->vmin = 0x1e;
- if (svsb->type == SVSB_LOW) {
+ if (svsb->type == SVSB_TYPE_LOW) {
svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[17]) & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[17] >> 8) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_HIGH) {
+ } else if (svsb->type == SVSB_TYPE_HIGH) {
svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
@@ -1946,13 +1966,13 @@ static bool svs_mt8188_efuse_parsing(struct svs_platform *svsp)
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
- if (svsb->type == SVSB_LOW) {
+ if (svsb->type == SVSB_TYPE_LOW) {
svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[5] >> 24) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[15] >> 16) & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[15] >> 24) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_HIGH) {
+ } else if (svsb->type == SVSB_TYPE_HIGH) {
svsb->mtdes = svsp->efuse[4] & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
@@ -2007,14 +2027,14 @@ static bool svs_mt8186_efuse_parsing(struct svs_platform *svsp)
svsb = &svsp->banks[idx];
switch (svsb->sw_id) {
- case SVSB_CPU_BIG:
- if (svsb->type == SVSB_HIGH) {
+ case SVSB_SWID_CPU_BIG:
+ if (svsb->type == SVSB_TYPE_HIGH) {
svsb->mdes = (svsp->efuse[2] >> 24) & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[2] >> 16) & GENMASK(7, 0);
svsb->mtdes = svsp->efuse[2] & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[13] >> 8) & GENMASK(7, 0);
svsb->dcbdet = svsp->efuse[13] & GENMASK(7, 0);
- } else if (svsb->type == SVSB_LOW) {
+ } else if (svsb->type == SVSB_TYPE_LOW) {
svsb->mdes = (svsp->efuse[3] >> 24) & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[3] >> 16) & GENMASK(7, 0);
svsb->mtdes = svsp->efuse[3] & GENMASK(7, 0);
@@ -2022,21 +2042,21 @@ static bool svs_mt8186_efuse_parsing(struct svs_platform *svsp)
svsb->dcbdet = (svsp->efuse[14] >> 16) & GENMASK(7, 0);
}
break;
- case SVSB_CPU_LITTLE:
+ case SVSB_SWID_CPU_LITTLE:
svsb->mdes = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
svsb->mtdes = svsp->efuse[4] & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[14] >> 8) & GENMASK(7, 0);
svsb->dcbdet = svsp->efuse[14] & GENMASK(7, 0);
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
svsb->mdes = (svsp->efuse[5] >> 24) & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
svsb->dcmdet = (svsp->efuse[15] >> 24) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[15] >> 16) & GENMASK(7, 0);
break;
- case SVSB_GPU:
+ case SVSB_SWID_GPU:
svsb->mdes = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
svsb->bdes = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
svsb->mtdes = svsp->efuse[6] & GENMASK(7, 0);
@@ -2098,7 +2118,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
switch (svsb->sw_id) {
- case SVSB_CPU_LITTLE:
+ case SVSB_SWID_CPU_LITTLE:
svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
@@ -2110,7 +2130,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
else
svsb->volt_od += 2;
break;
- case SVSB_CPU_BIG:
+ case SVSB_SWID_CPU_BIG:
svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
@@ -2122,7 +2142,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
else
svsb->volt_od += 12;
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
@@ -2134,7 +2154,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
else
svsb->volt_od += 2;
break;
- case SVSB_GPU:
+ case SVSB_SWID_GPU:
svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
@@ -2219,16 +2239,16 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
svsb->mts = mts;
switch (svsb->sw_id) {
- case SVSB_CPU_LITTLE:
+ case SVSB_SWID_CPU_LITTLE:
tb_roomt = x_roomt[3];
break;
- case SVSB_CPU_BIG:
+ case SVSB_SWID_CPU_BIG:
tb_roomt = x_roomt[4];
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
tb_roomt = x_roomt[3];
break;
- case SVSB_GPU:
+ case SVSB_SWID_GPU:
tb_roomt = x_roomt[1];
break;
default:
@@ -2321,9 +2341,9 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
- if (svsb->type == SVSB_HIGH)
+ if (svsb->type == SVSB_TYPE_HIGH)
svsb->opp_dev = svs_add_device_link(svsp, "gpu");
- else if (svsb->type == SVSB_LOW)
+ else if (svsb->type == SVSB_TYPE_LOW)
svsb->opp_dev = svs_get_subsys_device(svsp, "gpu");
if (IS_ERR(svsb->opp_dev))
@@ -2355,14 +2375,14 @@ static int svs_mt8186_platform_probe(struct svs_platform *svsp)
svsb = &svsp->banks[idx];
switch (svsb->sw_id) {
- case SVSB_CPU_LITTLE:
- case SVSB_CPU_BIG:
+ case SVSB_SWID_CPU_LITTLE:
+ case SVSB_SWID_CPU_BIG:
svsb->opp_dev = get_cpu_device(svsb->cpu_id);
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
svsb->opp_dev = svs_add_device_link(svsp, "cci");
break;
- case SVSB_GPU:
+ case SVSB_SWID_GPU:
svsb->opp_dev = svs_add_device_link(svsp, "gpu");
break;
default:
@@ -2394,14 +2414,14 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
svsb = &svsp->banks[idx];
switch (svsb->sw_id) {
- case SVSB_CPU_LITTLE:
- case SVSB_CPU_BIG:
+ case SVSB_SWID_CPU_LITTLE:
+ case SVSB_SWID_CPU_BIG:
svsb->opp_dev = get_cpu_device(svsb->cpu_id);
break;
- case SVSB_CCI:
+ case SVSB_SWID_CCI:
svsb->opp_dev = svs_add_device_link(svsp, "cci");
break;
- case SVSB_GPU:
+ case SVSB_SWID_GPU:
svsb->opp_dev = svs_add_device_link(svsp, "gpu");
break;
default:
@@ -2420,8 +2440,8 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
static struct svs_bank svs_mt8195_banks[] = {
{
- .sw_id = SVSB_GPU,
- .type = SVSB_LOW,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
@@ -2443,8 +2463,8 @@ static struct svs_bank svs_mt8195_banks[] = {
.ctl0 = 0x00540003,
},
{
- .sw_id = SVSB_GPU,
- .type = SVSB_HIGH,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.tzone_name = "gpu1",
@@ -2475,8 +2495,8 @@ static struct svs_bank svs_mt8195_banks[] = {
static struct svs_bank svs_mt8192_banks[] = {
{
- .sw_id = SVSB_GPU,
- .type = SVSB_LOW,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.tzone_name = "gpu1",
@@ -2503,8 +2523,8 @@ static struct svs_bank svs_mt8192_banks[] = {
.tzone_ltemp_voffset = 7,
},
{
- .sw_id = SVSB_GPU,
- .type = SVSB_HIGH,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.tzone_name = "gpu1",
@@ -2535,8 +2555,8 @@ static struct svs_bank svs_mt8192_banks[] = {
static struct svs_bank svs_mt8188_banks[] = {
{
- .sw_id = SVSB_GPU,
- .type = SVSB_LOW,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
@@ -2558,8 +2578,8 @@ static struct svs_bank svs_mt8188_banks[] = {
.ctl0 = 0x00100003,
},
{
- .sw_id = SVSB_GPU,
- .type = SVSB_HIGH,
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.tzone_name = "gpu1",
@@ -2590,8 +2610,8 @@ static struct svs_bank svs_mt8188_banks[] = {
static struct svs_bank svs_mt8186_banks[] = {
{
- .sw_id = SVSB_CPU_BIG,
- .type = SVSB_LOW,
+ .sw_id = SVSB_SWID_CPU_BIG,
+ .type = SVSB_TYPE_LOW,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.cpu_id = 6,
@@ -2615,8 +2635,8 @@ static struct svs_bank svs_mt8186_banks[] = {
.ctl0 = 0x00540003,
},
{
- .sw_id = SVSB_CPU_BIG,
- .type = SVSB_HIGH,
+ .sw_id = SVSB_SWID_CPU_BIG,
+ .type = SVSB_TYPE_HIGH,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
.cpu_id = 6,
@@ -2646,7 +2666,7 @@ static struct svs_bank svs_mt8186_banks[] = {
.tzone_ltemp_voffset = 8,
},
{
- .sw_id = SVSB_CPU_LITTLE,
+ .sw_id = SVSB_SWID_CPU_LITTLE,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.cpu_id = 0,
@@ -2675,7 +2695,7 @@ static struct svs_bank svs_mt8186_banks[] = {
.tzone_ltemp_voffset = 8,
},
{
- .sw_id = SVSB_CCI,
+ .sw_id = SVSB_SWID_CCI,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.tzone_name = "cpu_zone0",
@@ -2703,7 +2723,7 @@ static struct svs_bank svs_mt8186_banks[] = {
.tzone_ltemp_voffset = 8,
},
{
- .sw_id = SVSB_GPU,
+ .sw_id = SVSB_SWID_GPU,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.tzone_name = "mfg",
@@ -2733,7 +2753,7 @@ static struct svs_bank svs_mt8186_banks[] = {
static struct svs_bank svs_mt8183_banks[] = {
{
- .sw_id = SVSB_CPU_LITTLE,
+ .sw_id = SVSB_SWID_CPU_LITTLE,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.cpu_id = 0,
@@ -2757,7 +2777,7 @@ static struct svs_bank svs_mt8183_banks[] = {
.ctl0 = 0x00010001,
},
{
- .sw_id = SVSB_CPU_BIG,
+ .sw_id = SVSB_SWID_CPU_BIG,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.cpu_id = 4,
@@ -2781,7 +2801,7 @@ static struct svs_bank svs_mt8183_banks[] = {
.ctl0 = 0x00000001,
},
{
- .sw_id = SVSB_CCI,
+ .sw_id = SVSB_SWID_CCI,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.buck_name = "proc",
@@ -2804,7 +2824,7 @@ static struct svs_bank svs_mt8183_banks[] = {
.ctl0 = 0x00100003,
},
{
- .sw_id = SVSB_GPU,
+ .sw_id = SVSB_SWID_GPU,
.set_freq_pct = svs_set_bank_freq_pct_v2,
.get_volts = svs_get_bank_volts_v2,
.buck_name = "mali",
--
2.42.0
In preparation for commonizing the efuse parsing function, add the
SVS-Thermal coefficients for all SoCs for which said function can be
commonized (MT8186, MT8188, MT8192, MT8195) and assign those to their
platform data structure.
That will be used to calculate the MTS parameter with the equation
MTS = (ts_coeff * 2) / 1000
This commit brings no functional changes.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 6c6f133c327f..ab564d48092b 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -118,6 +118,10 @@
#define SVSB_VOPS_FLD_VOP2_6 GENMASK(23, 16)
#define SVSB_VOPS_FLD_VOP3_7 GENMASK(31, 24)
+/* SVS Thermal Coefficients */
+#define SVSB_TS_COEFF_MT8195 250460
+#define SVSB_TS_COEFF_MT8186 204650
+
/* svs bank related setting */
#define BITS8 8
#define MAX_OPP_ENTRIES 16
@@ -374,6 +378,7 @@ struct svs_fusemap {
* @bank_max: total number of svs banks
* @efuse: svs efuse data received from NVMEM framework
* @tefuse: thermal efuse data received from NVMEM framework
+ * @ts_coeff: thermal sensors coefficient
*/
struct svs_platform {
void __iomem *base;
@@ -388,6 +393,7 @@ struct svs_platform {
u32 bank_max;
u32 *efuse;
u32 *tefuse;
+ u32 ts_coeff;
};
struct svs_platform_data {
@@ -398,6 +404,7 @@ struct svs_platform_data {
const struct svs_fusemap *glb_fuse_map;
const u32 *regs;
u32 bank_max;
+ u32 ts_coeff;
};
/**
@@ -2926,6 +2933,7 @@ static const struct svs_platform_data svs_mt8195_platform_data = {
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8195_banks),
+ .ts_coeff = SVSB_TS_COEFF_MT8195,
.glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
{ 0, 0 }, { 19, 4 }
}
@@ -2938,6 +2946,7 @@ static const struct svs_platform_data svs_mt8192_platform_data = {
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8192_banks),
+ .ts_coeff = SVSB_TS_COEFF_MT8195,
.glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
/* FT_PGM not present */
{ -1, 0 }, { 19, 4 }
@@ -2951,6 +2960,7 @@ static const struct svs_platform_data svs_mt8188_platform_data = {
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8188_banks),
+ .ts_coeff = SVSB_TS_COEFF_MT8195,
.glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
/* FT_PGM and VMIN not present */
{ -1, 0 }, { -1, 0 }
@@ -2964,6 +2974,7 @@ static const struct svs_platform_data svs_mt8186_platform_data = {
.probe = svs_mt8186_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8186_banks),
+ .ts_coeff = SVSB_TS_COEFF_MT8186,
.glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
/* FT_PGM and VMIN not present */
{ -1, 0 }, { -1, 0 }
@@ -3021,6 +3032,7 @@ static int svs_probe(struct platform_device *pdev)
svsp->banks = svsp_data->banks;
svsp->regs = svsp_data->regs;
svsp->bank_max = svsp_data->bank_max;
+ svsp->ts_coeff = svsp_data->ts_coeff;
ret = svsp_data->probe(svsp);
if (ret)
--
2.42.0
This driver tries to create a device link to the thermal sensor device:
change all instances of "lvts" and "thermal" to "thermal-sensor", as
that's what the devicetree node name must be.
Note for MT8183: As specified in a previous commit, this SoC never got
SVS probing, so this is not a breaking change and it does not require
fallback for older device trees.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 6c27fb523bfa..b5beb33c95ba 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2329,7 +2329,7 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
return dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
"cannot get svs reset control\n");
- dev = svs_add_device_link(svsp, "lvts");
+ dev = svs_add_device_link(svsp, "thermal-sensor");
if (IS_ERR(dev))
return dev_err_probe(svsp->dev, PTR_ERR(dev),
"failed to get lvts device\n");
@@ -2362,7 +2362,7 @@ static int svs_mt8186_platform_probe(struct svs_platform *svsp)
return dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
"cannot get svs reset control\n");
- dev = svs_add_device_link(svsp, "lvts");
+ dev = svs_add_device_link(svsp, "thermal-sensor");
if (IS_ERR(dev))
return dev_err_probe(svsp->dev, PTR_ERR(dev),
"failed to get lvts device\n");
@@ -2401,7 +2401,7 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
struct svs_bank *svsb;
u32 idx;
- dev = svs_add_device_link(svsp, "thermal");
+ dev = svs_add_device_link(svsp, "thermal-sensor");
if (IS_ERR(dev))
return dev_err_probe(svsp->dev, PTR_ERR(dev),
"failed to get thermal device\n");
--
2.42.0
The t-calibration-data (SVS-Thermal calibration data) shall exist for
all SoCs or SVS won't work anyway: move it to the common svs_probe()
function and remove it from all of the per-SoC efuse_parsing() probe
callbacks.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 32 ++++++--------------------------
1 file changed, 6 insertions(+), 26 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index ab564d48092b..1042af2aee3f 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1884,11 +1884,6 @@ static bool svs_mt8195_efuse_parsing(struct svs_platform *svsp)
svsb->vmax += svsb->dvt_fixed;
}
- ret = svs_get_efuse_data(svsp, "t-calibration-data",
- &svsp->tefuse, &svsp->tefuse_max);
- if (ret)
- return false;
-
for (i = 0; i < svsp->tefuse_max; i++)
if (svsp->tefuse[i] != 0)
break;
@@ -1949,11 +1944,6 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
svsb->vmax += svsb->dvt_fixed;
}
- ret = svs_get_efuse_data(svsp, "t-calibration-data",
- &svsp->tefuse, &svsp->tefuse_max);
- if (ret)
- return false;
-
for (i = 0; i < svsp->tefuse_max; i++)
if (svsp->tefuse[i] != 0)
break;
@@ -2009,11 +1999,6 @@ static bool svs_mt8188_efuse_parsing(struct svs_platform *svsp)
svsb->vmax += svsb->dvt_fixed;
}
- ret = svs_get_efuse_data(svsp, "t-calibration-data",
- &svsp->tefuse, &svsp->tefuse_max);
- if (ret)
- return false;
-
for (i = 0; i < svsp->tefuse_max; i++)
if (svsp->tefuse[i] != 0)
break;
@@ -2097,11 +2082,6 @@ static bool svs_mt8186_efuse_parsing(struct svs_platform *svsp)
svsb->vmax += svsb->dvt_fixed;
}
- ret = svs_get_efuse_data(svsp, "t-calibration-data",
- &svsp->tefuse, &svsp->tefuse_max);
- if (ret)
- return false;
-
golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
if (!golden_temp)
golden_temp = 50;
@@ -2198,11 +2178,6 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
}
}
- ret = svs_get_efuse_data(svsp, "t-calibration-data",
- &svsp->tefuse, &svsp->tefuse_max);
- if (ret)
- return false;
-
/* Thermal efuse parsing */
adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0);
adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0);
@@ -3040,8 +3015,13 @@ static int svs_probe(struct platform_device *pdev)
ret = svs_get_efuse_data(svsp, "svs-calibration-data",
&svsp->efuse, &svsp->efuse_max);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "Cannot read SVS calibration\n");
+
+ ret = svs_get_efuse_data(svsp, "t-calibration-data",
+ &svsp->tefuse, &svsp->tefuse_max);
if (ret) {
- ret = -EPERM;
+ dev_err_probe(&pdev->dev, ret, "Cannot read SVS-Thermal calibration\n");
goto svs_probe_free_efuse;
}
--
2.42.0
Compress each entry to one line, as they fit in 84 columns, which
is acceptable.
While at it, also change the capital 'S' to 's' in 'sentinel'.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 5fd9884dd20f..ac36c2efcafa 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2731,24 +2731,12 @@ static const struct svs_platform_data svs_mt8183_platform_data = {
};
static const struct of_device_id svs_of_match[] = {
- {
- .compatible = "mediatek,mt8195-svs",
- .data = &svs_mt8195_platform_data,
- }, {
- .compatible = "mediatek,mt8192-svs",
- .data = &svs_mt8192_platform_data,
- }, {
- .compatible = "mediatek,mt8188-svs",
- .data = &svs_mt8188_platform_data,
- }, {
- .compatible = "mediatek,mt8186-svs",
- .data = &svs_mt8186_platform_data,
- }, {
- .compatible = "mediatek,mt8183-svs",
- .data = &svs_mt8183_platform_data,
- }, {
- /* Sentinel */
- },
+ { .compatible = "mediatek,mt8195-svs", .data = &svs_mt8195_platform_data },
+ { .compatible = "mediatek,mt8192-svs", .data = &svs_mt8192_platform_data },
+ { .compatible = "mediatek,mt8188-svs", .data = &svs_mt8188_platform_data },
+ { .compatible = "mediatek,mt8186-svs", .data = &svs_mt8186_platform_data },
+ { .compatible = "mediatek,mt8183-svs", .data = &svs_mt8183_platform_data },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, svs_of_match);
--
2.42.0
Add the MediaTek SVS node: this will lower the voltage of various
components of the SoC based on chip quality (read from fuses) in
order to save power and generate less heat.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8192.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 238f6eb25832..6dd32dbfb832 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -809,6 +809,18 @@ lvts_ap: thermal-sensor@1100b000 {
#thermal-sensor-cells = <1>;
};
+ svs: svs@1100bc00 {
+ compatible = "mediatek,mt8192-svs";
+ reg = <0 0x1100bc00 0 0x400>;
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&infracfg CLK_INFRA_THERM>;
+ clock-names = "main";
+ nvmem-cells = <&svs_calibration>, <&lvts_e_data1>;
+ nvmem-cell-names = "svs-calibration-data", "t-calibration-data";
+ resets = <&infracfg MT8192_INFRA_RST3_THERM_CTRL_PTP_SWRST>;
+ reset-names = "svs_rst";
+ };
+
pwm0: pwm@1100e000 {
compatible = "mediatek,mt8183-disp-pwm";
reg = <0 0x1100e000 0 0x1000>;
--
2.42.0
Add the MediaTek SVS node: this will lower the voltage of various
components of the SoC based on chip quality (read from fuses) in
order to save power and generate less heat.
Also, reduce the LVTS_AP iospace to 0xc00, because that's exactly
where SVS starts.
- LVTS_AP start: 0x1100b000 length: 0xc00
- SVS start: 0x1100bc00 length: 0x400
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 54c674c45b49..54debd4cf8e6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1115,7 +1115,7 @@ spi0: spi@1100a000 {
lvts_ap: thermal-sensor@1100b000 {
compatible = "mediatek,mt8195-lvts-ap";
- reg = <0 0x1100b000 0 0x1000>;
+ reg = <0 0x1100b000 0 0xc00>;
interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
resets = <&infracfg_ao MT8195_INFRA_RST0_THERM_CTRL_SWRST>;
@@ -1124,6 +1124,18 @@ lvts_ap: thermal-sensor@1100b000 {
#thermal-sensor-cells = <1>;
};
+ svs: svs@1100bc00 {
+ compatible = "mediatek,mt8195-svs";
+ reg = <0 0x1100bc00 0 0x400>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+ clock-names = "main";
+ nvmem-cells = <&svs_calib_data &lvts_efuse_data1>;
+ nvmem-cell-names = "svs-calibration-data", "t-calibration-data";
+ resets = <&infracfg_ao MT8195_INFRA_RST3_THERM_CTRL_PTP_SWRST>;
+ reset-names = "svs_rst";
+ };
+
disp_pwm0: pwm@1100e000 {
compatible = "mediatek,mt8195-disp-pwm", "mediatek,mt8183-disp-pwm";
reg = <0 0x1100e000 0 0x1000>;
@@ -1682,6 +1694,9 @@ lvts_efuse_data1: lvts1-calib@1bc {
lvts_efuse_data2: lvts2-calib@1d0 {
reg = <0x1d0 0x38>;
};
+ svs_calib_data: svs-calib@580 {
+ reg = <0x580 0x64>;
+ };
};
u3phy2: t-phy@11c40000 {
--
2.42.0
The svs_init01() and svs_init02() functions are already checking if the
INIT01 and INIT02 modes are available - but that's done in for loops and
for each SVS bank.
Give those a shortcut to get out early if no SVS bank features the
desired init mode: this is especially done to avoid some locking in
the svs_init01(), but also to avoid multiple for loops to check the
same, when no bank supports a specific mode.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index ae0cc22a2941..16a16c5a3f24 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1400,6 +1400,16 @@ static irqreturn_t svs_isr(int irq, void *data)
return IRQ_HANDLED;
}
+static bool svs_mode_available(struct svs_platform *svsp, u8 mode)
+{
+ int i;
+
+ for (i = 0; i < svsp->bank_max; i++)
+ if (svsp->banks[i].mode_support & mode)
+ return true;
+ return false;
+}
+
static int svs_init01(struct svs_platform *svsp)
{
struct svs_bank *svsb;
@@ -1408,6 +1418,9 @@ static int svs_init01(struct svs_platform *svsp)
int ret = 0, r;
u32 opp_freq, opp_vboot, buck_volt, idx, i;
+ if (!svs_mode_available(svsp, SVSB_MODE_INIT01))
+ return 0;
+
/* Keep CPUs' core power on for svs_init01 initialization */
cpuidle_pause_and_lock();
@@ -1575,6 +1588,9 @@ static int svs_init02(struct svs_platform *svsp)
int ret;
u32 idx;
+ if (!svs_mode_available(svsp, SVSB_MODE_INIT02))
+ return 0;
+
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
--
2.42.0
The `freq` variable is of type unsigned long and, even though it does
currently work with u32 because no frequency is higher than U32_MAX,
it is not guaranteed that in the future we will see one.
Initialize the freq variable with ULONG_MAX instead of U32_MAX.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 16a16c5a3f24..df39e7430ba9 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1804,7 +1804,7 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
return count;
}
- for (i = 0, freq = U32_MAX; i < svsb->opp_count; i++, freq--) {
+ for (i = 0, freq = ULONG_MAX; i < svsb->opp_count; i++, freq--) {
opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq);
if (IS_ERR(opp)) {
dev_err(svsb->dev, "cannot find freq = %ld\n",
--
2.42.0
The svs_regs_v2 array of registers was offsetted by 0xc00 because the
SVS node was supposed to have the same iostart as the thermal sensors.
That's wrong for two reasons:
1. Two different devices cannot have the same iostart in devicetree,
as those would technically be the same device otherwise; and
2. SVS and Thermal Sensor (be it LVTS or AUXADC thermal) are not the
same IP, and those two do obviously have a different iospace.
Even though there already are users of this register array, the only
one that declares a devicetree node for SVS is MT8183 - but it never
actually worked because the "tzts1" thermal zone missed thermal trips,
hence this driver's probe always failed on that SoC.
Knowing this - it is safe to say that keeping compatibility with older
device trees is pointless, hence simply subtract the 0xc00 offset from
the register offset array.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 108 ++++++++++++++++-----------------
1 file changed, 54 insertions(+), 54 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 0f7cfbe5630b..416e9b313c0a 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -256,60 +256,60 @@ enum svs_reg_index {
};
static const u32 svs_regs_v2[] = {
- [DESCHAR] = 0xc00,
- [TEMPCHAR] = 0xc04,
- [DETCHAR] = 0xc08,
- [AGECHAR] = 0xc0c,
- [DCCONFIG] = 0xc10,
- [AGECONFIG] = 0xc14,
- [FREQPCT30] = 0xc18,
- [FREQPCT74] = 0xc1c,
- [LIMITVALS] = 0xc20,
- [VBOOT] = 0xc24,
- [DETWINDOW] = 0xc28,
- [CONFIG] = 0xc2c,
- [TSCALCS] = 0xc30,
- [RUNCONFIG] = 0xc34,
- [SVSEN] = 0xc38,
- [INIT2VALS] = 0xc3c,
- [DCVALUES] = 0xc40,
- [AGEVALUES] = 0xc44,
- [VOP30] = 0xc48,
- [VOP74] = 0xc4c,
- [TEMP] = 0xc50,
- [INTSTS] = 0xc54,
- [INTSTSRAW] = 0xc58,
- [INTEN] = 0xc5c,
- [CHKINT] = 0xc60,
- [CHKSHIFT] = 0xc64,
- [STATUS] = 0xc68,
- [VDESIGN30] = 0xc6c,
- [VDESIGN74] = 0xc70,
- [DVT30] = 0xc74,
- [DVT74] = 0xc78,
- [AGECOUNT] = 0xc7c,
- [SMSTATE0] = 0xc80,
- [SMSTATE1] = 0xc84,
- [CTL0] = 0xc88,
- [DESDETSEC] = 0xce0,
- [TEMPAGESEC] = 0xce4,
- [CTRLSPARE0] = 0xcf0,
- [CTRLSPARE1] = 0xcf4,
- [CTRLSPARE2] = 0xcf8,
- [CTRLSPARE3] = 0xcfc,
- [CORESEL] = 0xf00,
- [THERMINTST] = 0xf04,
- [INTST] = 0xf08,
- [THSTAGE0ST] = 0xf0c,
- [THSTAGE1ST] = 0xf10,
- [THSTAGE2ST] = 0xf14,
- [THAHBST0] = 0xf18,
- [THAHBST1] = 0xf1c,
- [SPARE0] = 0xf20,
- [SPARE1] = 0xf24,
- [SPARE2] = 0xf28,
- [SPARE3] = 0xf2c,
- [THSLPEVEB] = 0xf30,
+ [DESCHAR] = 0x00,
+ [TEMPCHAR] = 0x04,
+ [DETCHAR] = 0x08,
+ [AGECHAR] = 0x0c,
+ [DCCONFIG] = 0x10,
+ [AGECONFIG] = 0x14,
+ [FREQPCT30] = 0x18,
+ [FREQPCT74] = 0x1c,
+ [LIMITVALS] = 0x20,
+ [VBOOT] = 0x24,
+ [DETWINDOW] = 0x28,
+ [CONFIG] = 0x2c,
+ [TSCALCS] = 0x30,
+ [RUNCONFIG] = 0x34,
+ [SVSEN] = 0x38,
+ [INIT2VALS] = 0x3c,
+ [DCVALUES] = 0x40,
+ [AGEVALUES] = 0x44,
+ [VOP30] = 0x48,
+ [VOP74] = 0x4c,
+ [TEMP] = 0x50,
+ [INTSTS] = 0x54,
+ [INTSTSRAW] = 0x58,
+ [INTEN] = 0x5c,
+ [CHKINT] = 0x60,
+ [CHKSHIFT] = 0x64,
+ [STATUS] = 0x68,
+ [VDESIGN30] = 0x6c,
+ [VDESIGN74] = 0x70,
+ [DVT30] = 0x74,
+ [DVT74] = 0x78,
+ [AGECOUNT] = 0x7c,
+ [SMSTATE0] = 0x80,
+ [SMSTATE1] = 0x84,
+ [CTL0] = 0x88,
+ [DESDETSEC] = 0xe0,
+ [TEMPAGESEC] = 0xe4,
+ [CTRLSPARE0] = 0xf0,
+ [CTRLSPARE1] = 0xf4,
+ [CTRLSPARE2] = 0xf8,
+ [CTRLSPARE3] = 0xfc,
+ [CORESEL] = 0x300,
+ [THERMINTST] = 0x304,
+ [INTST] = 0x308,
+ [THSTAGE0ST] = 0x30c,
+ [THSTAGE1ST] = 0x310,
+ [THSTAGE2ST] = 0x314,
+ [THAHBST0] = 0x318,
+ [THAHBST1] = 0x31c,
+ [SPARE0] = 0x320,
+ [SPARE1] = 0x324,
+ [SPARE2] = 0x328,
+ [SPARE3] = 0x32c,
+ [THSLPEVEB] = 0x330,
};
/**
--
2.42.0
Cleanup the svs_probe() function: use dev_err_probe() where possible,
change some efuse read failure gotos and then remove now impossible
IS_ERR_OR_NULL() checks (as they will never return true) for nvmem
(efuse read) failures.
Also remove some unnecessary blank lines.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 32 +++++++++++---------------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index ac36c2efcafa..ae0cc22a2941 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2775,14 +2775,13 @@ static int svs_probe(struct platform_device *pdev)
}
if (!svsp_data->efuse_parsing(svsp, svsp_data)) {
- dev_err(svsp->dev, "efuse data parsing failed\n");
- ret = -EPERM;
+ ret = dev_err_probe(svsp->dev, -EINVAL, "efuse data parsing failed\n");
goto svs_probe_free_tefuse;
}
ret = svs_bank_resource_setup(svsp);
if (ret) {
- dev_err(svsp->dev, "svs bank resource setup fail: %d\n", ret);
+ dev_err_probe(svsp->dev, ret, "svs bank resource setup fail\n");
goto svs_probe_free_tefuse;
}
@@ -2794,43 +2793,40 @@ static int svs_probe(struct platform_device *pdev)
svsp->main_clk = devm_clk_get(svsp->dev, "main");
if (IS_ERR(svsp->main_clk)) {
- dev_err(svsp->dev, "failed to get clock: %ld\n",
- PTR_ERR(svsp->main_clk));
- ret = PTR_ERR(svsp->main_clk);
+ ret = dev_err_probe(svsp->dev, PTR_ERR(svsp->main_clk),
+ "failed to get clock\n");
goto svs_probe_free_tefuse;
}
ret = clk_prepare_enable(svsp->main_clk);
if (ret) {
- dev_err(svsp->dev, "cannot enable main clk: %d\n", ret);
+ dev_err_probe(svsp->dev, ret, "cannot enable main clk\n");
goto svs_probe_free_tefuse;
}
svsp->base = of_iomap(svsp->dev->of_node, 0);
if (IS_ERR_OR_NULL(svsp->base)) {
- dev_err(svsp->dev, "cannot find svs register base\n");
- ret = -EINVAL;
+ ret = dev_err_probe(svsp->dev, -EINVAL, "cannot find svs register base\n");
goto svs_probe_clk_disable;
}
ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
IRQF_ONESHOT, svsp_data->name, svsp);
if (ret) {
- dev_err(svsp->dev, "register irq(%d) failed: %d\n",
- svsp_irq, ret);
+ dev_err_probe(svsp->dev, ret, "register irq(%d) failed\n", svsp_irq);
goto svs_probe_iounmap;
}
ret = svs_start(svsp);
if (ret) {
- dev_err(svsp->dev, "svs start fail: %d\n", ret);
+ dev_err_probe(svsp->dev, ret, "svs start fail\n");
goto svs_probe_iounmap;
}
#ifdef CONFIG_DEBUG_FS
ret = svs_create_debug_cmds(svsp);
if (ret) {
- dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret);
+ dev_err_probe(svsp->dev, ret, "svs create debug cmds fail\n");
goto svs_probe_iounmap;
}
#endif
@@ -2839,18 +2835,12 @@ static int svs_probe(struct platform_device *pdev)
svs_probe_iounmap:
iounmap(svsp->base);
-
svs_probe_clk_disable:
clk_disable_unprepare(svsp->main_clk);
-
svs_probe_free_tefuse:
- if (!IS_ERR_OR_NULL(svsp->tefuse))
- kfree(svsp->tefuse);
-
+ kfree(svsp->tefuse);
svs_probe_free_efuse:
- if (!IS_ERR_OR_NULL(svsp->efuse))
- kfree(svsp->efuse);
-
+ kfree(svsp->efuse);
return ret;
}
--
2.42.0
Remove almost all of the per-SoC .efuse_parsing() callbacks and replace
them with one common callback svs_common_parse_efuse(): to do that, also
change the function signature of the callback to add the newly required
pointer to struct svs_platform_data, containing the SVS-global fuse map.
This is done for MT8186, MT8188, MT8192, MT8195.
As for MT8183, the efuse parse function was simplified by using the new
fuse maps.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 332 +++++++--------------------------
1 file changed, 66 insertions(+), 266 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 1042af2aee3f..517a27c58888 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -122,6 +122,9 @@
#define SVSB_TS_COEFF_MT8195 250460
#define SVSB_TS_COEFF_MT8186 204650
+/* Algo helpers */
+#define FUSE_DATA_NOT_VALID U32_MAX
+
/* svs bank related setting */
#define BITS8 8
#define MAX_OPP_ENTRIES 16
@@ -399,7 +402,7 @@ struct svs_platform {
struct svs_platform_data {
char *name;
struct svs_bank *banks;
- bool (*efuse_parsing)(struct svs_platform *svsp);
+ bool (*efuse_parsing)(struct svs_platform *svsp, const struct svs_platform_data *pdata);
int (*probe)(struct svs_platform *svsp);
const struct svs_fusemap *glb_fuse_map;
const u32 *regs;
@@ -1838,264 +1841,83 @@ static int svs_get_efuse_data(struct svs_platform *svsp,
return 0;
}
-static bool svs_mt8195_efuse_parsing(struct svs_platform *svsp)
+static u32 svs_get_fuse_val(u32 *fuse_array, const struct svs_fusemap *fmap, u8 nbits)
{
- struct svs_bank *svsb;
- u32 idx, i, ft_pgm, vmin, golden_temp;
- int ret;
-
- for (i = 0; i < svsp->efuse_max; i++)
- if (svsp->efuse[i])
- dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
- i, svsp->efuse[i]);
-
- if (!svsp->efuse[10]) {
- dev_notice(svsp->dev, "svs_efuse[10] = 0x0?\n");
- return false;
- }
-
- /* Svs efuse parsing */
- ft_pgm = svsp->efuse[0] & GENMASK(7, 0);
- vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0);
-
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
-
- if (vmin == 0x1)
- svsb->vmin = 0x1e;
-
- if (ft_pgm == 0)
- svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
-
- if (svsb->type == SVSB_TYPE_LOW) {
- svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[8]) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[8] >> 8) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_TYPE_HIGH) {
- svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[8]) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[8] >> 8) & GENMASK(7, 0);
- }
-
- svsb->vmax += svsb->dvt_fixed;
- }
-
- for (i = 0; i < svsp->tefuse_max; i++)
- if (svsp->tefuse[i] != 0)
- break;
+ u32 val;
- if (i == svsp->tefuse_max)
- golden_temp = 50; /* All thermal efuse data are 0 */
- else
- golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
+ if (fmap->index < 0)
+ return FUSE_DATA_NOT_VALID;
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
- svsb->mts = 500;
- svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
- }
+ val = fuse_array[fmap->index] >> fmap->ofst;
+ val &= GENMASK(nbits - 1, 0);
- return true;
+ return val;
}
-static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
+static bool svs_is_available(struct svs_platform *svsp)
{
- struct svs_bank *svsb;
- u32 idx, i, vmin, golden_temp;
- int ret;
+ int i, num_populated = 0;
- for (i = 0; i < svsp->efuse_max; i++)
+ /* If at least two fuse arrays are populated, SVS is calibrated */
+ for (i = 0; i < svsp->efuse_max; i++) {
if (svsp->efuse[i])
- dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
- i, svsp->efuse[i]);
-
- if (!svsp->efuse[9]) {
- dev_notice(svsp->dev, "svs_efuse[9] = 0x0?\n");
- return false;
- }
-
- /* Svs efuse parsing */
- vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0);
-
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
-
- if (vmin == 0x1)
- svsb->vmin = 0x1e;
-
- if (svsb->type == SVSB_TYPE_LOW) {
- svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[17]) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[17] >> 8) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_TYPE_HIGH) {
- svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[17] >> 24) & GENMASK(7, 0);
- }
+ num_populated++;
- svsb->vmax += svsb->dvt_fixed;
+ if (num_populated > 1)
+ return true;
}
- for (i = 0; i < svsp->tefuse_max; i++)
- if (svsp->tefuse[i] != 0)
- break;
-
- if (i == svsp->tefuse_max)
- golden_temp = 50; /* All thermal efuse data are 0 */
- else
- golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
-
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
- svsb->mts = 500;
- svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
- }
-
- return true;
+ return false;
}
-static bool svs_mt8188_efuse_parsing(struct svs_platform *svsp)
+static bool svs_common_parse_efuse(struct svs_platform *svsp,
+ const struct svs_platform_data *pdata)
{
- struct svs_bank *svsb;
- u32 idx, i, golden_temp;
- int ret;
+ const struct svs_fusemap *gfmap = pdata->glb_fuse_map;
+ struct svs_fusemap tfm = { 0, 24 };
+ u32 golden_temp, val;
+ u8 ft_pgm, vmin;
+ int i;
- for (i = 0; i < svsp->efuse_max; i++)
- if (svsp->efuse[i])
- dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
- i, svsp->efuse[i]);
-
- if (!svsp->efuse[5]) {
- dev_notice(svsp->dev, "svs_efuse[5] = 0x0?\n");
+ if (!svs_is_available(svsp))
return false;
- }
-
- /* Svs efuse parsing */
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
-
- if (svsb->type == SVSB_TYPE_LOW) {
- svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[5] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[15] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[15] >> 24) & GENMASK(7, 0);
- } else if (svsb->type == SVSB_TYPE_HIGH) {
- svsb->mtdes = svsp->efuse[4] & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = svsp->efuse[14] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[14] >> 8) & GENMASK(7, 0);
- }
-
- svsb->vmax += svsb->dvt_fixed;
- }
-
- for (i = 0; i < svsp->tefuse_max; i++)
- if (svsp->tefuse[i] != 0)
- break;
-
- if (i == svsp->tefuse_max)
- golden_temp = 50; /* All thermal efuse data are 0 */
- else
- golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
-
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
- svsb->mts = 500;
- svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
- }
- return true;
-}
+ /* Get golden temperature from SVS-Thermal calibration */
+ val = svs_get_fuse_val(svsp->tefuse, &tfm, 8);
-static bool svs_mt8186_efuse_parsing(struct svs_platform *svsp)
-{
- struct svs_bank *svsb;
- u32 idx, i, golden_temp;
- int ret;
+ /* If golden temp is not programmed, use the default of 50 */
+ golden_temp = val ? val : 50;
- for (i = 0; i < svsp->efuse_max; i++)
- if (svsp->efuse[i])
- dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
- i, svsp->efuse[i]);
+ /* Parse fused SVS calibration */
+ ft_pgm = svs_get_fuse_val(svsp->efuse, &gfmap[GLB_FT_PGM], 8);
+ vmin = svs_get_fuse_val(svsp->efuse, &gfmap[GLB_VMIN], 2);
- if (!svsp->efuse[0]) {
- dev_notice(svsp->dev, "svs_efuse[0] = 0x0?\n");
- return false;
- }
+ for (i = 0; i < svsp->bank_max; i++) {
+ struct svs_bank *svsb = &svsp->banks[i];
+ const struct svs_fusemap *dfmap = svsb->dev_fuse_map;
- /* Svs efuse parsing */
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
+ if (vmin == 1)
+ svsb->vmin = 0x1e;
- switch (svsb->sw_id) {
- case SVSB_SWID_CPU_BIG:
- if (svsb->type == SVSB_TYPE_HIGH) {
- svsb->mdes = (svsp->efuse[2] >> 24) & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[2] >> 16) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[2] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[13] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = svsp->efuse[13] & GENMASK(7, 0);
- } else if (svsb->type == SVSB_TYPE_LOW) {
- svsb->mdes = (svsp->efuse[3] >> 24) & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[3] >> 16) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[3] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[14] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[14] >> 16) & GENMASK(7, 0);
- }
- break;
- case SVSB_SWID_CPU_LITTLE:
- svsb->mdes = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[4] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[14] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = svsp->efuse[14] & GENMASK(7, 0);
- break;
- case SVSB_SWID_CCI:
- svsb->mdes = (svsp->efuse[5] >> 24) & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[15] >> 24) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[15] >> 16) & GENMASK(7, 0);
- break;
- case SVSB_SWID_GPU:
- svsb->mdes = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
- svsb->bdes = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[6] & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[15] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = svsp->efuse[15] & GENMASK(7, 0);
- break;
- default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
- return false;
- }
+ if (ft_pgm == 0)
+ svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
+ svsb->mtdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_MTDES], 8);
+ svsb->bdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_BDES], 8);
+ svsb->mdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_MDES], 8);
+ svsb->dcbdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCBDET], 8);
+ svsb->dcmdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCMDET], 8);
svsb->vmax += svsb->dvt_fixed;
- }
-
- golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
- if (!golden_temp)
- golden_temp = 50;
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
- svsb->mts = 409;
- svsb->bts = (((500 * golden_temp + 204650) / 1000) - 25) * 4;
+ svsb->mts = (svsp->ts_coeff * 2) / 1000;
+ svsb->bts = (((500 * golden_temp + svsp->ts_coeff) / 1000) - 25) * 4;
}
return true;
}
-static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
+static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
+ const struct svs_platform_data *pdata)
{
struct svs_bank *svsb;
int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0;
@@ -2115,65 +1937,43 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
}
/* Svs efuse parsing */
- ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0);
+ ft_pgm = svs_get_fuse_val(svsp->efuse, &pdata->glb_fuse_map[GLB_FT_PGM], 4);
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ const struct svs_fusemap *dfmap = svsb->dev_fuse_map;
if (ft_pgm <= 1)
svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
+ svsb->mtdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_MTDES], 8);
+ svsb->bdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_BDES], 8);
+ svsb->mdes = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_MDES], 8);
+ svsb->dcbdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCBDET], 8);
+ svsb->dcmdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCMDET], 8);
+
switch (svsb->sw_id) {
case SVSB_SWID_CPU_LITTLE:
- svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0);
- svsb->mtdes = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
-
+ case SVSB_SWID_CCI:
if (ft_pgm <= 3)
svsb->volt_od += 10;
else
svsb->volt_od += 2;
break;
case SVSB_SWID_CPU_BIG:
- svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[17] & GENMASK(7, 0);
-
if (ft_pgm <= 3)
svsb->volt_od += 15;
else
svsb->volt_od += 12;
break;
- case SVSB_SWID_CCI:
- svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
- svsb->mtdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
-
- if (ft_pgm <= 3)
- svsb->volt_od += 10;
- else
- svsb->volt_od += 2;
- break;
case SVSB_SWID_GPU:
- svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
- svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
- svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
- svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
- svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0);
-
- if (ft_pgm >= 2) {
+ if (ft_pgm != FUSE_DATA_NOT_VALID && ft_pgm >= 2) {
svsb->freq_base = 800000000; /* 800MHz */
svsb->dvt_fixed = 2;
}
break;
default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+ dev_err(svsb->dev, "unknown sw_id: %u\n", bdata->sw_id);
return false;
}
}
@@ -2904,7 +2704,7 @@ static struct svs_bank svs_mt8183_banks[] = {
static const struct svs_platform_data svs_mt8195_platform_data = {
.name = "mt8195-svs",
.banks = svs_mt8195_banks,
- .efuse_parsing = svs_mt8195_efuse_parsing,
+ .efuse_parsing = svs_common_parse_efuse,
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8195_banks),
@@ -2917,7 +2717,7 @@ static const struct svs_platform_data svs_mt8195_platform_data = {
static const struct svs_platform_data svs_mt8192_platform_data = {
.name = "mt8192-svs",
.banks = svs_mt8192_banks,
- .efuse_parsing = svs_mt8192_efuse_parsing,
+ .efuse_parsing = svs_common_parse_efuse,
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8192_banks),
@@ -2931,7 +2731,7 @@ static const struct svs_platform_data svs_mt8192_platform_data = {
static const struct svs_platform_data svs_mt8188_platform_data = {
.name = "mt8188-svs",
.banks = svs_mt8188_banks,
- .efuse_parsing = svs_mt8188_efuse_parsing,
+ .efuse_parsing = svs_common_parse_efuse,
.probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8188_banks),
@@ -2945,7 +2745,7 @@ static const struct svs_platform_data svs_mt8188_platform_data = {
static const struct svs_platform_data svs_mt8186_platform_data = {
.name = "mt8186-svs",
.banks = svs_mt8186_banks,
- .efuse_parsing = svs_mt8186_efuse_parsing,
+ .efuse_parsing = svs_common_parse_efuse,
.probe = svs_mt8186_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8186_banks),
@@ -3025,7 +2825,7 @@ static int svs_probe(struct platform_device *pdev)
goto svs_probe_free_efuse;
}
- if (!svsp_data->efuse_parsing(svsp)) {
+ if (!svsp_data->efuse_parsing(svsp, svsp_data)) {
dev_err(svsp->dev, "efuse data parsing failed\n");
ret = -EPERM;
goto svs_probe_free_tefuse;
--
2.42.0
Some members of struct svs_bank are not changed during runtime, so those
are not variables but constants: move all of those to a new structure
called svs_bank_pdata and refactor the code to make use of that and
reorder members by size where possible.
This effectively moves at least 50 bytes to the text segment.
While at it, also uniform the thermal zone names across the banks.
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 1198 +++++++++++++++++---------------
1 file changed, 628 insertions(+), 570 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index df39e7430ba9..edf4ab14bc23 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2022 MediaTek Inc.
+ * Copyright (C) 2022 Collabora Ltd.
+ * AngeloGioacchino Del Regno <[email protected]>
*/
#include <linux/bitfield.h>
@@ -377,10 +379,10 @@ struct svs_fusemap {
* @efuse_max: total number of svs efuse
* @tefuse_max: total number of thermal efuse
* @regs: svs platform registers map
- * @bank_max: total number of svs banks
* @efuse: svs efuse data received from NVMEM framework
* @tefuse: thermal efuse data received from NVMEM framework
* @ts_coeff: thermal sensors coefficient
+ * @bank_max: total number of svs banks
*/
struct svs_platform {
void __iomem *base;
@@ -391,10 +393,10 @@ struct svs_platform {
size_t efuse_max;
size_t tefuse_max;
const u32 *regs;
- u32 bank_max;
u32 *efuse;
u32 *tefuse;
u32 ts_coeff;
+ u16 bank_max;
};
struct svs_platform_data {
@@ -404,59 +406,92 @@ struct svs_platform_data {
int (*probe)(struct svs_platform *svsp);
const struct svs_fusemap *glb_fuse_map;
const u32 *regs;
- u32 bank_max;
u32 ts_coeff;
+ u16 bank_max;
};
/**
- * struct svs_bank - svs bank representation
+ * struct svs_bank_pdata - SVS Bank immutable config parameters
* @dev_fuse_map: Bank fuse map data
+ * @buck_name: Regulator name
+ * @tzone_name: Thermal zone name
+ * @age_config: Bank age configuration
+ * @ctl0: TS-x selection
+ * @dc_config: Bank dc configuration
+ * @int_st: Bank interrupt identification
+ * @turn_freq_base: Reference frequency for 2-line turn point
+ * @tzone_htemp: Thermal zone high temperature threshold
+ * @tzone_ltemp: Thermal zone low temperature threshold
+ * @volt_step: Bank voltage step
+ * @volt_base: Bank voltage base
+ * @tzone_htemp_voffset: Thermal zone high temperature voltage offset
+ * @tzone_ltemp_voffset: Thermal zone low temperature voltage offset
+ * @chk_shift: Bank chicken shift
+ * @cpu_id: CPU core ID for SVS CPU bank use only
+ * @opp_count: Bank opp count
+ * @vboot: Voltage request for bank init01 only
+ * @vco: Bank VCO value
+ * @sw_id: Bank software identification
+ * @type: SVS Bank Type (1 or 2-line) and Role (high/low)
+ * @set_freq_pct: function pointer to set bank frequency percent table
+ * @get_volts: function pointer to get bank voltages
+ */
+struct svs_bank_pdata {
+ const struct svs_fusemap *dev_fuse_map;
+ char *buck_name;
+ char *tzone_name;
+ u32 age_config;
+ u32 ctl0;
+ u32 dc_config;
+ u32 int_st;
+ u32 turn_freq_base;
+ u32 tzone_htemp;
+ u32 tzone_ltemp;
+ u32 volt_step;
+ u32 volt_base;
+ u16 tzone_htemp_voffset;
+ u16 tzone_ltemp_voffset;
+ u8 chk_shift;
+ u8 cpu_id;
+ u8 opp_count;
+ u8 vboot;
+ u8 vco;
+ u8 sw_id;
+ u8 type;
+
+ /* Callbacks */
+ void (*set_freq_pct)(struct svs_platform *svsp, struct svs_bank *svsb);
+ void (*get_volts)(struct svs_platform *svsp, struct svs_bank *svsb);
+};
+
+/**
+ * struct svs_bank - svs bank representation
+ * @pdata: SVS Bank immutable config parameters
* @dev: bank device
* @opp_dev: device for opp table/buck control
* @init_completion: the timeout completion for bank init
* @buck: regulator used by opp_dev
* @tzd: thermal zone device for getting temperature
* @lock: mutex lock to protect voltage update process
- * @set_freq_pct: function pointer to set bank frequency percent table
- * @get_volts: function pointer to get bank voltages
* @name: bank name
- * @buck_name: regulator name
- * @tzone_name: thermal zone name
* @phase: bank current phase
* @volt_od: bank voltage overdrive
* @reg_data: bank register data in different phase for debug purpose
* @pm_runtime_enabled_count: bank pm runtime enabled count
- * @mode_support: bank mode support.
+ * @mode_support: bank mode support
* @freq_base: reference frequency for bank init
- * @turn_freq_base: refenrece frequency for 2-line turn point
- * @vboot: voltage request for bank init01 only
* @opp_dfreq: default opp frequency table
* @opp_dvolt: default opp voltage table
* @freq_pct: frequency percent table for bank init
* @volt: bank voltage table
- * @volt_step: bank voltage step
- * @volt_base: bank voltage base
* @volt_flags: bank voltage flags
* @vmax: bank voltage maximum
* @vmin: bank voltage minimum
- * @age_config: bank age configuration
* @age_voffset_in: bank age voltage offset
- * @dc_config: bank dc configuration
* @dc_voffset_in: bank dc voltage offset
* @dvt_fixed: bank dvt fixed value
- * @vco: bank VCO value
- * @chk_shift: bank chicken shift
* @core_sel: bank selection
- * @opp_count: bank opp count
- * @int_st: bank interrupt identification
- * @sw_id: bank software identification
- * @cpu_id: cpu core id for SVS CPU bank use only
- * @ctl0: TS-x selection
* @temp: bank temperature
- * @tzone_htemp: thermal zone high temperature threshold
- * @tzone_htemp_voffset: thermal zone high temperature voltage offset
- * @tzone_ltemp: thermal zone low temperature threshold
- * @tzone_ltemp_voffset: thermal zone low temperature voltage offset
* @bts: svs efuse data
* @mts: svs efuse data
* @bdes: svs efuse data
@@ -466,61 +501,41 @@ struct svs_platform_data {
* @dcmdet: svs efuse data
* @turn_pt: 2-line turn point tells which opp_volt calculated by high/low bank
* @vbin_turn_pt: voltage bin turn point helps know which svsb_volt should be overridden
- * @type: bank type to represent it is 2-line (high/low) bank or 1-line bank
*
- * Svs bank will generate suitalbe voltages by below general math equation
+ * Svs bank will generate suitable voltages by below general math equation
* and provide these voltages to opp voltage table.
*
* opp_volt[i] = (volt[i] * volt_step) + volt_base;
*/
struct svs_bank {
- const struct svs_fusemap *dev_fuse_map;
+ const struct svs_bank_pdata pdata;
struct device *dev;
struct device *opp_dev;
struct completion init_completion;
struct regulator *buck;
struct thermal_zone_device *tzd;
- struct mutex lock; /* lock to protect voltage update process */
- void (*set_freq_pct)(struct svs_platform *svsp, struct svs_bank *svsb);
- void (*get_volts)(struct svs_platform *svsp, struct svs_bank *svsb);
+ struct mutex lock;
+ int pm_runtime_enabled_count;
+ short int volt_od;
char *name;
- char *buck_name;
- char *tzone_name;
enum svsb_phase phase;
- short int volt_od;
u32 reg_data[SVSB_PHASE_MAX][SVS_REG_MAX];
- u32 pm_runtime_enabled_count;
u8 mode_support;
- u32 freq_base;
- u32 turn_freq_base;
- u8 vboot;
u32 opp_dfreq[MAX_OPP_ENTRIES];
u32 opp_dvolt[MAX_OPP_ENTRIES];
u32 freq_pct[MAX_OPP_ENTRIES];
u32 volt[MAX_OPP_ENTRIES];
- u32 volt_step;
- u32 volt_base;
u32 volt_flags;
- u8 vmax;
- u8 vmin;
- u32 age_config;
+ u32 freq_base;
+ u32 turn_pt;
+ u32 vbin_turn_pt;
+ u32 core_sel;
+ u32 temp;
u16 age_voffset_in;
- u32 dc_config;
u16 dc_voffset_in;
u8 dvt_fixed;
- u8 vco;
- u8 chk_shift;
- u32 core_sel;
- u8 opp_count;
- u32 int_st;
- u8 sw_id;
- u8 cpu_id;
- u32 ctl0;
- u32 temp;
- u32 tzone_htemp;
- u16 tzone_htemp_voffset;
- u32 tzone_ltemp;
- u16 tzone_ltemp_voffset;
+ u8 vmax;
+ u8 vmin;
u16 bts;
u16 mts;
u16 bdes;
@@ -528,9 +543,6 @@ struct svs_bank {
u8 mtdes;
u8 dcbdet;
u8 dcmdet;
- u32 turn_pt;
- u32 vbin_turn_pt;
- u8 type;
};
static u32 percent(u32 numerator, u32 denominator)
@@ -572,10 +584,11 @@ static u32 svs_opp_volt_to_bank_volt(u32 opp_u_volt, u32 svsb_volt_step,
static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
{
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
struct dev_pm_opp *opp;
u32 i, opp_u_volt;
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < bdata->opp_count; i++) {
opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
svsb->opp_dfreq[i],
true);
@@ -587,8 +600,8 @@ static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
opp_u_volt = dev_pm_opp_get_voltage(opp);
svsb->volt[i] = svs_opp_volt_to_bank_volt(opp_u_volt,
- svsb->volt_step,
- svsb->volt_base);
+ bdata->volt_step,
+ bdata->volt_base);
dev_pm_opp_put(opp);
}
@@ -598,6 +611,7 @@ static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
{
int ret = -EPERM, tzone_temp = 0;
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
u32 i, svsb_volt, opp_volt, temp_voffset = 0, opp_start, opp_stop;
mutex_lock(&svsb->lock);
@@ -606,15 +620,15 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
* 2-line bank updates its corresponding opp volts.
* 1-line bank updates all opp volts.
*/
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
opp_start = 0;
opp_stop = svsb->turn_pt;
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
opp_start = svsb->turn_pt;
- opp_stop = svsb->opp_count;
+ opp_stop = bdata->opp_count;
} else {
opp_start = 0;
- opp_stop = svsb->opp_count;
+ opp_stop = bdata->opp_count;
}
/* Get thermal effect */
@@ -623,20 +637,20 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n",
- svsb->tzone_name, ret, svsb->temp);
+ bdata->tzone_name, ret, svsb->temp);
svsb->phase = SVSB_PHASE_ERROR;
}
- if (tzone_temp >= svsb->tzone_htemp)
- temp_voffset += svsb->tzone_htemp_voffset;
- else if (tzone_temp <= svsb->tzone_ltemp)
- temp_voffset += svsb->tzone_ltemp_voffset;
+ if (tzone_temp >= bdata->tzone_htemp)
+ temp_voffset += bdata->tzone_htemp_voffset;
+ else if (tzone_temp <= bdata->tzone_ltemp)
+ temp_voffset += bdata->tzone_ltemp_voffset;
/* 2-line bank update all opp volts when running mon mode */
- if (svsb->phase == SVSB_PHASE_MON && (svsb->type == SVSB_TYPE_HIGH ||
- svsb->type == SVSB_TYPE_LOW)) {
+ if (svsb->phase == SVSB_PHASE_MON && (bdata->type == SVSB_TYPE_HIGH ||
+ bdata->type == SVSB_TYPE_LOW)) {
opp_start = 0;
- opp_stop = svsb->opp_count;
+ opp_stop = bdata->opp_count;
}
}
@@ -653,8 +667,8 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
case SVSB_PHASE_MON:
svsb_volt = max(svsb->volt[i] + temp_voffset, svsb->vmin);
opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
- svsb->volt_step,
- svsb->volt_base);
+ bdata->volt_step,
+ bdata->volt_base);
break;
default:
dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase);
@@ -816,7 +830,7 @@ static int svs_status_debug_show(struct seq_file *m, void *v)
svsb->name, tzone_temp, svsb->vbin_turn_pt,
svsb->turn_pt);
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < svsb->pdata.opp_count; i++) {
opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
svsb->opp_dfreq[i], true);
if (IS_ERR(opp)) {
@@ -923,9 +937,10 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
u32 i, j, *vop, vop74, vop30, turn_pt = svsb->turn_pt;
u32 b_sft, shift_byte = 0, opp_start = 0, opp_stop = 0;
- u32 middle_index = (svsb->opp_count / 2);
+ u32 middle_index = (bdata->opp_count / 2);
if (svsb->phase == SVSB_PHASE_MON &&
svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
@@ -936,7 +951,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
/* Target is to set svsb->volt[] by algorithm */
if (turn_pt < middle_index) {
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
/* volt[0] ~ volt[turn_pt - 1] */
for (i = 0; i < turn_pt; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
@@ -945,12 +960,12 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
shift_byte++;
}
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
- j = svsb->opp_count - 7;
+ j = bdata->opp_count - 7;
svsb->volt[turn_pt] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30);
shift_byte++;
- for (i = j; i < svsb->opp_count; i++) {
+ for (i = j; i < bdata->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
vop = (shift_byte < REG_BYTES) ? &vop30 :
&vop74;
@@ -967,7 +982,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
svsb->freq_pct[i]);
}
} else {
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
j = turn_pt - 7;
svsb->volt[0] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30);
@@ -987,9 +1002,9 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
svsb->volt[0],
svsb->volt[j],
svsb->freq_pct[i]);
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
/* volt[turn_pt] ~ volt[opp_count - 1] */
- for (i = turn_pt; i < svsb->opp_count; i++) {
+ for (i = turn_pt; i < bdata->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
vop = (shift_byte < REG_BYTES) ? &vop30 :
&vop74;
@@ -999,12 +1014,12 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
}
}
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
opp_start = 0;
opp_stop = svsb->turn_pt;
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
opp_start = svsb->turn_pt;
- opp_stop = svsb->opp_count;
+ opp_stop = bdata->opp_count;
}
for (i = opp_start; i < opp_stop; i++)
@@ -1014,11 +1029,11 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
/* For voltage bin support */
if (svsb->opp_dfreq[0] > svsb->freq_base) {
svsb->volt[0] = svs_opp_volt_to_bank_volt(svsb->opp_dvolt[0],
- svsb->volt_step,
- svsb->volt_base);
+ bdata->volt_step,
+ bdata->volt_base);
/* Find voltage bin turn point */
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < bdata->opp_count; i++) {
if (svsb->opp_dfreq[i] <= svsb->freq_base) {
svsb->vbin_turn_pt = i;
break;
@@ -1037,12 +1052,13 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *sv
static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0;
u32 b_sft, shift_byte = 0, turn_pt;
- u32 middle_index = (svsb->opp_count / 2);
+ u32 middle_index = (bdata->opp_count / 2);
- for (i = 0; i < svsb->opp_count; i++) {
- if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) {
+ for (i = 0; i < bdata->opp_count; i++) {
+ if (svsb->opp_dfreq[i] <= bdata->turn_freq_base) {
svsb->turn_pt = i;
break;
}
@@ -1052,7 +1068,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank
/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
if (turn_pt < middle_index) {
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
/*
* If we don't handle this situation,
* SVSB_TYPE_HIGH's FREQPCT74 / FREQPCT30 would keep "0"
@@ -1069,15 +1085,15 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank
*freq_pct |= (svsb->freq_pct[i] << b_sft);
shift_byte++;
}
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
/*
* freq_pct[turn_pt] +
* freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
*/
freq_pct30 = svsb->freq_pct[turn_pt];
shift_byte++;
- j = svsb->opp_count - 7;
- for (i = j; i < svsb->opp_count; i++) {
+ j = bdata->opp_count - 7;
+ for (i = j; i < bdata->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
freq_pct = (shift_byte < REG_BYTES) ?
&freq_pct30 : &freq_pct74;
@@ -1086,7 +1102,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank
}
}
} else {
- if (svsb->type == SVSB_TYPE_HIGH) {
+ if (bdata->type == SVSB_TYPE_HIGH) {
/*
* freq_pct[0] +
* freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
@@ -1101,9 +1117,9 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank
*freq_pct |= (svsb->freq_pct[i] << b_sft);
shift_byte++;
}
- } else if (svsb->type == SVSB_TYPE_LOW) {
+ } else if (bdata->type == SVSB_TYPE_LOW) {
/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
- for (i = turn_pt; i < svsb->opp_count; i++) {
+ for (i = turn_pt; i < bdata->opp_count; i++) {
b_sft = BITS8 * (shift_byte % REG_BYTES);
freq_pct = (shift_byte < REG_BYTES) ?
&freq_pct30 : &freq_pct74;
@@ -1119,6 +1135,7 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank
static void svs_get_bank_volts_v2(struct svs_platform *svsp, struct svs_bank *svsb)
{
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
u32 temp, i;
temp = svs_readl_relaxed(svsp, VOP74);
@@ -1146,17 +1163,17 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp, struct svs_bank *sv
svsb->volt[14],
svsb->freq_pct[15]);
- for (i = 0; i < svsb->opp_count; i++)
+ for (i = 0; i < bdata->opp_count; i++)
svsb->volt[i] += svsb->volt_od;
/* For voltage bin support */
if (svsb->opp_dfreq[0] > svsb->freq_base) {
svsb->volt[0] = svs_opp_volt_to_bank_volt(svsb->opp_dvolt[0],
- svsb->volt_step,
- svsb->volt_base);
+ bdata->volt_step,
+ bdata->volt_base);
/* Find voltage bin turn point */
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < bdata->opp_count; i++) {
if (svsb->opp_dfreq[i] <= svsb->freq_base) {
svsb->vbin_turn_pt = i;
break;
@@ -1196,6 +1213,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
enum svsb_phase target_phase)
{
struct svs_bank *svsb = &svsp->banks[bank_idx];
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
u32 des_char, temp_char, det_char, limit_vals, init2vals, ts_calcs;
svs_switch_bank(svsp, svsb);
@@ -1204,7 +1222,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
FIELD_PREP(SVSB_DESCHAR_FLD_MDES, svsb->mdes);
svs_writel_relaxed(svsp, des_char, DESCHAR);
- temp_char = FIELD_PREP(SVSB_TEMPCHAR_FLD_VCO, svsb->vco) |
+ temp_char = FIELD_PREP(SVSB_TEMPCHAR_FLD_VCO, bdata->vco) |
FIELD_PREP(SVSB_TEMPCHAR_FLD_MTDES, svsb->mtdes) |
FIELD_PREP(SVSB_TEMPCHAR_FLD_DVT_FIXED, svsb->dvt_fixed);
svs_writel_relaxed(svsp, temp_char, TEMPCHAR);
@@ -1213,11 +1231,11 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
FIELD_PREP(SVSB_DETCHAR_FLD_DCMDET, svsb->dcmdet);
svs_writel_relaxed(svsp, det_char, DETCHAR);
- svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG);
- svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG);
+ svs_writel_relaxed(svsp, bdata->dc_config, DCCONFIG);
+ svs_writel_relaxed(svsp, bdata->age_config, AGECONFIG);
svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);
- svsb->set_freq_pct(svsp, svsb);
+ bdata->set_freq_pct(svsp, svsb);
limit_vals = FIELD_PREP(SVSB_LIMITVALS_FLD_DTLO, SVSB_VAL_DTLO) |
FIELD_PREP(SVSB_LIMITVALS_FLD_DTHI, SVSB_VAL_DTHI) |
@@ -1227,13 +1245,13 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW);
svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG);
- svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT);
- svs_writel_relaxed(svsp, svsb->ctl0, CTL0);
+ svs_writel_relaxed(svsp, bdata->chk_shift, CHKSHIFT);
+ svs_writel_relaxed(svsp, bdata->ctl0, CTL0);
svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
switch (target_phase) {
case SVSB_PHASE_INIT01:
- svs_writel_relaxed(svsp, svsb->vboot, VBOOT);
+ svs_writel_relaxed(svsp, bdata->vboot, VBOOT);
svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN);
svs_writel_relaxed(svsp, SVSB_PTPEN_INIT01, SVSEN);
break;
@@ -1324,6 +1342,7 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp,
unsigned short bank_idx)
{
struct svs_bank *svsb = &svsp->banks[bank_idx];
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n",
__func__, svs_readl_relaxed(svsp, VOP74),
@@ -1333,7 +1352,7 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp,
svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_INIT02);
svsb->phase = SVSB_PHASE_INIT02;
- svsb->get_volts(svsp, svsb);
+ bdata->get_volts(svsp, svsb);
svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
svs_writel_relaxed(svsp, SVSB_INTSTS_F0_COMPLETE, INTSTS);
@@ -1343,11 +1362,12 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp,
unsigned short bank_idx)
{
struct svs_bank *svsb = &svsp->banks[bank_idx];
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_MON);
svsb->phase = SVSB_PHASE_MON;
- svsb->get_volts(svsp, svsb);
+ bdata->get_volts(svsp, svsb);
svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
svs_writel_relaxed(svsp, SVSB_INTSTS_FLD_MONVOP, INTSTS);
@@ -1356,18 +1376,20 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp,
static irqreturn_t svs_isr(int irq, void *data)
{
struct svs_platform *svsp = data;
+ const struct svs_bank_pdata *bdata;
struct svs_bank *svsb = NULL;
unsigned long flags;
u32 idx, int_sts, svs_en;
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name);
spin_lock_irqsave(&svs_lock, flags);
/* Find out which svs bank fires interrupt */
- if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) {
+ if (bdata->int_st & svs_readl_relaxed(svsp, INTST)) {
spin_unlock_irqrestore(&svs_lock, flags);
continue;
}
@@ -1412,6 +1434,7 @@ static bool svs_mode_available(struct svs_platform *svsp, u8 mode)
static int svs_init01(struct svs_platform *svsp)
{
+ const struct svs_bank_pdata *bdata;
struct svs_bank *svsb;
unsigned long flags, time_left;
bool search_done;
@@ -1427,6 +1450,7 @@ static int svs_init01(struct svs_platform *svsp)
/* Svs bank init01 preparation - power enable */
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
if (!(svsb->mode_support & SVSB_MODE_INIT01))
continue;
@@ -1434,7 +1458,7 @@ static int svs_init01(struct svs_platform *svsp)
ret = regulator_enable(svsb->buck);
if (ret) {
dev_err(svsb->dev, "%s enable fail: %d\n",
- svsb->buck_name, ret);
+ bdata->buck_name, ret);
goto svs_init01_resume_cpuidle;
}
@@ -1464,6 +1488,7 @@ static int svs_init01(struct svs_platform *svsp)
*/
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
if (!(svsb->mode_support & SVSB_MODE_INIT01))
continue;
@@ -1473,11 +1498,11 @@ static int svs_init01(struct svs_platform *svsp)
* fix to that freq until svs_init01 is done.
*/
search_done = false;
- opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
- svsb->volt_step,
- svsb->volt_base);
+ opp_vboot = svs_bank_volt_to_opp_volt(bdata->vboot,
+ bdata->volt_step,
+ bdata->volt_base);
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < bdata->opp_count; i++) {
opp_freq = svsb->opp_dfreq[i];
if (!search_done && svsb->opp_dvolt[i] <= opp_vboot) {
ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
@@ -1509,13 +1534,14 @@ static int svs_init01(struct svs_platform *svsp)
/* Svs bank init01 begins */
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
if (!(svsb->mode_support & SVSB_MODE_INIT01))
continue;
- opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
- svsb->volt_step,
- svsb->volt_base);
+ opp_vboot = svs_bank_volt_to_opp_volt(bdata->vboot,
+ bdata->volt_step,
+ bdata->volt_base);
buck_volt = regulator_get_voltage(svsb->buck);
if (buck_volt != opp_vboot) {
@@ -1542,11 +1568,12 @@ static int svs_init01(struct svs_platform *svsp)
svs_init01_finish:
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
if (!(svsb->mode_support & SVSB_MODE_INIT01))
continue;
- for (i = 0; i < svsb->opp_count; i++) {
+ for (i = 0; i < bdata->opp_count; i++) {
r = dev_pm_opp_enable(svsb->opp_dev,
svsb->opp_dfreq[i]);
if (r)
@@ -1572,7 +1599,7 @@ static int svs_init01(struct svs_platform *svsp)
r = regulator_disable(svsb->buck);
if (r)
dev_err(svsb->dev, "%s disable fail: %d\n",
- svsb->buck_name, r);
+ bdata->buck_name, r);
}
svs_init01_resume_cpuidle:
@@ -1583,6 +1610,7 @@ static int svs_init01(struct svs_platform *svsp)
static int svs_init02(struct svs_platform *svsp)
{
+ const struct svs_bank_pdata *bdata;
struct svs_bank *svsb;
unsigned long flags, time_left;
int ret;
@@ -1618,11 +1646,12 @@ static int svs_init02(struct svs_platform *svsp)
*/
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
if (!(svsb->mode_support & SVSB_MODE_INIT02))
continue;
- if (svsb->type == SVSB_TYPE_HIGH || svsb->type == SVSB_TYPE_LOW) {
+ if (bdata->type == SVSB_TYPE_HIGH || bdata->type == SVSB_TYPE_LOW) {
if (svs_sync_bank_volts_from_opp(svsb)) {
dev_err(svsb->dev, "sync volt fail\n");
ret = -EPERM;
@@ -1680,12 +1709,12 @@ static int svs_start(struct svs_platform *svsp)
static int svs_suspend(struct device *dev)
{
struct svs_platform *svsp = dev_get_drvdata(dev);
- struct svs_bank *svsb;
int ret;
u32 idx;
for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
+ struct svs_bank *svsb = &svsp->banks[idx];
+
svs_bank_disable_and_restore_default_volts(svsp, svsb);
}
@@ -1736,6 +1765,7 @@ static int svs_resume(struct device *dev)
static int svs_bank_resource_setup(struct svs_platform *svsp)
{
+ const struct svs_bank_pdata *bdata;
struct svs_bank *svsb;
struct dev_pm_opp *opp;
unsigned long freq;
@@ -1746,8 +1776,9 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
- if (svsb->sw_id >= SVSB_SWID_MAX || svsb->type >= SVSB_TYPE_MAX) {
+ if (bdata->sw_id >= SVSB_SWID_MAX || bdata->type >= SVSB_TYPE_MAX) {
dev_err(svsb->dev, "unknown bank sw_id or type\n");
return -EINVAL;
}
@@ -1757,8 +1788,8 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
return -ENOMEM;
svsb->name = devm_kasprintf(svsp->dev, GFP_KERNEL, "%s%s",
- svs_swid_names[svsb->sw_id],
- svs_type_names[svsb->type]);
+ svs_swid_names[bdata->sw_id],
+ svs_type_names[bdata->type]);
if (!svsb->name)
return -ENOMEM;
@@ -1779,10 +1810,10 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
if (svsb->mode_support & SVSB_MODE_INIT01) {
svsb->buck = devm_regulator_get_optional(svsb->opp_dev,
- svsb->buck_name);
+ bdata->buck_name);
if (IS_ERR(svsb->buck)) {
dev_err(svsb->dev, "cannot get \"%s-supply\"\n",
- svsb->buck_name);
+ bdata->buck_name);
return PTR_ERR(svsb->buck);
}
}
@@ -1797,14 +1828,14 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
}
count = dev_pm_opp_get_opp_count(svsb->opp_dev);
- if (svsb->opp_count != count) {
+ if (bdata->opp_count != count) {
dev_err(svsb->dev,
"opp_count not \"%u\" but get \"%d\"?\n",
- svsb->opp_count, count);
+ bdata->opp_count, count);
return count;
}
- for (i = 0, freq = ULONG_MAX; i < svsb->opp_count; i++, freq--) {
+ for (i = 0, freq = ULONG_MAX; i < bdata->opp_count; i++, freq--) {
opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq);
if (IS_ERR(opp)) {
dev_err(svsb->dev, "cannot find freq = %ld\n",
@@ -1901,7 +1932,8 @@ static bool svs_common_parse_efuse(struct svs_platform *svsp,
for (i = 0; i < svsp->bank_max; i++) {
struct svs_bank *svsb = &svsp->banks[i];
- const struct svs_fusemap *dfmap = svsb->dev_fuse_map;
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
+ const struct svs_fusemap *dfmap = bdata->dev_fuse_map;
if (vmin == 1)
svsb->vmin = 0x1e;
@@ -1927,11 +1959,11 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
const struct svs_platform_data *pdata)
{
struct svs_bank *svsb;
+ const struct svs_bank_pdata *bdata;
int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0;
int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t;
int o_slope, o_slope_sign, ts_id;
u32 idx, i, ft_pgm, mts, temp0, temp1, temp2;
- int ret;
for (i = 0; i < svsp->efuse_max; i++)
if (svsp->efuse[i])
@@ -1948,7 +1980,8 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
- const struct svs_fusemap *dfmap = svsb->dev_fuse_map;
+ bdata = &svsb->pdata;
+ const struct svs_fusemap *dfmap = bdata->dev_fuse_map;
if (ft_pgm <= 1)
svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
@@ -1959,7 +1992,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
svsb->dcbdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCBDET], 8);
svsb->dcmdet = svs_get_fuse_val(svsp->efuse, &dfmap[BDEV_DCMDET], 8);
- switch (svsb->sw_id) {
+ switch (bdata->sw_id) {
case SVSB_SWID_CPU_LITTLE:
case SVSB_SWID_CCI:
if (ft_pgm <= 3)
@@ -2044,9 +2077,10 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
+ bdata = &svsb->pdata;
svsb->mts = mts;
- switch (svsb->sw_id) {
+ switch (bdata->sw_id) {
case SVSB_SWID_CPU_LITTLE:
tb_roomt = x_roomt[3];
break;
@@ -2060,7 +2094,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
tb_roomt = x_roomt[1];
break;
default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+ dev_err(svsb->dev, "unknown sw_id: %u\n", bdata->sw_id);
goto remove_mt8183_svsb_mon_mode;
}
@@ -2147,24 +2181,24 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
for (idx = 0; idx < svsp->bank_max; idx++) {
struct svs_bank *svsb = &svsp->banks[idx];
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
- switch (svsb->sw_id) {
+ switch (bdata->sw_id) {
case SVSB_SWID_CPU_LITTLE:
case SVSB_SWID_CPU_BIG:
- svsb->opp_dev = get_cpu_device(svsb->cpu_id);
+ svsb->opp_dev = get_cpu_device(bdata->cpu_id);
break;
case SVSB_SWID_CCI:
svsb->opp_dev = svs_add_device_link(svsp, "cci");
break;
case SVSB_SWID_GPU:
- if (svsb->type == SVSB_TYPE_LOW)
+ if (bdata->type == SVSB_TYPE_LOW)
svsb->opp_dev = svs_get_subsys_device(svsp, "gpu");
else
svsb->opp_dev = svs_add_device_link(svsp, "gpu");
break;
- break;
default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+ dev_err(svsb->dev, "unknown sw_id: %u\n", bdata->sw_id);
return -EINVAL;
}
@@ -2180,7 +2214,6 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
static int svs_mt8183_platform_probe(struct svs_platform *svsp)
{
struct device *dev;
- struct svs_bank *svsb;
u32 idx;
dev = svs_add_device_link(svsp, "thermal-sensor");
@@ -2189,12 +2222,13 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
"failed to get thermal device\n");
for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
+ struct svs_bank *svsb = &svsp->banks[idx];
+ const struct svs_bank_pdata *bdata = &svsb->pdata;
- switch (svsb->sw_id) {
+ switch (bdata->sw_id) {
case SVSB_SWID_CPU_LITTLE:
case SVSB_SWID_CPU_BIG:
- svsb->opp_dev = get_cpu_device(svsb->cpu_id);
+ svsb->opp_dev = get_cpu_device(bdata->cpu_id);
break;
case SVSB_SWID_CCI:
svsb->opp_dev = svs_add_device_link(svsp, "cci");
@@ -2203,7 +2237,7 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
svsb->opp_dev = svs_add_device_link(svsp, "gpu");
break;
default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+ dev_err(svsb->dev, "unknown sw_id: %u\n", bdata->sw_id);
return -EINVAL;
}
@@ -2218,463 +2252,486 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
static struct svs_bank svs_mt8195_banks[] = {
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_LOW,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
- .mode_support = SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 640000000,
- .turn_freq_base = 640000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x38,
- .vmin = 0x14,
- .age_config = 0x555555,
- .dc_config = 0x1,
- .dvt_fixed = 0x1,
- .vco = 0x18,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0100,
- .int_st = BIT(0),
- .ctl0 = 0x00540003,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 10, 16 }, { 10, 24 }, { 10, 0 }, { 8, 0 }, { 8, 8 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x1,
+ .vco = 0x18,
+ .chk_shift = 0x87,
+ .int_st = BIT(0),
+ .ctl0 = 0x00540003,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 10, 16 }, { 10, 24 }, { 10, 0 }, { 8, 0 }, { 8, 8 }
+ }
+ },
+ .mode_support = SVSB_MODE_INIT02,
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
+ .freq_base = 640000000,
+ .core_sel = 0x0fff0100,
+ .dvt_fixed = 0x1,
+ .vmax = 0x38,
+ .vmin = 0x14,
},
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_HIGH,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .tzone_name = "gpu1",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 880000000,
- .turn_freq_base = 640000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x38,
- .vmin = 0x14,
- .age_config = 0x555555,
- .dc_config = 0x1,
- .dvt_fixed = 0x6,
- .vco = 0x18,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0101,
- .int_st = BIT(1),
- .ctl0 = 0x00540003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 0,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 7,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 9, 16 }, { 9, 24 }, { 9, 0 }, { 8, 0 }, { 8, 8 }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x1,
+ .vco = 0x18,
+ .chk_shift = 0x87,
+ .int_st = BIT(1),
+ .ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 9, 16 }, { 9, 24 }, { 9, 0 }, { 8, 0 }, { 8, 8 }
+ },
},
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 880000000,
+ .core_sel = 0x0fff0101,
+ .dvt_fixed = 0x6,
+ .vmax = 0x38,
+ .vmin = 0x14,
},
};
static struct svs_bank svs_mt8192_banks[] = {
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_LOW,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .tzone_name = "gpu1",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
- .mode_support = SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 688000000,
- .turn_freq_base = 688000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x60,
- .vmin = 0x1a,
- .age_config = 0x555555,
- .dc_config = 0x1,
- .dvt_fixed = 0x1,
- .vco = 0x18,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0100,
- .int_st = BIT(0),
- .ctl0 = 0x00540003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 0,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 7,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 10, 16 }, { 10, 24 }, { 10, 0 }, { 17, 0 }, { 17, 8 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 688000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x1,
+ .vco = 0x18,
+ .chk_shift = 0x87,
+ .int_st = BIT(0),
+ .ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 10, 16 }, { 10, 24 }, { 10, 0 }, { 17, 0 }, { 17, 8 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
+ .mode_support = SVSB_MODE_INIT02,
+ .freq_base = 688000000,
+ .core_sel = 0x0fff0100,
+ .dvt_fixed = 0x1,
+ .vmax = 0x60,
+ .vmin = 0x1a,
},
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_HIGH,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .tzone_name = "gpu1",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 902000000,
- .turn_freq_base = 688000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x60,
- .vmin = 0x1a,
- .age_config = 0x555555,
- .dc_config = 0x1,
- .dvt_fixed = 0x6,
- .vco = 0x18,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0101,
- .int_st = BIT(1),
- .ctl0 = 0x00540003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 0,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 7,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 9, 16 }, { 9, 24 }, { 17, 0 }, { 17, 16 }, { 17, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 688000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x1,
+ .vco = 0x18,
+ .chk_shift = 0x87,
+ .int_st = BIT(1),
+ .ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 9, 16 }, { 9, 24 }, { 17, 0 }, { 17, 16 }, { 17, 24 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 902000000,
+ .core_sel = 0x0fff0101,
+ .dvt_fixed = 0x6,
+ .vmax = 0x60,
+ .vmin = 0x1a,
},
};
static struct svs_bank svs_mt8188_banks[] = {
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_LOW,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
- .mode_support = SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 640000000,
- .turn_freq_base = 640000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x38,
- .vmin = 0x1c,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x1,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0000,
- .int_st = BIT(0),
- .ctl0 = 0x00100003,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 5, 16 }, { 5, 24 }, { 5, 0 }, { 15, 16 }, { 15, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_LOW,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(0),
+ .ctl0 = 0x00100003,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 5, 16 }, { 5, 24 }, { 5, 0 }, { 15, 16 }, { 15, 24 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
+ .mode_support = SVSB_MODE_INIT02,
+ .freq_base = 640000000,
+ .core_sel = 0x0fff0000,
+ .dvt_fixed = 0x1,
+ .vmax = 0x38,
+ .vmin = 0x1c,
},
{
- .sw_id = SVSB_SWID_GPU,
- .type = SVSB_TYPE_HIGH,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .tzone_name = "gpu1",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 880000000,
- .turn_freq_base = 640000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x38,
- .vmin = 0x1c,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x4,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0001,
- .int_st = BIT(1),
- .ctl0 = 0x00100003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 0,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 7,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 4, 16 }, { 4, 24 }, { 4, 0 }, { 14, 0 }, { 14, 8 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .type = SVSB_TYPE_HIGH,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 640000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(1),
+ .ctl0 = 0x00100003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 4, 16 }, { 4, 24 }, { 4, 0 }, { 14, 0 }, { 14, 8 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 880000000,
+ .core_sel = 0x0fff0001,
+ .dvt_fixed = 0x4,
+ .vmax = 0x38,
+ .vmin = 0x1c,
},
};
static struct svs_bank svs_mt8186_banks[] = {
{
- .sw_id = SVSB_SWID_CPU_BIG,
- .type = SVSB_TYPE_LOW,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .cpu_id = 6,
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
- .mode_support = SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 1670000000,
- .turn_freq_base = 1670000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .volt_od = 4,
- .vmax = 0x59,
- .vmin = 0x20,
- .age_config = 0x1,
- .dc_config = 0x1,
- .dvt_fixed = 0x3,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0100,
- .int_st = BIT(0),
- .ctl0 = 0x00540003,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 3, 16 }, { 3, 24 }, { 3, 0 }, { 14, 16 }, { 14, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CPU_BIG,
+ .type = SVSB_TYPE_LOW,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .cpu_id = 6,
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 1670000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x1,
+ .dc_config = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(0),
+ .ctl0 = 0x00540003,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 3, 16 }, { 3, 24 }, { 3, 0 }, { 14, 16 }, { 14, 24 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
+ .volt_od = 4,
+ .mode_support = SVSB_MODE_INIT02,
+ .freq_base = 1670000000,
+ .core_sel = 0x0fff0100,
+ .dvt_fixed = 0x3,
+ .vmax = 0x59,
+ .vmin = 0x20,
},
{
- .sw_id = SVSB_SWID_CPU_BIG,
- .type = SVSB_TYPE_HIGH,
- .set_freq_pct = svs_set_bank_freq_pct_v3,
- .get_volts = svs_get_bank_volts_v3,
- .cpu_id = 6,
- .tzone_name = "cpu_big0",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 2050000000,
- .turn_freq_base = 1670000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .volt_od = 4,
- .vmax = 0x73,
- .vmin = 0x20,
- .age_config = 0x1,
- .dc_config = 0x1,
- .dvt_fixed = 0x6,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0101,
- .int_st = BIT(1),
- .ctl0 = 0x00540003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 8,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 8,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 2, 16 }, { 2, 24 }, { 2, 0 }, { 13, 0 }, { 13, 8 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CPU_BIG,
+ .type = SVSB_TYPE_HIGH,
+ .set_freq_pct = svs_set_bank_freq_pct_v3,
+ .get_volts = svs_get_bank_volts_v3,
+ .cpu_id = 6,
+ .tzone_name = "cpu-big",
+ .opp_count = MAX_OPP_ENTRIES,
+ .turn_freq_base = 1670000000,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x1,
+ .dc_config = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(1),
+ .ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 8,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 8,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 2, 16 }, { 2, 24 }, { 2, 0 }, { 13, 0 }, { 13, 8 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .volt_od = 4,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 2050000000,
+ .core_sel = 0x0fff0101,
+ .dvt_fixed = 0x6,
+ .vmax = 0x73,
+ .vmin = 0x20,
},
{
- .sw_id = SVSB_SWID_CPU_LITTLE,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .cpu_id = 0,
- .tzone_name = "cpu_zone0",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 2000000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .volt_od = 3,
- .vmax = 0x65,
- .vmin = 0x20,
- .age_config = 0x1,
- .dc_config = 0x1,
- .dvt_fixed = 0x6,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0102,
- .int_st = BIT(2),
- .ctl0 = 0x3210000f,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 8,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 8,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 4, 16 }, { 4, 24 }, { 4, 0 }, { 14, 0 }, { 14, 8 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CPU_LITTLE,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .cpu_id = 0,
+ .tzone_name = "cpu-little",
+ .opp_count = MAX_OPP_ENTRIES,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x1,
+ .dc_config = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(2),
+ .ctl0 = 0x3210000f,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 8,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 8,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 4, 16 }, { 4, 24 }, { 4, 0 }, { 14, 0 }, { 14, 8 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .volt_od = 3,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 2000000000,
+ .core_sel = 0x0fff0102,
+ .dvt_fixed = 0x6,
+ .vmax = 0x65,
+ .vmin = 0x20,
},
{
- .sw_id = SVSB_SWID_CCI,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .tzone_name = "cpu_zone0",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 1400000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .volt_od = 3,
- .vmax = 0x65,
- .vmin = 0x20,
- .age_config = 0x1,
- .dc_config = 0x1,
- .dvt_fixed = 0x6,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0103,
- .int_st = BIT(3),
- .ctl0 = 0x3210000f,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 8,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 8,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 5, 16 }, { 5, 24 }, { 5, 0 }, { 15, 16 }, { 15, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CCI,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .tzone_name = "cci",
+ .opp_count = MAX_OPP_ENTRIES,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x1,
+ .dc_config = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(3),
+ .ctl0 = 0x3210000f,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 8,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 8,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 5, 16 }, { 5, 24 }, { 5, 0 }, { 15, 16 }, { 15, 24 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .volt_od = 3,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 1400000000,
+ .core_sel = 0x0fff0103,
+ .dvt_fixed = 0x6,
+ .vmax = 0x65,
+ .vmin = 0x20,
},
{
- .sw_id = SVSB_SWID_GPU,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .tzone_name = "mfg",
- .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT |
- SVSB_MON_VOLT_IGNORE,
- .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 850000000,
- .volt_step = 6250,
- .volt_base = 400000,
- .vmax = 0x58,
- .vmin = 0x20,
- .age_config = 0x555555,
- .dc_config = 0x1,
- .dvt_fixed = 0x4,
- .vco = 0x10,
- .chk_shift = 0x87,
- .core_sel = 0x0fff0104,
- .int_st = BIT(4),
- .ctl0 = 0x00100003,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 8,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 7,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 6, 16 }, { 6, 24 }, { 6, 0 }, { 15, 8 }, { 15, 0 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .volt_step = 6250,
+ .volt_base = 400000,
+ .age_config = 0x555555,
+ .dc_config = 0x1,
+ .vco = 0x10,
+ .chk_shift = 0x87,
+ .int_st = BIT(4),
+ .ctl0 = 0x00100003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 8,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 6, 16 }, { 6, 24 }, { 6, 0 }, { 15, 8 }, { 15, 0 }
+ }
+ },
+ .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | SVSB_MON_VOLT_IGNORE,
+ .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 850000000,
+ .core_sel = 0x0fff0104,
+ .dvt_fixed = 0x4,
+ .vmax = 0x58,
+ .vmin = 0x20,
},
};
static struct svs_bank svs_mt8183_banks[] = {
{
- .sw_id = SVSB_SWID_CPU_LITTLE,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .cpu_id = 0,
- .buck_name = "proc",
- .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
- .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 1989000000,
- .vboot = 0x30,
- .volt_step = 6250,
- .volt_base = 500000,
- .vmax = 0x64,
- .vmin = 0x18,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x7,
- .vco = 0x10,
- .chk_shift = 0x77,
- .core_sel = 0x8fff0000,
- .int_st = BIT(0),
- .ctl0 = 0x00010001,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 16, 0 }, { 16, 8 }, { 17, 16 }, { 16, 16 }, { 16, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CPU_LITTLE,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .cpu_id = 0,
+ .buck_name = "proc",
+ .opp_count = MAX_OPP_ENTRIES,
+ .vboot = 0x30,
+ .volt_step = 6250,
+ .volt_base = 500000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x77,
+ .int_st = BIT(0),
+ .ctl0 = 0x00010001,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 16, 0 }, { 16, 8 }, { 17, 16 }, { 16, 16 }, { 16, 24 }
+ }
+ },
+ .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
+ .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+ .freq_base = 1989000000,
+ .core_sel = 0x8fff0000,
+ .dvt_fixed = 0x7,
+ .vmax = 0x64,
+ .vmin = 0x18,
+
},
{
- .sw_id = SVSB_SWID_CPU_BIG,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .cpu_id = 4,
- .buck_name = "proc",
- .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
- .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 1989000000,
- .vboot = 0x30,
- .volt_step = 6250,
- .volt_base = 500000,
- .vmax = 0x58,
- .vmin = 0x10,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x7,
- .vco = 0x10,
- .chk_shift = 0x77,
- .core_sel = 0x8fff0001,
- .int_st = BIT(1),
- .ctl0 = 0x00000001,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 18, 0 }, { 18, 8 }, { 17, 0 }, { 18, 16 }, { 18, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CPU_BIG,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .cpu_id = 4,
+ .buck_name = "proc",
+ .opp_count = MAX_OPP_ENTRIES,
+ .vboot = 0x30,
+ .volt_step = 6250,
+ .volt_base = 500000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x77,
+ .int_st = BIT(1),
+ .ctl0 = 0x00000001,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 18, 0 }, { 18, 8 }, { 17, 0 }, { 18, 16 }, { 18, 24 }
+ }
+ },
+ .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
+ .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+ .freq_base = 1989000000,
+ .core_sel = 0x8fff0001,
+ .dvt_fixed = 0x7,
+ .vmax = 0x58,
+ .vmin = 0x10,
+
},
{
- .sw_id = SVSB_SWID_CCI,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .buck_name = "proc",
- .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
- .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 1196000000,
- .vboot = 0x30,
- .volt_step = 6250,
- .volt_base = 500000,
- .vmax = 0x64,
- .vmin = 0x18,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x7,
- .vco = 0x10,
- .chk_shift = 0x77,
- .core_sel = 0x8fff0002,
- .int_st = BIT(2),
- .ctl0 = 0x00100003,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 4, 0 }, { 4, 8 }, { 5, 16 }, { 4, 16 }, { 4, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_CCI,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .buck_name = "proc",
+ .opp_count = MAX_OPP_ENTRIES,
+ .vboot = 0x30,
+ .volt_step = 6250,
+ .volt_base = 500000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x77,
+ .int_st = BIT(2),
+ .ctl0 = 0x00100003,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 4, 0 }, { 4, 8 }, { 5, 16 }, { 4, 16 }, { 4, 24 }
+ }
+ },
+ .volt_flags = SVSB_INIT01_VOLT_INC_ONLY,
+ .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+ .freq_base = 1196000000,
+ .core_sel = 0x8fff0002,
+ .dvt_fixed = 0x7,
+ .vmax = 0x64,
+ .vmin = 0x18,
},
{
- .sw_id = SVSB_SWID_GPU,
- .set_freq_pct = svs_set_bank_freq_pct_v2,
- .get_volts = svs_get_bank_volts_v2,
- .buck_name = "mali",
- .tzone_name = "tzts2",
- .volt_flags = SVSB_INIT01_PD_REQ |
- SVSB_INIT01_VOLT_INC_ONLY,
- .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02 |
- SVSB_MODE_MON,
- .opp_count = MAX_OPP_ENTRIES,
- .freq_base = 900000000,
- .vboot = 0x30,
- .volt_step = 6250,
- .volt_base = 500000,
- .vmax = 0x40,
- .vmin = 0x14,
- .age_config = 0x555555,
- .dc_config = 0x555555,
- .dvt_fixed = 0x3,
- .vco = 0x10,
- .chk_shift = 0x77,
- .core_sel = 0x8fff0003,
- .int_st = BIT(3),
- .ctl0 = 0x00050001,
- .tzone_htemp = 85000,
- .tzone_htemp_voffset = 0,
- .tzone_ltemp = 25000,
- .tzone_ltemp_voffset = 3,
- .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
- { 6, 0 }, { 6, 8 }, { 5, 0 }, { 6, 16 }, { 6, 24 }
- }
+ .pdata = (const struct svs_bank_pdata) {
+ .sw_id = SVSB_SWID_GPU,
+ .set_freq_pct = svs_set_bank_freq_pct_v2,
+ .get_volts = svs_get_bank_volts_v2,
+ .buck_name = "mali",
+ .tzone_name = "gpu",
+ .opp_count = MAX_OPP_ENTRIES,
+ .vboot = 0x30,
+ .volt_step = 6250,
+ .volt_base = 500000,
+ .age_config = 0x555555,
+ .dc_config = 0x555555,
+ .vco = 0x10,
+ .chk_shift = 0x77,
+ .int_st = BIT(3),
+ .ctl0 = 0x00050001,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 3,
+ .dev_fuse_map = (const struct svs_fusemap[BDEV_MAX]) {
+ { 6, 0 }, { 6, 8 }, { 5, 0 }, { 6, 16 }, { 6, 24 }
+ }
+ },
+ .volt_flags = SVSB_INIT01_PD_REQ | SVSB_INIT01_VOLT_INC_ONLY,
+ .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02 | SVSB_MODE_MON,
+ .freq_base = 900000000,
+ .core_sel = 0x8fff0003,
+ .dvt_fixed = 0x3,
+ .vmax = 0x40,
+ .vmin = 0x14,
},
};
@@ -2874,5 +2931,6 @@ static struct platform_driver svs_driver = {
module_platform_driver(svs_driver);
MODULE_AUTHOR("Roger Lu <[email protected]>");
+MODULE_AUTHOR("AngeloGioacchino Del Regno <[email protected]>");
MODULE_DESCRIPTION("MediaTek SVS driver");
MODULE_LICENSE("GPL");
--
2.42.0