Subject: [PATCH v3 00/20] MediaTek SVS driver partial refactoring

Changes in v3:
- Fix patch [18/20] for tzone_name moved to pdata

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 | 2002 +++++++++++-----------
4 files changed, 996 insertions(+), 1061 deletions(-)

--
2.42.0


Subject: [PATCH v3 07/20] soc: mediatek: mtk-svs: Add a map to retrieve fused values

In preparation for adding a common efuse parsing function which will
greatly reduce code duplication, add a SoC-specific mapping that will
be used to retrieve the right SVS calibration values from the fuses.
The maps are two: one is a Global Map used for reading parameters that
are SVS-global, and one is a Bank Map for reading calibrations for
each SVS Bank.

While at it, also populate the map in the platform data for each SoC.

Being this a preparation commit, there are no functional changes.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 87 ++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index b5beb33c95ba..6c6f133c327f 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -340,6 +340,26 @@ static const char * const svs_type_names[SVSB_TYPE_MAX] = {
"", "_LOW", "_HIGH"
};

+enum svs_fusemap_dev {
+ BDEV_BDES,
+ BDEV_MDES,
+ BDEV_MTDES,
+ BDEV_DCBDET,
+ BDEV_DCMDET,
+ BDEV_MAX
+};
+
+enum svs_fusemap_glb {
+ GLB_FT_PGM,
+ GLB_VMIN,
+ GLB_MAX
+};
+
+struct svs_fusemap {
+ s8 index;
+ u8 ofst;
+};
+
/**
* struct svs_platform - svs platform control
* @base: svs platform register base
@@ -375,12 +395,14 @@ struct svs_platform_data {
struct svs_bank *banks;
bool (*efuse_parsing)(struct svs_platform *svsp);
int (*probe)(struct svs_platform *svsp);
+ const struct svs_fusemap *glb_fuse_map;
const u32 *regs;
u32 bank_max;
};

/**
* struct svs_bank - svs bank representation
+ * @dev_fuse_map: Bank fuse map data
* @dev: bank device
* @opp_dev: device for opp table/buck control
* @init_completion: the timeout completion for bank init
@@ -444,6 +466,7 @@ struct svs_platform_data {
* opp_volt[i] = (volt[i] * volt_step) + volt_base;
*/
struct svs_bank {
+ const struct svs_fusemap *dev_fuse_map;
struct device *dev;
struct device *opp_dev;
struct completion init_completion;
@@ -2457,6 +2480,9 @@ static struct svs_bank svs_mt8195_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_GPU,
@@ -2486,6 +2512,9 @@ static struct svs_bank svs_mt8195_banks[] = {
.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 }
+ },
},
};

@@ -2517,6 +2546,9 @@ static struct svs_bank svs_mt8192_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_GPU,
@@ -2546,6 +2578,9 @@ static struct svs_bank svs_mt8192_banks[] = {
.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 }
+ }
},
};

@@ -2572,6 +2607,9 @@ static struct svs_bank svs_mt8188_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_GPU,
@@ -2601,6 +2639,9 @@ static struct svs_bank svs_mt8188_banks[] = {
.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 }
+ }
},
};

@@ -2629,6 +2670,9 @@ static struct svs_bank svs_mt8186_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_CPU_BIG,
@@ -2660,6 +2704,9 @@ static struct svs_bank svs_mt8186_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_CPU_LITTLE,
@@ -2689,6 +2736,9 @@ static struct svs_bank svs_mt8186_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_CCI,
@@ -2717,6 +2767,9 @@ static struct svs_bank svs_mt8186_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_GPU,
@@ -2744,6 +2797,9 @@ static struct svs_bank svs_mt8186_banks[] = {
.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 }
+ }
},
};

