2023-01-03 11:33:35

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 0/14] Enhance SVS's robustness

SVS driver got accepted upstream but still has room to be improved.
Therefore, we add these patches to fix issues and coding style.

Change since v2:
- change the goto label wording from "out_of_resume" to "svs_resume_reset_assert" patch [9/14]
- Add patch [10/14] to reset svs hardware when svs_resume fail

Matthias Brugger (4):
soc: mediatek: mtk-svs: clean up platform probing
soc: mediatek: mtk-svs: improve readability of platform_probe
soc: mediatek: mtk-svs: move svs_platform_probe into probe
soc: mediatek: mtk-svs: delete superfluous platform data entries

Ricardo Ribalda (1):
soc: mediatek: mtk-svs: enable the IRQ later

Roger Lu (8):
soc: mtk-svs: mt8183: refactor o_slope calculation
soc: mediatek: mtk-svs: use svs get efuse common function
soc: mediatek: mtk-svs: use svs clk control APIs
soc: mediatek: mtk-svs: reset svs when svs_resume() fail
soc: mediatek: mtk-svs: use common function to disable restore
voltages
soc: mediatek: mtk-svs: restore default voltages when svs_init02()
fail
soc: mediatek: mtk-svs: add thermal voltage compensation if needed
soc: mediatek: mtk-svs: keep svs alive even though debug cmd create
fail

Shang XiaoJing (1):
soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in
svs_init01()

drivers/soc/mediatek/mtk-svs.c | 351 ++++++++++++++++-----------------
1 file changed, 174 insertions(+), 177 deletions(-)



2023-01-03 11:34:32

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 09/14] soc: mediatek: mtk-svs: use svs clk control APIs

In MediaTek HW design, svs and thermal both use the same clk source.
It means that svs clk reference count from CCF includes thermal control
counts. That makes svs driver confuse whether it disabled svs's main clk
or not from CCF's perspective and lead to turn off their shared clk
unexpectedly. Therefore, we add svs clk control APIs to make sure svs's
main clk is controlled well by svs driver itself.

Here is a NG example. Rely on CCF's reference count and cause problem.

thermal probe (clk ref = 1)
-> svs probe (clk ref = 2)
-> svs suspend (clk ref = 1)
-> thermal suspend (clk ref = 0)
-> thermal resume (clk ref = 1)
-> svs resume (encounter error, clk ref = 1)
-> svs suspend (clk ref = 0)
-> thermal suspend (Fail here, thermal HW control w/o clk)

Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 60 ++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 70f87715a084..d8b759897fec 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -6,6 +6,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/completion.h>
#include <linux/cpuidle.h>
#include <linux/debugfs.h>
@@ -323,6 +324,7 @@ static const u32 svs_regs_v2[] = {
* @bank_max: total number of svs banks
* @efuse: svs efuse data received from NVMEM framework
* @tefuse: thermal efuse data received from NVMEM framework
+ * @clk_cnt: clock count shows the clk enable/disable times by svs driver
*/
struct svs_platform {
void __iomem *base;
@@ -337,6 +339,7 @@ struct svs_platform {
u32 bank_max;
u32 *efuse;
u32 *tefuse;
+ s32 clk_cnt;
};

struct svs_platform_data {
@@ -496,6 +499,32 @@ static void svs_switch_bank(struct svs_platform *svsp)
svs_writel_relaxed(svsp, svsb->core_sel, CORESEL);
}

+static bool svs_is_clk_enabled(struct svs_platform *svsp)
+{
+ return svsp->clk_cnt > 0 ? true : false;
+}
+
+static int svs_clk_enable(struct svs_platform *svsp)
+{
+ int ret;
+
+ ret = clk_prepare_enable(svsp->main_clk);
+ if (ret) {
+ dev_err(svsp->dev, "cannot enable main_clk: %d\n", ret);
+ return ret;
+ }
+
+ svsp->clk_cnt++;
+
+ return 0;
+}
+
+static void svs_clk_disable(struct svs_platform *svsp)
+{
+ clk_disable_unprepare(svsp->main_clk);
+ svsp->clk_cnt--;
+}
+
static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
u32 svsb_volt_base)
{
@@ -1543,6 +1572,12 @@ static int svs_suspend(struct device *dev)
int ret;
u32 idx;

+ if (!svs_is_clk_enabled(svsp)) {
+ dev_err(svsp->dev, "svs clk is disabled already (%d)\n",
+ svsp->clk_cnt);
+ return 0;
+ }
+
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];

@@ -1564,7 +1599,7 @@ static int svs_suspend(struct device *dev)
return ret;
}