@@ -2771,6 +2827,9 @@ static struct svs_bank svs_mt8183_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_CPU_BIG,
@@ -2795,6 +2854,9 @@ static struct svs_bank svs_mt8183_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_CCI,
@@ -2818,6 +2880,9 @@ static struct svs_bank svs_mt8183_banks[] = {
.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 }
+ }
},
{
.sw_id = SVSB_SWID_GPU,
@@ -2848,6 +2913,9 @@ static struct svs_bank svs_mt8183_banks[] = {
.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 }
+ }
},
};

@@ -2858,6 +2926,9 @@ 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),
+ .glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
+ { 0, 0 }, { 19, 4 }
+ }
};

static const struct svs_platform_data svs_mt8192_platform_data = {
@@ -2867,6 +2938,10 @@ 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),
+ .glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
+ /* FT_PGM not present */
+ { -1, 0 }, { 19, 4 }
+ }
};

static const struct svs_platform_data svs_mt8188_platform_data = {
@@ -2876,6 +2951,10 @@ 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),
+ .glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
+ /* FT_PGM and VMIN not present */
+ { -1, 0 }, { -1, 0 }
+ }
};

static const struct svs_platform_data svs_mt8186_platform_data = {
@@ -2885,6 +2964,10 @@ 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),
+ .glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
+ /* FT_PGM and VMIN not present */
+ { -1, 0 }, { -1, 0 }
+ }
};

static const struct svs_platform_data svs_mt8183_platform_data = {
@@ -2894,6 +2977,10 @@ static const struct svs_platform_data svs_mt8183_platform_data = {
.probe = svs_mt8183_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8183_banks),
+ .glb_fuse_map = (const struct svs_fusemap[GLB_MAX]) {
+ /* VMIN not present */
+ { 0, 4 }, { -1, 0 }
+ }
};