- clk_disable_unprepare(svsp->main_clk);
+ svs_clk_disable(svsp);

return 0;
}
@@ -1574,28 +1609,27 @@ static int svs_resume(struct device *dev)
struct svs_platform *svsp = dev_get_drvdata(dev);
int ret;

- ret = clk_prepare_enable(svsp->main_clk);
- if (ret) {
- dev_err(svsp->dev, "cannot enable main_clk, disable svs\n");
+ ret = svs_clk_enable(svsp);
+ if (ret)
return ret;
- }

ret = reset_control_deassert(svsp->rst);
if (ret) {
dev_err(svsp->dev, "cannot deassert reset %d\n", ret);
- goto out_of_resume;
+ goto svs_resume_clk_disable;
}

ret = svs_init02(svsp);
if (ret)
- goto out_of_resume;
+ goto svs_resume_clk_disable;

svs_mon_mode(svsp);

return 0;

-out_of_resume:
- clk_disable_unprepare(svsp->main_clk);
+svs_resume_clk_disable:
+ svs_clk_disable(svsp);
+
return ret;
}

@@ -2340,11 +2374,9 @@ static int svs_probe(struct platform_device *pdev)
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);
+ ret = svs_clk_enable(svsp);
+ if (ret)
goto svs_probe_free_tefuse;
- }

svsp->base = of_iomap(svsp->dev->of_node, 0);
if (IS_ERR_OR_NULL(svsp->base)) {
@@ -2385,7 +2417,7 @@ static int svs_probe(struct platform_device *pdev)
iounmap(svsp->base);

svs_probe_clk_disable:
- clk_disable_unprepare(svsp->main_clk);
+ svs_clk_disable(svsp);

svs_probe_free_tefuse:
if (!IS_ERR_OR_NULL(svsp->tefuse))
--
2.18.0

2023-01-03 11:40:18

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 13/14] soc: mediatek: mtk-svs: add thermal voltage compensation if needed

Some extreme test environment may keep IC temperature very low or very high
during system boot stage. For stability concern, we add thermal voltage
compenstation if needed no matter svs bank phase is in init02 or mon mode.

Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 1b4798a9101c..581bb8373b0c 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -585,7 +585,7 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
}

/* Get thermal effect */
- if (svsb->phase == SVSB_PHASE_MON) {
+ if (!IS_ERR_OR_NULL(svsb->tzd)) {
ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
@@ -600,7 +600,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->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+ if (svsb->phase == SVSB_PHASE_MON && (svsb->type == SVSB_HIGH ||
+ svsb->type == SVSB_LOW)) {
opp_start = 0;
opp_stop = svsb->opp_count;
}
@@ -616,11 +617,6 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
/* do nothing */
goto unlock_mutex;
case SVSB_PHASE_INIT02:
- svsb_volt = max(svsb->volt[i], svsb->vmin);
- opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
- svsb->volt_step,
- svsb->volt_base);
- break;
case SVSB_PHASE_MON:
svsb_volt = max(svsb->volt[i] + temp_voffset, svsb->vmin);
opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
@@ -1714,7 +1710,7 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
}
}