static const struct of_device_id svs_of_match[] = {
--
2.42.0

Subject: [PATCH v3 04/20] soc: mediatek: mtk-svs: Build bank name string dynamically

In svs_bank_resource_setup() there is a "big" switch assigning different
names depending on sw_id and type and this will surely grow: for example
MT8186 has got a two-line type (high/low) SVS bank for CPU_BIG, and this
would require more switch nesting.

Simplify all of this by changing that to a devm_kasprintf() call that
will concatenate the SW_ID string (e.g. SVSB_CPU_LITTLE) with the Type
string (e.g. _LOW), resulting in the expected full bank name (e.g.
SVSB_CPU_LITTLE_LOW).

This being a dynamic allocation can be slower, but this happens only
once in the life of this driver and it's not a performance path, so it's
totally acceptable.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 39 +++++++++++++++-------------------
1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index ddbb9ba3e47d..1c7592fd6ae7 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -332,6 +332,14 @@ static const u32 svs_regs_v2[] = {
[THSLPEVEB] = 0x330,
};

+static const char * const svs_swid_names[SVSB_SWID_MAX] = {
+ "SVSB_CPU_LITTLE", "SVSB_CPU_BIG", "SVSB_CCI", "SVSB_GPU"
+};
+
+static const char * const svs_type_names[SVSB_TYPE_MAX] = {
+ "", "_LOW", "_HIGH"
+};
+
/**
* struct svs_platform - svs platform control
* @base: svs platform register base
@@ -1696,34 +1704,21 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];

- switch (svsb->sw_id) {
- case SVSB_SWID_CPU_LITTLE:
- svsb->name = "SVSB_CPU_LITTLE";
- break;
- case SVSB_SWID_CPU_BIG:
- svsb->name = "SVSB_CPU_BIG";
- break;
- case SVSB_SWID_CCI:
- svsb->name = "SVSB_CCI";
- break;
- case SVSB_SWID_GPU:
- if (svsb->type == SVSB_TYPE_HIGH)
- svsb->name = "SVSB_GPU_HIGH";
- else if (svsb->type == SVSB_TYPE_LOW)
- svsb->name = "SVSB_GPU_LOW";
- else
- svsb->name = "SVSB_GPU";
- break;
- default:
- dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+ if (svsb->sw_id >= SVSB_SWID_MAX || svsb->type >= SVSB_TYPE_MAX) {
+ dev_err(svsb->dev, "unknown bank sw_id or type\n");
return -EINVAL;
}

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

+ svsb->name = devm_kasprintf(svsp->dev, GFP_KERNEL, "%s%s",
+ svs_swid_names[svsb->sw_id],
+ svs_type_names[svsb->type]);
+ if (!svsb->name)
+ return -ENOMEM;
+
ret = dev_set_name(svsb->dev, "%s", svsb->name);
if (ret)
return ret;
--
2.42.0

Subject: [PATCH v3 01/20] arm64: dts: mediatek: mt8183: Change iospaces for thermal and svs

The SVS iospace starts at 0x1100bc00 and not at 0x1100b000 as the
latter is the thermal sensor iospace instead.

Change the iospaces for both as following:
- Thermal: 0x1100b000, length 0xc00
- SVS: 0x1100bc00, length 0x400

Please note that while this would be a breaking change for SVS (but
not for thermal sensors), it doesn't matter because the svs driver
never worked anyway because of the missing trips in tzts2, causing
that thermal zone to never actually register, hence the SVS driver
to fail probing anyway.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 26 ++++++++++++------------
1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 5169779d01df..13c3104bc67b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1183,22 +1183,10 @@ spi0: spi@1100a000 {
status = "disabled";
};

- svs: svs@1100b000 {
- compatible = "mediatek,mt8183-svs";
- reg = <0 0x1100b000 0 0x1000>;
- interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&infracfg CLK_INFRA_THERM>;
- clock-names = "main";
- nvmem-cells = <&svs_calibration>,
- <&thermal_calibration>;
- nvmem-cell-names = "svs-calibration-data",
- "t-calibration-data";
- };
-
thermal: thermal@1100b000 {
#thermal-sensor-cells = <1>;
compatible = "mediatek,mt8183-thermal";
- reg = <0 0x1100b000 0 0x1000>;
+ reg = <0 0x1100b000 0 0xc00>;
clocks = <&infracfg CLK_INFRA_THERM>,
<&infracfg CLK_INFRA_AUXADC>;
clock-names = "therm", "auxadc";
@@ -1210,6 +1198,18 @@ thermal: thermal@1100b000 {
nvmem-cell-names = "calibration-data";
};

+ svs: svs@1100bc00 {
+ compatible = "mediatek,mt8183-svs";
+ reg = <0 0x1100bc00 0 0x400>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_THERM>;
+ clock-names = "main";
+ nvmem-cells = <&svs_calibration>,
+ <&thermal_calibration>;
+ nvmem-cell-names = "svs-calibration-data",
+ "t-calibration-data";
+ };
+
thermal_zones: thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <100>;
--
2.42.0

Subject: [PATCH v3 03/20] soc: mediatek: mtk-svs: Convert sw_id and type to enumerations

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

Subject: [PATCH v3 02/20] soc: mediatek: mtk-svs: Subtract offset from regs_v2 to avoid conflict

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

Subject: [PATCH v3 06/20] soc: mediatek: mtk-svs: Change the thermal sensor device name

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

Subject: [PATCH v3 14/20] soc: mediatek: mtk-svs: Compress of_device_id entries

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

Subject: [PATCH v3 20/20] arm64: dts: mediatek: mt8195: Add SVS node and reduce LVTS_AP iospace

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

Subject: [PATCH v3 05/20] soc: mediatek: mtk-svs: Reduce memory footprint of struct svs_bank

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

Subject: [PATCH v3 08/20] soc: mediatek: mtk-svs: Add SVS-Thermal coefficient to SoC platform data

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

Subject: [PATCH v3 09/20] soc: mediatek: mtk-svs: Move t-calibration-data retrieval to svs_probe()

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

Subject: [PATCH v3 12/20] soc: mediatek: mtk-svs: Commonize MT8192 probe function for MT8186

Include the additions of svs_mt8186_platform_probe() in the common
svs_mt8192_platform_probe() function, remove the former, and use the
latter as .probe() callback for MT8186.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 44 ++++++----------------------------
1 file changed, 7 insertions(+), 37 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index e7df3a577b4c..cd5064683506 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -2119,7 +2119,6 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
static int svs_mt8192_platform_probe(struct svs_platform *svsp)
{
struct device *dev;
- struct svs_bank *svsb;
u32 idx;

svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
@@ -2133,40 +2132,7 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
"failed to get lvts device\n");

for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
-
- if (svsb->type == SVSB_TYPE_HIGH)
- svsb->opp_dev = svs_add_device_link(svsp, "gpu");
- else if (svsb->type == SVSB_TYPE_LOW)
- svsb->opp_dev = svs_get_subsys_device(svsp, "gpu");
-
- if (IS_ERR(svsb->opp_dev))
- return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev),
- "failed to get OPP device for bank %d\n",
- idx);
- }
-
- return 0;
-}
-
-static int svs_mt8186_platform_probe(struct svs_platform *svsp)
-{
- struct device *dev;
- struct svs_bank *svsb;
- u32 idx;
-
- svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
- if (IS_ERR(svsp->rst))
- return dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
- "cannot get svs reset control\n");
-
- 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");
-
- for (idx = 0; idx < svsp->bank_max; idx++) {
- svsb = &svsp->banks[idx];
+ struct svs_bank *svsb = &svsp->banks[idx];

switch (svsb->sw_id) {
case SVSB_SWID_CPU_LITTLE:
@@ -2177,7 +2143,11 @@ static int svs_mt8186_platform_probe(struct svs_platform *svsp)
svsb->opp_dev = svs_add_device_link(svsp, "cci");
break;
case SVSB_SWID_GPU:
- svsb->opp_dev = svs_add_device_link(svsp, "gpu");
+ if (svsb->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);
@@ -2739,7 +2709,7 @@ static const struct svs_platform_data svs_mt8186_platform_data = {
.name = "mt8186-svs",
.banks = svs_mt8186_banks,
.efuse_parsing = svs_common_parse_efuse,
- .probe = svs_mt8186_platform_probe,
+ .probe = svs_mt8192_platform_probe,
.regs = svs_regs_v2,
.bank_max = ARRAY_SIZE(svs_mt8186_banks),
.ts_coeff = SVSB_TS_COEFF_MT8186,
--
2.42.0

Subject: [PATCH v3 10/20] soc: mediatek: mtk-svs: Commonize efuse parse function for most SoCs

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

Subject: [PATCH v3 11/20] soc: mediatek: mtk-svs: Drop supplementary svs per-bank pointer

Drop the "pbank" pointer from struct svs_bank: this was used to simply
pass a pointer to the SVS bank that the flow was working on.
That for instance needs more locking, and it's avoidable by adding one
more parameter to functions working on specific banks, either a bank
index number, or passing the svs_bank pointer directly from the caller.

Even if the locking can now be reduced, for now, it was still left in
place for the sake of making sure to not introduce any stability and/or
reliability regression.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/soc/mediatek/mtk-svs.c | 87 ++++++++++++++++------------------
1 file changed, 40 insertions(+), 47 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 517a27c58888..e7df3a577b4c 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -372,7 +372,6 @@ struct svs_fusemap {
* @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_max: total number of svs efuse
@@ -387,7 +386,6 @@ struct svs_platform {
void __iomem *base;
struct device *dev;
struct clk *main_clk;
- struct svs_bank *pbank;
struct svs_bank *banks;
struct reset_control *rst;
size_t efuse_max;
@@ -483,8 +481,8 @@ struct svs_bank {
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);
- void (*get_volts)(struct svs_platform *svsp);
+ void (*set_freq_pct)(struct svs_platform *svsp, struct svs_bank *svsb);
+ void (*get_volts)(struct svs_platform *svsp, struct svs_bank *svsb);
char *name;
char *buck_name;
char *tzone_name;
@@ -555,10 +553,8 @@ static void svs_writel_relaxed(struct svs_platform *svsp, u32 val,
writel_relaxed(val, svsp->base + svsp->regs[rg_i]);
}

-static void svs_switch_bank(struct svs_platform *svsp)
+static void svs_switch_bank(struct svs_platform *svsp, struct svs_bank *svsb)
{
- struct svs_bank *svsb = svsp->pbank;
-
svs_writel_relaxed(svsp, svsb->core_sel, CORESEL);
}

@@ -693,8 +689,7 @@ static void svs_bank_disable_and_restore_default_volts(struct svs_platform *svsp
return;

spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_switch_bank(svsp);
+ svs_switch_bank(svsp, svsb);
svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
spin_unlock_irqrestore(&svs_lock, flags);
@@ -926,9 +921,8 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
return DIV_ROUND_UP(vx, 100);
}

-static void svs_get_bank_volts_v3(struct svs_platform *svsp)
+static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{
- struct svs_bank *svsb = svsp->pbank;
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);
@@ -1041,9 +1035,8 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp)
}
}

-static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
+static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{
- struct svs_bank *svsb = svsp->pbank;
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);
@@ -1124,9 +1117,8 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
svs_writel_relaxed(svsp, freq_pct30, FREQPCT30);
}

-static void svs_get_bank_volts_v2(struct svs_platform *svsp)
+static void svs_get_bank_volts_v2(struct svs_platform *svsp, struct svs_bank *svsb)
{
- struct svs_bank *svsb = svsp->pbank;
u32 temp, i;

temp = svs_readl_relaxed(svsp, VOP74);
@@ -1181,9 +1173,8 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp)
}
}

-static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp)
+static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp, struct svs_bank *svsb)
{
- struct svs_bank *svsb = svsp->pbank;
u32 freqpct74_val, freqpct30_val;

freqpct74_val = FIELD_PREP(SVSB_FREQPCTS_FLD_PCT0_4, svsb->freq_pct[8]) |
@@ -1201,12 +1192,13 @@ static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp)
}

static void svs_set_bank_phase(struct svs_platform *svsp,
+ unsigned int bank_idx,
enum svsb_phase target_phase)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];
u32 des_char, temp_char, det_char, limit_vals, init2vals, ts_calcs;

- svs_switch_bank(svsp);
+ svs_switch_bank(svsp, svsb);

des_char = FIELD_PREP(SVSB_DESCHAR_FLD_BDES, svsb->bdes) |
FIELD_PREP(SVSB_DESCHAR_FLD_MDES, svsb->mdes);
@@ -1225,7 +1217,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG);
svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);

- svsb->set_freq_pct(svsp);
+ svsb->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) |
@@ -1267,18 +1259,20 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
}

static inline void svs_save_bank_register_data(struct svs_platform *svsp,
+ unsigned short bank_idx,
enum svsb_phase phase)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];
enum svs_reg_index rg_i;

for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++)
svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i);
}

-static inline void svs_error_isr_handler(struct svs_platform *svsp)
+static inline void svs_error_isr_handler(struct svs_platform *svsp,
+ unsigned short bank_idx)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];

dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n",
__func__, svs_readl_relaxed(svsp, CORESEL));
@@ -1290,16 +1284,17 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
svs_readl_relaxed(svsp, SMSTATE1));
dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));

- svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR);
+ svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_ERROR);

svsb->phase = SVSB_PHASE_ERROR;
svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
}

-static inline void svs_init01_isr_handler(struct svs_platform *svsp)
+static inline void svs_init01_isr_handler(struct svs_platform *svsp,
+ unsigned short bank_idx)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];
u32 val;

dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n",
@@ -1307,7 +1302,7 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
svs_readl_relaxed(svsp, VDESIGN30),
svs_readl_relaxed(svsp, DCVALUES));

- svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01);
+ svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_INIT01);

svsb->phase = SVSB_PHASE_INIT01;
val = ~(svs_readl_relaxed(svsp, DCVALUES) & GENMASK(15, 0)) + 1;
@@ -1325,32 +1320,34 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
svsb->core_sel &= ~SVSB_DET_CLK_EN;
}

-static inline void svs_init02_isr_handler(struct svs_platform *svsp)
+static inline void svs_init02_isr_handler(struct svs_platform *svsp,
+ unsigned short bank_idx)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];

dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n",
__func__, svs_readl_relaxed(svsp, VOP74),
svs_readl_relaxed(svsp, VOP30),
svs_readl_relaxed(svsp, DCVALUES));

- svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02);
+ svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_INIT02);

svsb->phase = SVSB_PHASE_INIT02;
- svsb->get_volts(svsp);
+ svsb->get_volts(svsp, svsb);

svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
svs_writel_relaxed(svsp, SVSB_INTSTS_F0_COMPLETE, INTSTS);
}

-static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
+static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp,
+ unsigned short bank_idx)
{
- struct svs_bank *svsb = svsp->pbank;
+ struct svs_bank *svsb = &svsp->banks[bank_idx];

- svs_save_bank_register_data(svsp, SVSB_PHASE_MON);
+ svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_MON);

svsb->phase = SVSB_PHASE_MON;
- svsb->get_volts(svsp);
+ svsb->get_volts(svsp, svsb);

svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
svs_writel_relaxed(svsp, SVSB_INTSTS_FLD_MONVOP, INTSTS);
@@ -1368,7 +1365,6 @@ static irqreturn_t svs_isr(int irq, void *data)
WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name);

spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;

/* Find out which svs bank fires interrupt */
if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) {
@@ -1376,20 +1372,20 @@ static irqreturn_t svs_isr(int irq, void *data)
continue;
}