- if (svsb->mode_support & SVSB_MODE_MON) {
+ if (!IS_ERR_OR_NULL(svsb->tzone_name)) {
svsb->tzd = thermal_zone_get_zone_by_name(svsb->tzone_name);
if (IS_ERR(svsb->tzd)) {
dev_err(svsb->dev, "cannot get \"%s\" thermal zone\n",
@@ -2158,6 +2154,7 @@ static struct svs_bank svs_mt8192_banks[] = {
.type = SVSB_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,
@@ -2175,6 +2172,10 @@ static struct svs_bank svs_mt8192_banks[] = {
.core_sel = 0x0fff0100,
.int_st = BIT(0),
.ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
},
{
.sw_id = SVSB_GPU,
--
2.18.0

2023-01-03 11:40:18

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 03/14] soc: mediatek: mtk-svs: clean up platform probing

From: Matthias Brugger <[email protected]>

We only ever call the SoC specific probe function from
svs_platform_probe. No need to carry that function in a global
datastructure around.

Signed-off-by: Matthias Brugger <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 465b60a5cedc..5abf94aafbac 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -319,7 +319,6 @@ static const u32 svs_regs_v2[] = {
* @banks: svs banks that svs platform supports
* @rst: svs platform reset control
* @efuse_parsing: svs platform efuse parsing function pointer
- * @probe: svs platform probe function pointer
* @efuse_max: total number of svs efuse
* @tefuse_max: total number of thermal efuse
* @regs: svs platform registers map
@@ -336,7 +335,6 @@ struct svs_platform {
struct svs_bank *banks;
struct reset_control *rst;
bool (*efuse_parsing)(struct svs_platform *svsp);
- int (*probe)(struct svs_platform *svsp);
size_t efuse_max;
size_t tefuse_max;
const u32 *regs;
@@ -2347,11 +2345,10 @@ static struct svs_platform *svs_platform_probe(struct platform_device *pdev)
svsp->name = svsp_data->name;
svsp->banks = svsp_data->banks;
svsp->efuse_parsing = svsp_data->efuse_parsing;
- svsp->probe = svsp_data->probe;
svsp->regs = svsp_data->regs;
svsp->bank_max = svsp_data->bank_max;

- ret = svsp->probe(svsp);
+ ret = svsp_data->probe(svsp);
if (ret)
return ERR_PTR(ret);

--
2.18.0

2023-01-03 11:40:36

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 05/14] soc: mediatek: mtk-svs: move svs_platform_probe into probe

From: Matthias Brugger <[email protected]>

Moving svs_platform_probe into driver probe function will allow us to
reduce svs_platform members. This will be done in a follow-up patch.

Signed-off-by: Matthias Brugger <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 7fea1a5bb842..bbec96696c55 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2325,17 +2325,17 @@ static const struct of_device_id svs_of_match[] = {
},
};

-static struct svs_platform *svs_platform_probe(struct platform_device *pdev)
+static int svs_probe(struct platform_device *pdev)
{
struct svs_platform *svsp;
const struct svs_platform_data *svsp_data;
- int ret;
+ int ret, svsp_irq;

svsp_data = of_device_get_match_data(&pdev->dev);

svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL);
if (!svsp)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;

svsp->dev = &pdev->dev;
svsp->name = svsp_data->name;
@@ -2346,19 +2346,7 @@ static struct svs_platform *svs_platform_probe(struct platform_device *pdev)

ret = svsp_data->probe(svsp);
if (ret)
- return ERR_PTR(ret);
-
- return svsp;
-}
-
-static int svs_probe(struct platform_device *pdev)
-{
- struct svs_platform *svsp;
- int svsp_irq, ret;
-
- svsp = svs_platform_probe(pdev);
- if (IS_ERR(svsp))
- return PTR_ERR(svsp);
+ return ret;

if (!svs_is_efuse_data_correct(svsp)) {
dev_notice(svsp->dev, "efuse data isn't correct\n");
--
2.18.0

2023-01-03 11:41:02

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 06/14] soc: mediatek: mtk-svs: delete superfluous platform data entries

From: Matthias Brugger <[email protected]>

The platform name and efuse parsing function pointer are only used while
probing the device. Use them from the svs_platform_data struct instead.

Signed-off-by: Matthias Brugger <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index bbec96696c55..308cd36a23fc 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -311,14 +311,12 @@ static const u32 svs_regs_v2[] = {

/**
* struct svs_platform - svs platform control
- * @name: svs platform name
* @base: svs platform register base
* @dev: svs platform device
* @main_clk: main clock for svs bank
* @pbank: svs bank pointer needing to be protected by spin_lock section
* @banks: svs banks that svs platform supports
* @rst: svs platform reset control
- * @efuse_parsing: svs platform efuse parsing function pointer
* @efuse_max: total number of svs efuse
* @tefuse_max: total number of thermal efuse
* @regs: svs platform registers map
@@ -327,14 +325,12 @@ static const u32 svs_regs_v2[] = {
* @tefuse: thermal efuse data received from NVMEM framework
*/
struct svs_platform {
- char *name;
void __iomem *base;
struct device *dev;
struct clk *main_clk;
struct svs_bank *pbank;
struct svs_bank *banks;
struct reset_control *rst;
- bool (*efuse_parsing)(struct svs_platform *svsp);
size_t efuse_max;
size_t tefuse_max;
const u32 *regs;
@@ -2009,7 +2005,7 @@ static bool svs_is_efuse_data_correct(struct svs_platform *svsp)
svsp->efuse_max /= sizeof(u32);
nvmem_cell_put(cell);

- return svsp->efuse_parsing(svsp);
+ return true;
}

static struct device *svs_get_subsys_device(struct svs_platform *svsp,
@@ -2338,9 +2334,7 @@ static int svs_probe(struct platform_device *pdev)
return -ENOMEM;

svsp->dev = &pdev->dev;
- svsp->name = svsp_data->name;
svsp->banks = svsp_data->banks;
- svsp->efuse_parsing = svsp_data->efuse_parsing;
svsp->regs = svsp_data->regs;
svsp->bank_max = svsp_data->bank_max;

@@ -2351,6 +2345,12 @@ static int svs_probe(struct platform_device *pdev)
if (!svs_is_efuse_data_correct(svsp)) {
dev_notice(svsp->dev, "efuse data isn't correct\n");
ret = -EPERM;
+ goto svs_probe_free_efuse;
+ }
+
+ if (!svsp_data->efuse_parsing(svsp)) {
+ dev_err(svsp->dev, "efuse data parsing failed\n");
+ ret = -EPERM;
goto svs_probe_free_resource;
}

@@ -2388,7 +2388,7 @@ static int svs_probe(struct platform_device *pdev)
}

ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
- IRQF_ONESHOT, svsp->name, svsp);
+ IRQF_ONESHOT, svsp_data->name, svsp);
if (ret) {
dev_err(svsp->dev, "register irq(%d) failed: %d\n",
svsp_irq, ret);
@@ -2416,11 +2416,13 @@ static int svs_probe(struct platform_device *pdev)
clk_disable_unprepare(svsp->main_clk);

svs_probe_free_resource:
- if (!IS_ERR_OR_NULL(svsp->efuse))
- kfree(svsp->efuse);
if (!IS_ERR_OR_NULL(svsp->tefuse))
kfree(svsp->tefuse);

+svs_probe_free_efuse:
+ if (!IS_ERR_OR_NULL(svsp->efuse))
+ kfree(svsp->efuse);
+
return ret;
}

--
2.18.0

2023-01-03 11:41:09

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 12/14] soc: mediatek: mtk-svs: restore default voltages when svs_init02() fail

If svs init02 fail, it means we cannot rely on svs bank voltages anymore.
We need to disable svs function and restore DVFS opp voltages back to the
default voltages for making sure we have enough DVFS voltages.

Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index f4382def9736..1b4798a9101c 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1495,6 +1495,7 @@ static int svs_init02(struct svs_platform *svsp)
{
struct svs_bank *svsb;
unsigned long flags, time_left;
+ int ret;
u32 idx;

for (idx = 0; idx < svsp->bank_max; idx++) {
@@ -1513,7 +1514,8 @@ static int svs_init02(struct svs_platform *svsp)
msecs_to_jiffies(5000));
if (!time_left) {
dev_err(svsb->dev, "init02 completion timeout\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto out_of_init02;
}
}

@@ -1531,12 +1533,21 @@ static int svs_init02(struct svs_platform *svsp)
if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
if (svs_sync_bank_volts_from_opp(svsb)) {
dev_err(svsb->dev, "sync volt fail\n");
- return -EPERM;
+ ret = -EPERM;
+ goto out_of_init02;
}
}
}

return 0;
+
+out_of_init02:
+ for (idx = 0; idx < svsp->bank_max; idx++) {
+ svsb = &svsp->banks[idx];
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
+ }
+
+ return ret;
}

static void svs_mon_mode(struct svs_platform *svsp)
--
2.18.0

2023-01-03 11:42:50

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 07/14] soc: mtk-svs: mt8183: refactor o_slope calculation

The o_slope value is dependent of the o_slope_sign, refactor code to get
rid of unnecessary if constructs.

Signed-off-by: Matthias Brugger <[email protected]>
Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 51 +++++++++++++++-------------------
1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 308cd36a23fc..9578baf3d9a7 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1893,26 +1893,27 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0);

ts_id = (svsp->tefuse[1] >> 9) & BIT(0);
- o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
-
- if (adc_cali_en_t == 1) {
- if (!ts_id)
- o_slope = 0;
-
- if (adc_ge_t < 265 || adc_ge_t > 758 ||
- adc_oe_t < 265 || adc_oe_t > 758 ||
- o_vtsmcu[0] < -8 || o_vtsmcu[0] > 484 ||
- o_vtsmcu[1] < -8 || o_vtsmcu[1] > 484 ||
- o_vtsmcu[2] < -8 || o_vtsmcu[2] > 484 ||
- o_vtsmcu[3] < -8 || o_vtsmcu[3] > 484 ||
- o_vtsmcu[4] < -8 || o_vtsmcu[4] > 484 ||
- o_vtsabb < -8 || o_vtsabb > 484 ||
- degc_cali < 1 || degc_cali > 63) {
- dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
- goto remove_mt8183_svsb_mon_mode;
- }
+ if (!ts_id) {
+ o_slope = 1534;
} else {
- dev_err(svsp->dev, "no thermal efuse, no mon mode\n");
+ o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
+ if (!o_slope_sign)
+ o_slope = 1534 + o_slope * 10;
+ else
+ o_slope = 1534 - o_slope * 10;
+ }
+
+ if (adc_cali_en_t == 0 ||
+ adc_ge_t < 265 || adc_ge_t > 758 ||
+ adc_oe_t < 265 || adc_oe_t > 758 ||
+ o_vtsmcu[0] < -8 || o_vtsmcu[0] > 484 ||
+ o_vtsmcu[1] < -8 || o_vtsmcu[1] > 484 ||
+ o_vtsmcu[2] < -8 || o_vtsmcu[2] > 484 ||
+ o_vtsmcu[3] < -8 || o_vtsmcu[3] > 484 ||
+ o_vtsmcu[4] < -8 || o_vtsmcu[4] > 484 ||
+ o_vtsabb < -8 || o_vtsabb > 484 ||
+ degc_cali < 1 || degc_cali > 63) {
+ dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
goto remove_mt8183_svsb_mon_mode;
}

@@ -1931,11 +1932,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / gain;

temp0 = (10000 * 100000 / gain) * 15 / 18;
-
- if (!o_slope_sign)
- mts = (temp0 * 10) / (1534 + o_slope * 10);
- else
- mts = (temp0 * 10) / (1534 - o_slope * 10);
+ mts = (temp0 * 10) / o_slope;

for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
@@ -1962,11 +1959,7 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
temp0 = (degc_cali * 10 / 2);
temp1 = ((10000 * 100000 / 4096 / gain) *
oe + tb_roomt * 10) * 15 / 18;
-
- if (!o_slope_sign)
- temp2 = temp1 * 100 / (1534 + o_slope * 10);
- else
- temp2 = temp1 * 100 / (1534 - o_slope * 10);
+ temp2 = temp1 * 100 / o_slope;

svsb->bts = (temp0 + temp2 - 250) * 4 / 10;
}
--
2.18.0