- svs_switch_bank(svsp);
+ svs_switch_bank(svsp, svsb);
int_sts = svs_readl_relaxed(svsp, INTSTS);
svs_en = svs_readl_relaxed(svsp, SVSEN);

if (int_sts == SVSB_INTSTS_F0_COMPLETE &&
svs_en == SVSB_PTPEN_INIT01)
- svs_init01_isr_handler(svsp);
+ svs_init01_isr_handler(svsp, idx);
else if (int_sts == SVSB_INTSTS_F0_COMPLETE &&
svs_en == SVSB_PTPEN_INIT02)
- svs_init02_isr_handler(svsp);
+ svs_init02_isr_handler(svsp, idx);
else if (int_sts & SVSB_INTSTS_FLD_MONVOP)
- svs_mon_mode_isr_handler(svsp);
+ svs_mon_mode_isr_handler(svsp, idx);
else
- svs_error_isr_handler(svsp);
+ svs_error_isr_handler(svsp, idx);

spin_unlock_irqrestore(&svs_lock, flags);
break;
@@ -1518,8 +1514,7 @@ static int svs_init01(struct svs_platform *svsp)
}

spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_set_bank_phase(svsp, SVSB_PHASE_INIT01);
+ svs_set_bank_phase(svsp, idx, SVSB_PHASE_INIT01);
spin_unlock_irqrestore(&svs_lock, flags);

time_left = wait_for_completion_timeout(&svsb->init_completion,
@@ -1588,8 +1583,7 @@ static int svs_init02(struct svs_platform *svsp)

reinit_completion(&svsb->init_completion);
spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_set_bank_phase(svsp, SVSB_PHASE_INIT02);
+ svs_set_bank_phase(svsp, idx, SVSB_PHASE_INIT02);
spin_unlock_irqrestore(&svs_lock, flags);

time_left = wait_for_completion_timeout(&svsb->init_completion,
@@ -1645,8 +1639,7 @@ static void svs_mon_mode(struct svs_platform *svsp)
continue;

spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_set_bank_phase(svsp, SVSB_PHASE_MON);
+ svs_set_bank_phase(svsp, idx, SVSB_PHASE_MON);
spin_unlock_irqrestore(&svs_lock, flags);
}
}
--
2.42.0

Subject: [PATCH v3 13/20] soc: mediatek: mtk-svs: Remove redundant print in svs_get_efuse_data

Callers of svs_get_efuse_data() are already printing an error in case
anything goes wrong, and the error print for nvmem_cell_read() failure
is redundant: remove it.

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

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index cd5064683506..5fd9884dd20f 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1822,8 +1822,6 @@ static int svs_get_efuse_data(struct svs_platform *svsp,

*svsp_efuse = nvmem_cell_read(cell, svsp_efuse_max);
if (IS_ERR(*svsp_efuse)) {
- dev_err(svsp->dev, "cannot read \"%s\" efuse: %ld\n",
- nvmem_cell_name, PTR_ERR(*svsp_efuse));
nvmem_cell_put(cell);
return PTR_ERR(*svsp_efuse);
}
--
2.42.0

Subject: [PATCH v3 16/20] soc: mediatek: mtk-svs: Check if SVS mode is available in the beginning

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

Subject: [PATCH v3 17/20] soc: mediatek: mtk-svs: Use ULONG_MAX to compare floor frequency

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

Subject: [PATCH v3 15/20] soc: mediatek: mtk-svs: Cleanup of svs_probe() function

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

Subject: [PATCH v3 19/20] arm64: dts: mediatek: mt8192: Add Smart Voltage Scaling node

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

Subject: [PATCH v3 18/20] soc: mediatek: mtk-svs: Constify runtime-immutable members of svs_bank

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 | 1204 +++++++++++++++++---------------
1 file changed, 631 insertions(+), 573 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index df39e7430ba9..c832f5c670bc 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,32 +1810,32 @@ 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);
}
}