2023-01-03 11:50:16

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 04/14] soc: mediatek: mtk-svs: improve readability of platform_probe

From: Matthias Brugger <[email protected]>

If a compatible misses a match data entry, then something is wrong in
the development phase, we don't need to check for that at runtime.

Signed-off-by: Matthias Brugger <[email protected]>
Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 5abf94aafbac..7fea1a5bb842 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2332,10 +2332,6 @@ static struct svs_platform *svs_platform_probe(struct platform_device *pdev)
int ret;

svsp_data = of_device_get_match_data(&pdev->dev);
- if (!svsp_data) {
- dev_err(&pdev->dev, "no svs platform data?\n");
- return ERR_PTR(-EPERM);
- }

svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL);
if (!svsp)
--
2.18.0

2023-01-03 11:50:36

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 11/14] soc: mediatek: mtk-svs: use common function to disable restore voltages

The timing of disabling SVS bank and restore default voltage is more
than one place. Therefore, add a common function to use for removing
the superfluous codes.

Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 44 +++++++++++++++++-----------------
1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 567536e32a46..f4382def9736 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -651,6 +651,26 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
return ret;
}

+static void svs_bank_disable_and_restore_default_volts(struct svs_platform *svsp,
+ struct svs_bank *svsb)
+{
+ unsigned long flags;
+
+ if (svsb->mode_support == SVSB_MODE_ALL_DISABLE)
+ return;
+
+ /* This spinlock might wait for svs_isr() process */
+ spin_lock_irqsave(&svs_lock, flags);
+ svsp->pbank = svsb;
+ svs_switch_bank(svsp);
+ svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
+ svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
+ spin_unlock_irqrestore(&svs_lock, flags);
+
+ svsb->phase = SVSB_PHASE_ERROR;
+ svs_adjust_pm_opp_volts(svsb);
+}
+
static int svs_dump_debug_show(struct seq_file *m, void *p)
{
struct svs_platform *svsp = (struct svs_platform *)m->private;
@@ -726,7 +746,6 @@ static ssize_t svs_enable_debug_write(struct file *filp,
{
struct svs_bank *svsb = file_inode(filp)->i_private;
struct svs_platform *svsp = dev_get_drvdata(svsb->dev);
- unsigned long flags;
int enabled, ret;
char *buf = NULL;

@@ -742,16 +761,8 @@ static ssize_t svs_enable_debug_write(struct file *filp,
return ret;

if (!enabled) {
- spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
svsb->mode_support = SVSB_MODE_ALL_DISABLE;
- svs_switch_bank(svsp);
- svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
- svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
- spin_unlock_irqrestore(&svs_lock, flags);
-
- svsb->phase = SVSB_PHASE_ERROR;
- svs_adjust_pm_opp_volts(svsb);
}

kfree(buf);
@@ -1568,7 +1579,6 @@ static int svs_suspend(struct device *dev)
{
struct svs_platform *svsp = dev_get_drvdata(dev);
struct svs_bank *svsb;
- unsigned long flags;
int ret;
u32 idx;

@@ -1580,17 +1590,7 @@ static int svs_suspend(struct device *dev)

for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
-
- /* This might wait for svs_isr() process */
- spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_switch_bank(svsp);
- svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
- svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
- spin_unlock_irqrestore(&svs_lock, flags);
-
- svsb->phase = SVSB_PHASE_ERROR;
- svs_adjust_pm_opp_volts(svsb);
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
}

ret = reset_control_assert(svsp->rst);
--
2.18.0

2023-01-03 11:52:03

by Roger Lu

[permalink] [raw]
Subject: [PATCH v3 14/14] soc: mediatek: mtk-svs: keep svs alive even though debug cmd create fail

Some projects might not support DEBUG_FS but still needs svs to be
supported. Therefore, keep svs alive even though debug cmd create fail.

Signed-off-by: Roger Lu <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 581bb8373b0c..02ecbdb7aa32 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -806,7 +806,7 @@ static int svs_status_debug_show(struct seq_file *m, void *v)

debug_fops_ro(status);

-static int svs_create_debug_cmds(struct svs_platform *svsp)
+static void svs_create_debug_cmds(struct svs_platform *svsp)
{
struct svs_bank *svsb;
struct dentry *svs_dir, *svsb_dir, *file_entry;
@@ -831,7 +831,7 @@ static int svs_create_debug_cmds(struct svs_platform *svsp)
if (IS_ERR(svs_dir)) {
dev_err(svsp->dev, "cannot create %s: %ld\n",
d, PTR_ERR(svs_dir));
- return PTR_ERR(svs_dir);
+ return;
}

for (i = 0; i < ARRAY_SIZE(svs_entries); i++) {
@@ -841,7 +841,7 @@ static int svs_create_debug_cmds(struct svs_platform *svsp)
if (IS_ERR(file_entry)) {
dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
d, svs_entries[i].name, PTR_ERR(file_entry));
- return PTR_ERR(file_entry);
+ return;
}
}

@@ -855,7 +855,7 @@ static int svs_create_debug_cmds(struct svs_platform *svsp)
if (IS_ERR(svsb_dir)) {
dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
d, svsb->name, PTR_ERR(svsb_dir));
- return PTR_ERR(svsb_dir);
+ return;
}

for (i = 0; i < ARRAY_SIZE(svsb_entries); i++) {
@@ -866,12 +866,10 @@ static int svs_create_debug_cmds(struct svs_platform *svsp)
dev_err(svsp->dev, "no %s/%s/%s?: %ld\n",
d, svsb->name, svsb_entries[i].name,
PTR_ERR(file_entry));
- return PTR_ERR(file_entry);
+ return;
}
}
}
-
- return 0;
}

static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
@@ -2421,11 +2419,7 @@ static int svs_probe(struct platform_device *pdev)
goto svs_probe_iounmap;
}

- ret = svs_create_debug_cmds(svsp);
- if (ret) {
- dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret);
- goto svs_probe_iounmap;
- }
+ svs_create_debug_cmds(svsp);

return 0;

--
2.18.0