- if (!IS_ERR_OR_NULL(svsb->tzone_name)) {
- svsb->tzd = thermal_zone_get_zone_by_name(svsb->tzone_name);
+ if (!IS_ERR_OR_NULL(bdata->tzone_name)) {
+ svsb->tzd = thermal_zone_get_zone_by_name(bdata->tzone_name);
if (IS_ERR(svsb->tzd)) {
dev_err(svsb->dev, "cannot get \"%s\" thermal zone\n",
- svsb->tzone_name);
+ bdata->tzone_name);
return PTR_ERR(svsb->tzd);
}
}

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

2023-11-22 11:24:18

by Eugen Hristev

[permalink] [raw]
Subject: Re: [PATCH v3 09/20] soc: mediatek: mtk-svs: Move t-calibration-data retrieval to svs_probe()

On 11/21/23 14:50, AngeloGioacchino Del Regno wrote:
> 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;
> -

Hello Angelo,

if you removed the code using `ret` in this patch, it makes sense to
also remove the variable here instead of doing it in patch 18.
It will avoid unused variable warnings for this patch.


> 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");

With the previous code, if svs-calibration-data could not be read, the
code would go to svs_probe_free_efuse. In your case, it returns directly.
I believe that svs_get_efuse_data using nvmem_cell_read does not
allocate the buffer for the efuse , hence no more need to free it ? The
exit code is checking if it's ERR or NULL, but still, if the buffer was
not allocated, it doesn't make sense to jump there indeed.
In that case, you are also changing the behavior here , and your commit
appears to do more than a simple move.

> +
> + 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;

again in this case the tefuse has not been allocated I assume.

So previous code was a bit excessive in trying to free the efuse/tefuse ?

Eugen

> }
>

Subject: Re: [PATCH v3 09/20] soc: mediatek: mtk-svs: Move t-calibration-data retrieval to svs_probe()

Il 22/11/23 12:23, Eugen Hristev ha scritto:
> On 11/21/23 14:50, AngeloGioacchino Del Regno wrote:
>> 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;
>> -
>
> Hello Angelo,
>
> if you removed the code using `ret` in this patch, it makes sense to also remove
> the variable here instead of doing it in patch 18.
> It will avoid unused variable warnings for this patch.
>
>

Yes, though the comment is not for this function, but rather for 8183. Anyway, that
makes sense, but if it's the only change of this v3, it's something that I can fix
while applying instead of sending another 20 patches round. Thanks.

>>       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");
>
> With the previous code, if svs-calibration-data could not be read, the code would
> go to svs_probe_free_efuse. In your case, it returns directly.
> I believe that svs_get_efuse_data using nvmem_cell_read does not allocate the
> buffer for the efuse , hence no more need to free it ? The exit code is checking if
> it's ERR or NULL, but still, if the buffer was not allocated, it doesn't make sense
> to jump there indeed.
> In that case, you are also changing the behavior here , and your commit appears to
> do more than a simple move.
>

I'm not changing the behavior: the previous behavior was to fail and free the efuse
variable if previously allocated, the current behavior is to fail and free the
efuse variable if previously allocated, and the tefuse variable if previously
allocated, which is a result of the actual move of the retrieval of the thermal
fuse calibration data.

I really don't see anything implicit here.

>> +
>> +    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;
>
> again in this case the tefuse has not been allocated I assume.
>
> So previous code was a bit excessive in trying to free the efuse/tefuse ?

The previous code was performing an useless error check on something that was not
supposed to be allocated *yet*. Yes, it was wrong before.

Cheers,
Angelo

2023-11-22 12:53:59

by Eugen Hristev

[permalink] [raw]
Subject: Re: [PATCH v3 09/20] soc: mediatek: mtk-svs: Move t-calibration-data retrieval to svs_probe()

On 11/22/23 14:41, AngeloGioacchino Del Regno wrote:
> Il 22/11/23 12:23, Eugen Hristev ha scritto:
>> On 11/21/23 14:50, AngeloGioacchino Del Regno wrote:
>>> 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;
>>> -
>>
>> Hello Angelo,
>>
>> if you removed the code using `ret` in this patch, it makes sense to
>> also remove the variable here instead of doing it in patch 18.
>> It will avoid unused variable warnings for this patch.
>>
>>
>
> Yes, though the comment is not for this function, but rather for 8183.
> Anyway, that
> makes sense, but if it's the only change of this v3, it's something that
> I can fix
> while applying instead of sending another 20 patches round. Thanks.
>
>>>       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");
>>
>> With the previous code, if svs-calibration-data could not be read, the
>> code would go to svs_probe_free_efuse. In your case, it returns directly.
>> I believe that svs_get_efuse_data using nvmem_cell_read does not
>> allocate the buffer for the efuse , hence no more need to free it ?
>> The exit code is checking if it's ERR or NULL, but still, if the
>> buffer was not allocated, it doesn't make sense to jump there indeed.
>> In that case, you are also changing the behavior here , and your
>> commit appears to do more than a simple move.
>>
>
> I'm not changing the behavior: the previous behavior was to fail and
> free the efuse
> variable if previously allocated, the current behavior is to fail and
> free the
> efuse variable if previously allocated, and the tefuse variable if
> previously
> allocated, which is a result of the actual move of the retrieval of the
> thermal
> fuse calibration data.
>
> I really don't see anything implicit here.
>

Previous behavior was


ret = svs_get_efuse_data (efuse)

if (ret) goto svs_probe_free_efuse


Now, you have it as

ret = svs_get_efuse_data (efuse)

if (ret) return dev_err_probe...


>>> +
>>> +    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;
>>
>> again in this case the tefuse has not been allocated I assume.
>>
>> So previous code was a bit excessive in trying to free the efuse/tefuse ?
>
> The previous code was performing an useless error check on something
> that was not
> supposed to be allocated *yet*. Yes, it was wrong before.
>
> Cheers,
> Angelo
> _______________________________________________
> Kernel mailing list -- [email protected]
> To unsubscribe send an email to [email protected]