summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2023-04-14 22:39:49 +0200
committerArnd Bergmann <arnd@arndb.de>2023-04-14 22:39:59 +0200
commit4f2f29913684f729b70bbfa0c6c23c7025f1db89 (patch)
tree4bfb948135c21ded955217a0a04ce17f32d1cd6b /drivers/soc
parent04523aceae8c89d3c91ff33bdde6892f63a60f35 (diff)
parent5ce5e0d08e340ab13169a5f33ed5f98000891a61 (diff)
Merge tag 'v6.3-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into soc/drivers
mtk-svs: smaller coding style changes mtk-mutex: - add support for mt8365 display and mt8195 VPP mutex - add support for more then 32 mods - use module_platform_driver instead of open coding mtk-mmsys: - add support for mt8195 RSZ switching - add remove function - use module_platform_driver instead of open coding - split out mt8173 routing table from the legacy table - bump up resets in mt8173 to 64 - add support for mt6795 (Helio X10) - clean-up IS_REACHABLE code for cmdq * tag 'v6.3-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux: (25 commits) soc: mediatek: Kconfig: Add MTK_CMDQ dependency to MTK_MMSYS soc: mediatek: mutex: Use dev_err_probe() soc: mediatek: mtk-mmsys: Add support for MT6795 Helio X10 soc: mediatek: mtk-mmsys: Change MT8173 num_resets to 64 soc: mediatek: mtk-mmsys: Split out MT8173 mmsys DDP routing table soc: mediatek: Cleanup ifdefs for IS_REACHABLE(CONFIG_MTK_CMDQ) soc: mediatek: cmdq: Add inline functions for !CONFIG_MTK_CMDQ soc: mediatek: mtk-mutex: Use module_platform_driver() macro soc: mediatek: mtk-mutex: Replace max handles number with definition soc: mediatek: mtk-mutex: Compress of_device_id array entries soc: mediatek: mtk-mmsys: Add MODULE_DEVICE_TABLE() to allow auto-load soc: mediatek: mtk-mmsys: Compress of_device_id array entries soc: mediatek: mtk-mmsys: Use module_platform_driver() macro soc: mediatek: mtk-mmsys: Add .remove() callback dt-bindings: soc: mediatek: add display mutex for MT8365 SoC dt-bindings: soc: mediatek: specify which compatible requires clocks property soc: mediatek: mtk-svs: add thermal voltage compensation if needed soc: mediatek: mtk-svs: fix passing zero to 'PTR_ERR' soc: mediatek: mtk-svs: delete node name check soc: mediatek: mutex: support MT8195 VPPSYS ... Link: https://lore.kernel.org/r/bc9f7a74-ce12-b323-021c-ff2c0473e979@gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/mediatek/Kconfig1
-rw-r--r--drivers/soc/mediatek/mt8173-mmsys.h95
-rw-r--r--drivers/soc/mediatek/mt8195-mmsys.h13
-rw-r--r--drivers/soc/mediatek/mtk-mmsys.c195
-rw-r--r--drivers/soc/mediatek/mtk-mmsys.h2
-rw-r--r--drivers/soc/mediatek/mtk-mutex.c218
-rw-r--r--drivers/soc/mediatek/mtk-svs.c149
7 files changed, 420 insertions, 253 deletions
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index d6b83a5508ca..a88cf04fc803 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -76,6 +76,7 @@ config MTK_MMSYS
tristate "MediaTek MMSYS Support"
default ARCH_MEDIATEK
depends on HAS_IOMEM
+ depends on MTK_CMDQ || MTK_CMDQ=n
help
Say yes here to add support for the MediaTek Multimedia
Subsystem (MMSYS).
diff --git a/drivers/soc/mediatek/mt8173-mmsys.h b/drivers/soc/mediatek/mt8173-mmsys.h
new file mode 100644
index 000000000000..9d24e381271e
--- /dev/null
+++ b/drivers/soc/mediatek/mt8173-mmsys.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8173_MMSYS_H
+#define __SOC_MEDIATEK_MT8173_MMSYS_H
+
+#define MT8173_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x040
+#define MT8173_DISP_REG_CONFIG_DISP_OVL1_MOUT_EN 0x044
+#define MT8173_DISP_REG_CONFIG_DISP_OD_MOUT_EN 0x048
+#define MT8173_DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN 0x04c
+#define MT8173_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN 0x050
+#define MT8173_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN 0x084
+#define MT8173_DISP_REG_CONFIG_DISP_COLOR1_SEL_IN 0x088
+#define MT8173_DISP_REG_CONFIG_DISP_AAL_SEL_IN 0x08c
+#define MT8173_DISP_REG_CONFIG_DISP_UFOE_SEL_IN 0x0a0
+#define MT8173_DISP_REG_CONFIG_DSI0_SEL_IN 0x0a4
+#define MT8173_DISP_REG_CONFIG_DPI_SEL_IN 0x0ac
+#define MT8173_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN 0x0b0
+#define MT8173_DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN 0x0c8
+#define MT8173_DISP_REG_CONFIG_DISP_COLOR0_SOUT_SEL_IN 0x0bc
+
+#define MT8173_AAL_SEL_IN_MERGE BIT(0)
+#define MT8173_COLOR0_SEL_IN_OVL0 BIT(0)
+#define MT8173_COLOR0_SOUT_MERGE BIT(0)
+#define MT8173_DPI0_SEL_IN_MASK GENMASK(1, 0)
+#define MT8173_DPI0_SEL_IN_RDMA1 BIT(0)
+#define MT8173_DSI0_SEL_IN_UFOE BIT(0)
+#define MT8173_GAMMA_MOUT_EN_RDMA1 BIT(0)
+#define MT8173_OD0_MOUT_EN_RDMA0 BIT(0)
+#define MT8173_OVL0_MOUT_EN_COLOR0 BIT(0)
+#define MT8173_OVL1_MOUT_EN_COLOR1 BIT(0)
+#define MT8173_UFOE_MOUT_EN_DSI0 BIT(0)
+#define MT8173_UFOE_SEL_IN_RDMA0 BIT(0)
+#define MT8173_RDMA0_SOUT_COLOR0 BIT(0)
+
+static const struct mtk_mmsys_routes mt8173_mmsys_routing_table[] = {
+ {
+ DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
+ MT8173_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN,
+ MT8173_OVL0_MOUT_EN_COLOR0, MT8173_OVL0_MOUT_EN_COLOR0
+ }, {
+ DDP_COMPONENT_OD0, DDP_COMPONENT_RDMA0,
+ MT8173_DISP_REG_CONFIG_DISP_OD_MOUT_EN,
+ MT8173_OD0_MOUT_EN_RDMA0, MT8173_OD0_MOUT_EN_RDMA0
+ }, {
+ DDP_COMPONENT_UFOE, DDP_COMPONENT_DSI0,
+ MT8173_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN,
+ MT8173_UFOE_MOUT_EN_DSI0, MT8173_UFOE_MOUT_EN_DSI0
+ }, {
+ DDP_COMPONENT_COLOR0, DDP_COMPONENT_AAL0,
+ MT8173_DISP_REG_CONFIG_DISP_COLOR0_SOUT_SEL_IN,
+ MT8173_COLOR0_SOUT_MERGE, 0 /* SOUT to AAL */
+ }, {
+ DDP_COMPONENT_RDMA0, DDP_COMPONENT_UFOE,
+ MT8173_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN,
+ MT8173_RDMA0_SOUT_COLOR0, 0 /* SOUT to UFOE */
+ }, {
+ DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
+ MT8173_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN,
+ MT8173_COLOR0_SEL_IN_OVL0, MT8173_COLOR0_SEL_IN_OVL0
+ }, {
+ DDP_COMPONENT_AAL0, DDP_COMPONENT_COLOR0,
+ MT8173_DISP_REG_CONFIG_DISP_AAL_SEL_IN,
+ MT8173_AAL_SEL_IN_MERGE, 0 /* SEL_IN from COLOR0 */
+ }, {
+ DDP_COMPONENT_RDMA0, DDP_COMPONENT_UFOE,
+ MT8173_DISP_REG_CONFIG_DISP_UFOE_SEL_IN,
+ MT8173_UFOE_SEL_IN_RDMA0, 0 /* SEL_IN from RDMA0 */
+ }, {
+ DDP_COMPONENT_UFOE, DDP_COMPONENT_DSI0,
+ MT8173_DISP_REG_CONFIG_DSI0_SEL_IN,
+ MT8173_DSI0_SEL_IN_UFOE, 0, /* SEL_IN from UFOE */
+ }, {
+ DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
+ MT8173_DISP_REG_CONFIG_DISP_OVL1_MOUT_EN,
+ MT8173_OVL1_MOUT_EN_COLOR1, MT8173_OVL1_MOUT_EN_COLOR1
+ }, {
+ DDP_COMPONENT_GAMMA, DDP_COMPONENT_RDMA1,
+ MT8173_DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN,
+ MT8173_GAMMA_MOUT_EN_RDMA1, MT8173_GAMMA_MOUT_EN_RDMA1
+ }, {
+ DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+ MT8173_DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN,
+ RDMA1_SOUT_MASK, RDMA1_SOUT_DPI0
+ }, {
+ DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
+ MT8173_DISP_REG_CONFIG_DISP_COLOR1_SEL_IN,
+ COLOR1_SEL_IN_OVL1, COLOR1_SEL_IN_OVL1
+ }, {
+ DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+ MT8173_DISP_REG_CONFIG_DPI_SEL_IN,
+ MT8173_DPI0_SEL_IN_MASK, MT8173_DPI0_SEL_IN_RDMA1
+ }
+};
+
+#endif /* __SOC_MEDIATEK_MT8173_MMSYS_H */
diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index a6652ae63431..9be2df2832a4 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -146,6 +146,19 @@
#define MT8195_VDO1_MIXER_SOUT_SEL_IN 0xf68
#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER 0
+/* VPPSYS1 */
+#define MT8195_VPP1_HW_DCM_1ST_DIS0 0x150
+#define MT8195_VPP1_HW_DCM_1ST_DIS1 0x160
+#define MT8195_VPP1_HW_DCM_2ND_DIS0 0x1a0
+#define MT8195_VPP1_HW_DCM_2ND_DIS1 0x1b0
+#define MT8195_SVPP2_BUF_BF_RSZ_SWITCH 0xf48
+#define MT8195_SVPP3_BUF_BF_RSZ_SWITCH 0xf74
+
+/* VPPSYS1 HW DCM client*/
+#define MT8195_SVPP1_MDP_RSZ BIT(25)
+#define MT8195_SVPP2_MDP_RSZ BIT(4)
+#define MT8195_SVPP3_MDP_RSZ BIT(5)
+
static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
{
DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index eb4c7e57896c..9619faa796e8 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -15,6 +15,7 @@
#include "mtk-mmsys.h"
#include "mt8167-mmsys.h"
+#include "mt8173-mmsys.h"
#include "mt8183-mmsys.h"
#include "mt8186-mmsys.h"
#include "mt8188-mmsys.h"
@@ -40,6 +41,14 @@ static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = {
.clk_driver = "clk-mt6779-mm",
};
+static const struct mtk_mmsys_driver_data mt6795_mmsys_driver_data = {
+ .clk_driver = "clk-mt6795-mm",
+ .routes = mt8173_mmsys_routing_table,
+ .num_routes = ARRAY_SIZE(mt8173_mmsys_routing_table),
+ .sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
+ .num_resets = 64,
+};
+
static const struct mtk_mmsys_driver_data mt6797_mmsys_driver_data = {
.clk_driver = "clk-mt6797-mm",
};
@@ -52,10 +61,10 @@ static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
.clk_driver = "clk-mt8173-mm",
- .routes = mmsys_default_routing_table,
- .num_routes = ARRAY_SIZE(mmsys_default_routing_table),
+ .routes = mt8173_mmsys_routing_table,
+ .num_routes = ARRAY_SIZE(mt8173_mmsys_routing_table),
.sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
- .num_resets = 32,
+ .num_resets = 64,
};
static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
@@ -121,6 +130,8 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
struct mtk_mmsys {
void __iomem *regs;
const struct mtk_mmsys_driver_data *data;
+ struct platform_device *clks_pdev;
+ struct platform_device *drm_pdev;
spinlock_t lock; /* protects mmsys_sw_rst_b reg */
struct reset_controller_dev rcdev;
struct cmdq_client_reg cmdq_base;
@@ -129,21 +140,18 @@ struct mtk_mmsys {
static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val,
struct cmdq_pkt *cmdq_pkt)
{
+ int ret;
u32 tmp;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- if (cmdq_pkt) {
- if (mmsys->cmdq_base.size == 0) {
- pr_err("mmsys lose gce property, failed to update mmsys bits with cmdq");
+ if (mmsys->cmdq_base.size && cmdq_pkt) {
+ ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+ mmsys->cmdq_base.offset + offset, val,
+ mask);
+ if (ret)
+ pr_debug("CMDQ unavailable: using CPU write\n");
+ else
return;
- }
- cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
- mmsys->cmdq_base.offset + offset, val,
- mask);
- return;
}
-#endif
-
tmp = readl_relaxed(mmsys->regs + offset);
tmp = (tmp & ~mask) | (val & mask);
writel_relaxed(tmp, mmsys->regs + offset);
@@ -242,6 +250,50 @@ void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val)
}
EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_dpi_fmt_config);
+void mtk_mmsys_vpp_rsz_merge_config(struct device *dev, u32 id, bool enable,
+ struct cmdq_pkt *cmdq_pkt)
+{
+ u32 reg;
+
+ switch (id) {
+ case 2:
+ reg = MT8195_SVPP2_BUF_BF_RSZ_SWITCH;
+ break;
+ case 3:
+ reg = MT8195_SVPP3_BUF_BF_RSZ_SWITCH;
+ break;
+ default:
+ dev_err(dev, "Invalid id %d\n", id);
+ return;
+ }
+
+ mtk_mmsys_update_bits(dev_get_drvdata(dev), reg, ~0, enable, cmdq_pkt);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_vpp_rsz_merge_config);
+
+void mtk_mmsys_vpp_rsz_dcm_config(struct device *dev, bool enable,
+ struct cmdq_pkt *cmdq_pkt)
+{
+ u32 client;
+
+ client = MT8195_SVPP1_MDP_RSZ;
+ mtk_mmsys_update_bits(dev_get_drvdata(dev),
+ MT8195_VPP1_HW_DCM_1ST_DIS0, client,
+ ((enable) ? client : 0), cmdq_pkt);
+ mtk_mmsys_update_bits(dev_get_drvdata(dev),
+ MT8195_VPP1_HW_DCM_2ND_DIS0, client,
+ ((enable) ? client : 0), cmdq_pkt);
+
+ client = MT8195_SVPP2_MDP_RSZ | MT8195_SVPP3_MDP_RSZ;
+ mtk_mmsys_update_bits(dev_get_drvdata(dev),
+ MT8195_VPP1_HW_DCM_1ST_DIS1, client,
+ ((enable) ? client : 0), cmdq_pkt);
+ mtk_mmsys_update_bits(dev_get_drvdata(dev),
+ MT8195_VPP1_HW_DCM_2ND_DIS1, client,
+ ((enable) ? client : 0), cmdq_pkt);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_vpp_rsz_dcm_config);
+
static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
bool assert)
{
@@ -330,11 +382,10 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
}
}
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ /* CMDQ is optional */
ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
if (ret)
dev_dbg(dev, "No mediatek,gce-client-reg!\n");
-#endif
platform_set_drvdata(pdev, mmsys);
@@ -342,6 +393,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
PLATFORM_DEVID_AUTO, NULL, 0);
if (IS_ERR(clks))
return PTR_ERR(clks);
+ mmsys->clks_pdev = clks;
if (mmsys->data->is_vppsys)
goto out_probe_done;
@@ -352,78 +404,44 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
platform_device_unregister(clks);
return PTR_ERR(drm);
}
+ mmsys->drm_pdev = drm;
out_probe_done:
return 0;
}
+static int mtk_mmsys_remove(struct platform_device *pdev)
+{
+ struct mtk_mmsys *mmsys = platform_get_drvdata(pdev);
+
+ platform_device_unregister(mmsys->drm_pdev);
+ platform_device_unregister(mmsys->clks_pdev);
+
+ return 0;
+}
+
static const struct of_device_id of_match_mtk_mmsys[] = {
- {
- .compatible = "mediatek,mt2701-mmsys",
- .data = &mt2701_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt2712-mmsys",
- .data = &mt2712_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt6779-mmsys",
- .data = &mt6779_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt6797-mmsys",
- .data = &mt6797_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt8167-mmsys",
- .data = &mt8167_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt8173-mmsys",
- .data = &mt8173_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt8183-mmsys",
- .data = &mt8183_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt8186-mmsys",
- .data = &mt8186_mmsys_driver_data,
- },
- {
- .compatible = "mediatek,mt8188-vdosys0",
- .data = &mt8188_vdosys0_driver_data,
- },
- {
- .compatible = "mediatek,mt8192-mmsys",
- .data = &mt8192_mmsys_driver_data,
- },
- { /* deprecated compatible */
- .compatible = "mediatek,mt8195-mmsys",
- .data = &mt8195_vdosys0_driver_data,
- },
- {
- .compatible = "mediatek,mt8195-vdosys0",
- .data = &mt8195_vdosys0_driver_data,
- },
- {
- .compatible = "mediatek,mt8195-vdosys1",
- .data = &mt8195_vdosys1_driver_data,
- },
- {
- .compatible = "mediatek,mt8195-vppsys0",
- .data = &mt8195_vppsys0_driver_data,
- },
- {
- .compatible = "mediatek,mt8195-vppsys1",
- .data = &mt8195_vppsys1_driver_data,
- },
- {
- .compatible = "mediatek,mt8365-mmsys",
- .data = &mt8365_mmsys_driver_data,
- },
- { }
+ { .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data },
+ { .compatible = "mediatek,mt2712-mmsys", .data = &mt2712_mmsys_driver_data },
+ { .compatible = "mediatek,mt6779-mmsys", .data = &mt6779_mmsys_driver_data },
+ { .compatible = "mediatek,mt6795-mmsys", .data = &mt6795_mmsys_driver_data },
+ { .compatible = "mediatek,mt6797-mmsys", .data = &mt6797_mmsys_driver_data },
+ { .compatible = "mediatek,mt8167-mmsys", .data = &mt8167_mmsys_driver_data },
+ { .compatible = "mediatek,mt8173-mmsys", .data = &mt8173_mmsys_driver_data },
+ { .compatible = "mediatek,mt8183-mmsys", .data = &mt8183_mmsys_driver_data },
+ { .compatible = "mediatek,mt8186-mmsys", .data = &mt8186_mmsys_driver_data },
+ { .compatible = "mediatek,mt8188-vdosys0", .data = &mt8188_vdosys0_driver_data },
+ { .compatible = "mediatek,mt8192-mmsys", .data = &mt8192_mmsys_driver_data },
+ /* "mediatek,mt8195-mmsys" compatible is deprecated */
+ { .compatible = "mediatek,mt8195-mmsys", .data = &mt8195_vdosys0_driver_data },
+ { .compatible = "mediatek,mt8195-vdosys0", .data = &mt8195_vdosys0_driver_data },
+ { .compatible = "mediatek,mt8195-vdosys1", .data = &mt8195_vdosys1_driver_data },
+ { .compatible = "mediatek,mt8195-vppsys0", .data = &mt8195_vppsys0_driver_data },
+ { .compatible = "mediatek,mt8195-vppsys1", .data = &mt8195_vppsys1_driver_data },
+ { .compatible = "mediatek,mt8365-mmsys", .data = &mt8365_mmsys_driver_data },
+ { /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, of_match_mtk_mmsys);
static struct platform_driver mtk_mmsys_drv = {
.driver = {
@@ -431,20 +449,9 @@ static struct platform_driver mtk_mmsys_drv = {
.of_match_table = of_match_mtk_mmsys,
},
.probe = mtk_mmsys_probe,
+ .remove = mtk_mmsys_remove,
};
-
-static int __init mtk_mmsys_init(void)
-{
- return platform_driver_register(&mtk_mmsys_drv);
-}
-
-static void __exit mtk_mmsys_exit(void)
-{
- platform_driver_unregister(&mtk_mmsys_drv);
-}
-
-module_init(mtk_mmsys_init);
-module_exit(mtk_mmsys_exit);
+module_platform_driver(mtk_mmsys_drv);
MODULE_AUTHOR("Yongqiang Niu <yongqiang.niu@mediatek.com>");
MODULE_DESCRIPTION("MediaTek SoC MMSYS driver");
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 56f8cc3a97b7..6725403d2e3a 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -96,7 +96,7 @@ struct mtk_mmsys_driver_data {
};
/*
- * Routes in mt8173, mt2701, mt2712 are different. That means
+ * Routes in mt2701 and mt2712 are different. That means
* in the same register address, it controls different input/output
* selection for each SoC. But, right now, they use the same table as
* default routes meet their requirements. But we don't have the complete
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index c5b1b42303ac..26f3d9a41496 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -14,6 +14,8 @@
#include <linux/soc/mediatek/mtk-mutex.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
+#define MTK_MUTEX_MAX_HANDLES 10
+
#define MT2701_MUTEX0_MOD0 0x2c
#define MT2701_MUTEX0_SOF0 0x30
#define MT8183_MUTEX0_MOD0 0x30
@@ -23,6 +25,7 @@
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n))
+#define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n) ((mutex_mod_reg) + 0x20 * (n) + 0x4)
#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n))
#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n))
@@ -163,6 +166,53 @@
#define MT8195_MUTEX_MOD_DISP1_DPI1 26
#define MT8195_MUTEX_MOD_DISP1_DP_INTF0 27
+/* VPPSYS0 */
+#define MT8195_MUTEX_MOD_MDP_RDMA0 0
+#define MT8195_MUTEX_MOD_MDP_FG0 1
+#define MT8195_MUTEX_MOD_MDP_STITCH0 2
+#define MT8195_MUTEX_MOD_MDP_HDR0 3
+#define MT8195_MUTEX_MOD_MDP_AAL0 4
+#define MT8195_MUTEX_MOD_MDP_RSZ0 5
+#define MT8195_MUTEX_MOD_MDP_TDSHP0 6
+#define MT8195_MUTEX_MOD_MDP_COLOR0 7
+#define MT8195_MUTEX_MOD_MDP_OVL0 8
+#define MT8195_MUTEX_MOD_MDP_PAD0 9
+#define MT8195_MUTEX_MOD_MDP_TCC0 10
+#define MT8195_MUTEX_MOD_MDP_WROT0 11
+
+/* VPPSYS1 */
+#define MT8195_MUTEX_MOD_MDP_TCC1 3
+#define MT8195_MUTEX_MOD_MDP_RDMA1 4
+#define MT8195_MUTEX_MOD_MDP_RDMA2 5
+#define MT8195_MUTEX_MOD_MDP_RDMA3 6
+#define MT8195_MUTEX_MOD_MDP_FG1 7
+#define MT8195_MUTEX_MOD_MDP_FG2 8
+#define MT8195_MUTEX_MOD_MDP_FG3 9
+#define MT8195_MUTEX_MOD_MDP_HDR1 10
+#define MT8195_MUTEX_MOD_MDP_HDR2 11
+#define MT8195_MUTEX_MOD_MDP_HDR3 12
+#define MT8195_MUTEX_MOD_MDP_AAL1 13
+#define MT8195_MUTEX_MOD_MDP_AAL2 14
+#define MT8195_MUTEX_MOD_MDP_AAL3 15
+#define MT8195_MUTEX_MOD_MDP_RSZ1 16
+#define MT8195_MUTEX_MOD_MDP_RSZ2 17
+#define MT8195_MUTEX_MOD_MDP_RSZ3 18
+#define MT8195_MUTEX_MOD_MDP_TDSHP1 19
+#define MT8195_MUTEX_MOD_MDP_TDSHP2 20
+#define MT8195_MUTEX_MOD_MDP_TDSHP3 21
+#define MT8195_MUTEX_MOD_MDP_MERGE2 22
+#define MT8195_MUTEX_MOD_MDP_MERGE3 23
+#define MT8195_MUTEX_MOD_MDP_COLOR1 24
+#define MT8195_MUTEX_MOD_MDP_COLOR2 25
+#define MT8195_MUTEX_MOD_MDP_COLOR3 26
+#define MT8195_MUTEX_MOD_MDP_OVL1 27
+#define MT8195_MUTEX_MOD_MDP_PAD1 28
+#define MT8195_MUTEX_MOD_MDP_PAD2 29
+#define MT8195_MUTEX_MOD_MDP_PAD3 30
+#define MT8195_MUTEX_MOD_MDP_WROT1 31
+#define MT8195_MUTEX_MOD_MDP_WROT2 32
+#define MT8195_MUTEX_MOD_MDP_WROT3 33
+
#define MT8365_MUTEX_MOD_DISP_OVL0 7
#define MT8365_MUTEX_MOD_DISP_OVL0_2L 8
#define MT8365_MUTEX_MOD_DISP_RDMA0 9
@@ -234,7 +284,7 @@
#define MT8195_MUTEX_EOF_DPI1 (MT8195_MUTEX_SOF_DPI1 << 7)
struct mtk_mutex {
- int id;
+ u8 id;
bool claimed;
};
@@ -264,7 +314,7 @@ struct mtk_mutex_ctx {
struct device *dev;
struct clk *clk;
void __iomem *regs;
- struct mtk_mutex mutex[10];
+ struct mtk_mutex mutex[MTK_MUTEX_MAX_HANDLES];
const struct mtk_mutex_data *data;
phys_addr_t addr;
struct cmdq_client_reg cmdq_reg;
@@ -443,6 +493,52 @@ static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
};
+static const unsigned int mt8195_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
+ [MUTEX_MOD_IDX_MDP_RDMA0] = MT8195_MUTEX_MOD_MDP_RDMA0,
+ [MUTEX_MOD_IDX_MDP_RDMA1] = MT8195_MUTEX_MOD_MDP_RDMA1,
+ [MUTEX_MOD_IDX_MDP_RDMA2] = MT8195_MUTEX_MOD_MDP_RDMA2,
+ [MUTEX_MOD_IDX_MDP_RDMA3] = MT8195_MUTEX_MOD_MDP_RDMA3,
+ [MUTEX_MOD_IDX_MDP_STITCH0] = MT8195_MUTEX_MOD_MDP_STITCH0,
+ [MUTEX_MOD_IDX_MDP_FG0] = MT8195_MUTEX_MOD_MDP_FG0,
+ [MUTEX_MOD_IDX_MDP_FG1] = MT8195_MUTEX_MOD_MDP_FG1,
+ [MUTEX_MOD_IDX_MDP_FG2] = MT8195_MUTEX_MOD_MDP_FG2,
+ [MUTEX_MOD_IDX_MDP_FG3] = MT8195_MUTEX_MOD_MDP_FG3,
+ [MUTEX_MOD_IDX_MDP_HDR0] = MT8195_MUTEX_MOD_MDP_HDR0,
+ [MUTEX_MOD_IDX_MDP_HDR1] = MT8195_MUTEX_MOD_MDP_HDR1,
+ [MUTEX_MOD_IDX_MDP_HDR2] = MT8195_MUTEX_MOD_MDP_HDR2,
+ [MUTEX_MOD_IDX_MDP_HDR3] = MT8195_MUTEX_MOD_MDP_HDR3,
+ [MUTEX_MOD_IDX_MDP_AAL0] = MT8195_MUTEX_MOD_MDP_AAL0,
+ [MUTEX_MOD_IDX_MDP_AAL1] = MT8195_MUTEX_MOD_MDP_AAL1,
+ [MUTEX_MOD_IDX_MDP_AAL2] = MT8195_MUTEX_MOD_MDP_AAL2,
+ [MUTEX_MOD_IDX_MDP_AAL3] = MT8195_MUTEX_MOD_MDP_AAL3,
+ [MUTEX_MOD_IDX_MDP_RSZ0] = MT8195_MUTEX_MOD_MDP_RSZ0,
+ [MUTEX_MOD_IDX_MDP_RSZ1] = MT8195_MUTEX_MOD_MDP_RSZ1,
+ [MUTEX_MOD_IDX_MDP_RSZ2] = MT8195_MUTEX_MOD_MDP_RSZ2,
+ [MUTEX_MOD_IDX_MDP_RSZ3] = MT8195_MUTEX_MOD_MDP_RSZ3,
+ [MUTEX_MOD_IDX_MDP_MERGE2] = MT8195_MUTEX_MOD_MDP_MERGE2,
+ [MUTEX_MOD_IDX_MDP_MERGE3] = MT8195_MUTEX_MOD_MDP_MERGE3,
+ [MUTEX_MOD_IDX_MDP_TDSHP0] = MT8195_MUTEX_MOD_MDP_TDSHP0,
+ [MUTEX_MOD_IDX_MDP_TDSHP1] = MT8195_MUTEX_MOD_MDP_TDSHP1,
+ [MUTEX_MOD_IDX_MDP_TDSHP2] = MT8195_MUTEX_MOD_MDP_TDSHP2,
+ [MUTEX_MOD_IDX_MDP_TDSHP3] = MT8195_MUTEX_MOD_MDP_TDSHP3,
+ [MUTEX_MOD_IDX_MDP_COLOR0] = MT8195_MUTEX_MOD_MDP_COLOR0,
+ [MUTEX_MOD_IDX_MDP_COLOR1] = MT8195_MUTEX_MOD_MDP_COLOR1,
+ [MUTEX_MOD_IDX_MDP_COLOR2] = MT8195_MUTEX_MOD_MDP_COLOR2,
+ [MUTEX_MOD_IDX_MDP_COLOR3] = MT8195_MUTEX_MOD_MDP_COLOR3,
+ [MUTEX_MOD_IDX_MDP_OVL0] = MT8195_MUTEX_MOD_MDP_OVL0,
+ [MUTEX_MOD_IDX_MDP_OVL1] = MT8195_MUTEX_MOD_MDP_OVL1,
+ [MUTEX_MOD_IDX_MDP_PAD0] = MT8195_MUTEX_MOD_MDP_PAD0,
+ [MUTEX_MOD_IDX_MDP_PAD1] = MT8195_MUTEX_MOD_MDP_PAD1,
+ [MUTEX_MOD_IDX_MDP_PAD2] = MT8195_MUTEX_MOD_MDP_PAD2,
+ [MUTEX_MOD_IDX_MDP_PAD3] = MT8195_MUTEX_MOD_MDP_PAD3,
+ [MUTEX_MOD_IDX_MDP_TCC0] = MT8195_MUTEX_MOD_MDP_TCC0,
+ [MUTEX_MOD_IDX_MDP_TCC1] = MT8195_MUTEX_MOD_MDP_TCC1,
+ [MUTEX_MOD_IDX_MDP_WROT0] = MT8195_MUTEX_MOD_MDP_WROT0,
+ [MUTEX_MOD_IDX_MDP_WROT1] = MT8195_MUTEX_MOD_MDP_WROT1,
+ [MUTEX_MOD_IDX_MDP_WROT2] = MT8195_MUTEX_MOD_MDP_WROT2,
+ [MUTEX_MOD_IDX_MDP_WROT3] = MT8195_MUTEX_MOD_MDP_WROT3,
+};
+
static const unsigned int mt8365_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL0] = MT8365_MUTEX_MOD_DISP_AAL,
[DDP_COMPONENT_CCORR] = MT8365_MUTEX_MOD_DISP_CCORR,
@@ -603,6 +699,13 @@ static const struct mtk_mutex_data mt8195_mutex_driver_data = {
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
};
+static const struct mtk_mutex_data mt8195_vpp_mutex_driver_data = {
+ .mutex_sof = mt8195_mutex_sof,
+ .mutex_mod_reg = MT8183_MUTEX0_MOD0,
+ .mutex_sof_reg = MT8183_MUTEX0_SOF0,
+ .mutex_table_mod = mt8195_mutex_table_mod,
+};
+
static const struct mtk_mutex_data mt8365_mutex_driver_data = {
.mutex_mod = mt8365_mutex_mod,
.mutex_sof = mt8183_mutex_sof,
@@ -616,7 +719,7 @@ struct mtk_mutex *mtk_mutex_get(struct device *dev)
struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
int i;
- for (i = 0; i < 10; i++)
+ for (i = 0; i < MTK_MUTEX_MAX_HANDLES; i++)
if (!mtx->mutex[i].claimed) {
mtx->mutex[i].claimed = true;
return &mtx->mutex[i];
@@ -768,23 +871,18 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
{
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
mutex[mutex->id]);
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt;
WARN_ON(&mtx->mutex[mutex->id] != mutex);
if (!mtx->cmdq_reg.size) {
dev_err(mtx->dev, "mediatek,gce-client-reg hasn't been set");
- return -EINVAL;
+ return -ENODEV;
}
cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys,
mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1);
return 0;
-#else
- dev_err(mtx->dev, "Not support for enable MUTEX by CMDQ");
- return -ENODEV;
-#endif
}
EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
@@ -828,7 +926,7 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex,
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
mutex[mutex->id]);
unsigned int reg;
- unsigned int offset;
+ u32 reg_offset, id_offset = 0;
WARN_ON(&mtx->mutex[mutex->id] != mutex);
@@ -838,16 +936,34 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex,
return -EINVAL;
}
- offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
- mutex->id);
- reg = readl_relaxed(mtx->regs + offset);
+ /*
+ * Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods
+ * are present, hence requiring multiple 32-bits registers.
+ *
+ * The mutex_table_mod fully represents that by defining the number of
+ * the mod sequentially, later used as a bit number, which can be more
+ * than 0..31.
+ *
+ * In order to retain compatibility with older SoCs, we perform R/W on
+ * the single 32 bits registers, but this requires us to translate the
+ * mutex ID bit accordingly.
+ */
+ if (mtx->data->mutex_table_mod[idx] < 32) {
+ reg_offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
+ mutex->id);
+ } else {
+ reg_offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg,
+ mutex->id);
+ id_offset = 32;
+ }
+ reg = readl_relaxed(mtx->regs + reg_offset);
if (clear)
- reg &= ~BIT(mtx->data->mutex_table_mod[idx]);
+ reg &= ~BIT(mtx->data->mutex_table_mod[idx] - id_offset);
else
- reg |= BIT(mtx->data->mutex_table_mod[idx]);
+ reg |= BIT(mtx->data->mutex_table_mod[idx] - id_offset);
- writel_relaxed(reg, mtx->regs + offset);
+ writel_relaxed(reg, mtx->regs + reg_offset);
return 0;
}
@@ -879,27 +995,21 @@ static int mtk_mutex_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mtk_mutex_ctx *mtx;
struct resource *regs;
- int i;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- int ret;
-#endif
+ int i, ret;
mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
if (!mtx)
return -ENOMEM;
- for (i = 0; i < 10; i++)
+ for (i = 0; i < MTK_MUTEX_MAX_HANDLES; i++)
mtx->mutex[i].id = i;
mtx->data = of_device_get_match_data(dev);
if (!mtx->data->no_clk) {
mtx->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(mtx->clk)) {
- if (PTR_ERR(mtx->clk) != -EPROBE_DEFER)
- dev_err(dev, "Failed to get clock\n");
- return PTR_ERR(mtx->clk);
- }
+ if (IS_ERR(mtx->clk))
+ return dev_err_probe(dev, PTR_ERR(mtx->clk), "Failed to get clock\n");
}
mtx->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
@@ -909,11 +1019,10 @@ static int mtk_mutex_probe(struct platform_device *pdev)
}
mtx->addr = regs->start;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ /* CMDQ is optional */
ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0);
if (ret)
dev_dbg(dev, "No mediatek,gce-client-reg!\n");
-#endif
platform_set_drvdata(pdev, mtx);
@@ -921,31 +1030,20 @@ static int mtk_mutex_probe(struct platform_device *pdev)
}
static const struct of_device_id mutex_driver_dt_match[] = {
- { .compatible = "mediatek,mt2701-disp-mutex",
- .data = &mt2701_mutex_driver_data},
- { .compatible = "mediatek,mt2712-disp-mutex",
- .data = &mt2712_mutex_driver_data},
- { .compatible = "mediatek,mt6795-disp-mutex",
- .data = &mt6795_mutex_driver_data},
- { .compatible = "mediatek,mt8167-disp-mutex",
- .data = &mt8167_mutex_driver_data},
- { .compatible = "mediatek,mt8173-disp-mutex",
- .data = &mt8173_mutex_driver_data},
- { .compatible = "mediatek,mt8183-disp-mutex",
- .data = &mt8183_mutex_driver_data},
- { .compatible = "mediatek,mt8186-disp-mutex",
- .data = &mt8186_mutex_driver_data},
- { .compatible = "mediatek,mt8186-mdp3-mutex",
- .data = &mt8186_mdp_mutex_driver_data},
- { .compatible = "mediatek,mt8188-disp-mutex",
- .data = &mt8188_mutex_driver_data},
- { .compatible = "mediatek,mt8192-disp-mutex",
- .data = &mt8192_mutex_driver_data},
- { .compatible = "mediatek,mt8195-disp-mutex",
- .data = &mt8195_mutex_driver_data},
- { .compatible = "mediatek,mt8365-disp-mutex",
- .data = &mt8365_mutex_driver_data},
- {},
+ { .compatible = "mediatek,mt2701-disp-mutex", .data = &mt2701_mutex_driver_data },
+ { .compatible = "mediatek,mt2712-disp-mutex", .data = &mt2712_mutex_driver_data },
+ { .compatible = "mediatek,mt6795-disp-mutex", .data = &mt6795_mutex_driver_data },
+ { .compatible = "mediatek,mt8167-disp-mutex", .data = &mt8167_mutex_driver_data },
+ { .compatible = "mediatek,mt8173-disp-mutex", .data = &mt8173_mutex_driver_data },
+ { .compatible = "mediatek,mt8183-disp-mutex", .data = &mt8183_mutex_driver_data },
+ { .compatible = "mediatek,mt8186-disp-mutex", .data = &mt8186_mutex_driver_data },
+ { .compatible = "mediatek,mt8186-mdp3-mutex", .data = &mt8186_mdp_mutex_driver_data },
+ { .compatible = "mediatek,mt8188-disp-mutex", .data = &mt8188_mutex_driver_data },
+ { .compatible = "mediatek,mt8192-disp-mutex", .data = &mt8192_mutex_driver_data },
+ { .compatible = "mediatek,mt8195-disp-mutex", .data = &mt8195_mutex_driver_data },
+ { .compatible = "mediatek,mt8195-vpp-mutex", .data = &mt8195_vpp_mutex_driver_data },
+ { .compatible = "mediatek,mt8365-disp-mutex", .data = &mt8365_mutex_driver_data },
+ { /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
@@ -957,19 +1055,7 @@ static struct platform_driver mtk_mutex_driver = {
.of_match_table = mutex_driver_dt_match,
},
};
-
-static int __init mtk_mutex_init(void)
-{
- return platform_driver_register(&mtk_mutex_driver);
-}
-
-static void __exit mtk_mutex_exit(void)
-{
- platform_driver_unregister(&mtk_mutex_driver);
-}
-
-module_init(mtk_mutex_init);
-module_exit(mtk_mutex_exit);
+module_platform_driver(mtk_mutex_driver);
MODULE_AUTHOR("Yongqiang Niu <yongqiang.niu@mediatek.com>");
MODULE_DESCRIPTION("MediaTek SoC MUTEX driver");
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index f26eb2f637d5..b9c96182a46a 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -558,7 +558,7 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
}
/* Get thermal effect */
- if (svsb->phase == SVSB_PHASE_MON) {
+ if (!IS_ERR_OR_NULL(svsb->tzd)) {
ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
@@ -573,7 +573,8 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
temp_voffset += svsb->tzone_ltemp_voffset;
/* 2-line bank update all opp volts when running mon mode */
- if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+ if (svsb->phase == SVSB_PHASE_MON && (svsb->type == SVSB_HIGH ||
+ svsb->type == SVSB_LOW)) {
opp_start = 0;
opp_stop = svsb->opp_count;
}
@@ -589,11 +590,6 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
/* do nothing */
goto unlock_mutex;
case SVSB_PHASE_INIT02:
- svsb_volt = max(svsb->volt[i], svsb->vmin);
- opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
- svsb->volt_step,
- svsb->volt_base);
- break;
case SVSB_PHASE_MON:
svsb_volt = max(svsb->volt[i] + temp_voffset, svsb->vmin);
opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
@@ -624,6 +620,25 @@ unlock_mutex:
return ret;
}
+static void svs_bank_disable_and_restore_default_volts(struct svs_platform *svsp,
+ struct svs_bank *svsb)
+{
+ unsigned long flags;
+
+ if (svsb->mode_support == SVSB_MODE_ALL_DISABLE)
+ return;
+
+ spin_lock_irqsave(&svs_lock, flags);
+ svsp->pbank = svsb;
+ svs_switch_bank(svsp);
+ svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
+ svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
+ spin_unlock_irqrestore(&svs_lock, flags);
+
+ svsb->phase = SVSB_PHASE_ERROR;
+ svs_adjust_pm_opp_volts(svsb);
+}
+
#ifdef CONFIG_DEBUG_FS
static int svs_dump_debug_show(struct seq_file *m, void *p)
{
@@ -700,7 +715,6 @@ static ssize_t svs_enable_debug_write(struct file *filp,
{
struct svs_bank *svsb = file_inode(filp)->i_private;
struct svs_platform *svsp = dev_get_drvdata(svsb->dev);
- unsigned long flags;
int enabled, ret;
char *buf = NULL;
@@ -716,16 +730,8 @@ static ssize_t svs_enable_debug_write(struct file *filp,
return ret;
if (!enabled) {
- spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
svsb->mode_support = SVSB_MODE_ALL_DISABLE;
- svs_switch_bank(svsp);
- svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
- svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
- spin_unlock_irqrestore(&svs_lock, flags);
-
- svsb->phase = SVSB_PHASE_ERROR;
- svs_adjust_pm_opp_volts(svsb);
}
kfree(buf);
@@ -1508,16 +1514,7 @@ static int svs_init02(struct svs_platform *svsp)
out_of_init02:
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
-
- spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_switch_bank(svsp);
- svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
- svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
- spin_unlock_irqrestore(&svs_lock, flags);
-
- svsb->phase = SVSB_PHASE_ERROR;
- svs_adjust_pm_opp_volts(svsb);
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
}
return ret;
@@ -1563,23 +1560,12 @@ static int svs_suspend(struct device *dev)
{
struct svs_platform *svsp = dev_get_drvdata(dev);
struct svs_bank *svsb;
- unsigned long flags;
int ret;
u32 idx;
for (idx = 0; idx < svsp->bank_max; idx++) {
svsb = &svsp->banks[idx];
-
- /* This might wait for svs_isr() process */
- spin_lock_irqsave(&svs_lock, flags);
- svsp->pbank = svsb;
- svs_switch_bank(svsp);
- svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
- svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
- spin_unlock_irqrestore(&svs_lock, flags);
-
- svsb->phase = SVSB_PHASE_ERROR;
- svs_adjust_pm_opp_volts(svsb);
+ svs_bank_disable_and_restore_default_volts(svsp, svsb);
}
ret = reset_control_assert(svsp->rst);
@@ -1693,7 +1679,7 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
}
}
- if (svsb->mode_support & SVSB_MODE_MON) {
+ if (!IS_ERR_OR_NULL(svsb->tzone_name)) {
svsb->tzd = thermal_zone_get_zone_by_name(svsb->tzone_name);
if (IS_ERR(svsb->tzd)) {
dev_err(svsb->dev, "cannot get \"%s\" thermal zone\n",
@@ -1729,26 +1715,28 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
return 0;
}
-static int svs_thermal_efuse_get_data(struct svs_platform *svsp)
+static int svs_get_efuse_data(struct svs_platform *svsp,
+ const char *nvmem_cell_name,
+ u32 **svsp_efuse, size_t *svsp_efuse_max)
{
struct nvmem_cell *cell;
- /* Thermal efuse parsing */
- cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
- if (IS_ERR_OR_NULL(cell)) {
- dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", PTR_ERR(cell));
+ cell = nvmem_cell_get(svsp->dev, nvmem_cell_name);
+ if (IS_ERR(cell)) {
+ dev_err(svsp->dev, "no \"%s\"? %ld\n",
+ nvmem_cell_name, PTR_ERR(cell));
return PTR_ERR(cell);
}
- svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max);
- if (IS_ERR(svsp->tefuse)) {
- dev_err(svsp->dev, "cannot read thermal efuse: %ld\n",
- PTR_ERR(svsp->tefuse));
+ *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->tefuse);
+ return PTR_ERR(*svsp_efuse);
}
- svsp->tefuse_max /= sizeof(u32);
+ *svsp_efuse_max /= sizeof(u32);
nvmem_cell_put(cell);
return 0;
@@ -1796,7 +1784,8 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
svsb->vmax += svsb->dvt_fixed;
}
- ret = svs_thermal_efuse_get_data(svsp);
+ ret = svs_get_efuse_data(svsp, "t-calibration-data",
+ &svsp->tefuse, &svsp->tefuse_max);
if (ret)
return false;
@@ -1901,7 +1890,8 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
}
}
- ret = svs_thermal_efuse_get_data(svsp);
+ ret = svs_get_efuse_data(svsp, "t-calibration-data",
+ &svsp->tefuse, &svsp->tefuse_max);
if (ret)
return false;
@@ -2003,32 +1993,6 @@ remove_mt8183_svsb_mon_mode:
return true;
}
-static bool svs_is_efuse_data_correct(struct svs_platform *svsp)
-{
- struct nvmem_cell *cell;
-
- /* Get svs efuse by nvmem */
- cell = nvmem_cell_get(svsp->dev, "svs-calibration-data");
- if (IS_ERR(cell)) {
- dev_err(svsp->dev, "no \"svs-calibration-data\"? %ld\n",
- PTR_ERR(cell));
- return false;
- }
-
- svsp->efuse = nvmem_cell_read(cell, &svsp->efuse_max);
- if (IS_ERR(svsp->efuse)) {
- dev_err(svsp->dev, "cannot read svs efuse: %ld\n",
- PTR_ERR(svsp->efuse));
- nvmem_cell_put(cell);
- return false;
- }
-
- svsp->efuse_max /= sizeof(u32);
- nvmem_cell_put(cell);
-
- return true;
-}
-
static struct device *svs_get_subsys_device(struct svs_platform *svsp,
const char *node_name)
{
@@ -2059,11 +2023,6 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
struct device *dev;
struct device_link *sup_link;
- if (!node_name) {
- dev_err(svsp->dev, "node name cannot be null\n");
- return ERR_PTR(-EINVAL);
- }
-
dev = svs_get_subsys_device(svsp, node_name);
if (IS_ERR(dev))
return dev;
@@ -2159,6 +2118,7 @@ static struct svs_bank svs_mt8192_banks[] = {
.type = SVSB_LOW,
.set_freq_pct = svs_set_bank_freq_pct_v3,
.get_volts = svs_get_bank_volts_v3,
+ .tzone_name = "gpu1",
.volt_flags = SVSB_REMOVE_DVTFIXED_VOLT,
.mode_support = SVSB_MODE_INIT02,
.opp_count = MAX_OPP_ENTRIES,
@@ -2176,6 +2136,10 @@ static struct svs_bank svs_mt8192_banks[] = {
.core_sel = 0x0fff0100,
.int_st = BIT(0),
.ctl0 = 0x00540003,
+ .tzone_htemp = 85000,
+ .tzone_htemp_voffset = 0,
+ .tzone_ltemp = 25000,
+ .tzone_ltemp_voffset = 7,
},
{
.sw_id = SVSB_GPU,
@@ -2364,8 +2328,9 @@ static int svs_probe(struct platform_device *pdev)
if (ret)
return ret;
- if (!svs_is_efuse_data_correct(svsp)) {
- dev_notice(svsp->dev, "efuse data isn't correct\n");
+ ret = svs_get_efuse_data(svsp, "svs-calibration-data",
+ &svsp->efuse, &svsp->efuse_max);
+ if (ret) {
ret = -EPERM;
goto svs_probe_free_efuse;
}
@@ -2373,19 +2338,19 @@ static int svs_probe(struct platform_device *pdev)
if (!svsp_data->efuse_parsing(svsp)) {
dev_err(svsp->dev, "efuse data parsing failed\n");
ret = -EPERM;
- goto svs_probe_free_resource;
+ 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);
- goto svs_probe_free_resource;
+ goto svs_probe_free_tefuse;
}
svsp_irq = platform_get_irq(pdev, 0);
if (svsp_irq < 0) {
ret = svsp_irq;
- goto svs_probe_free_resource;
+ goto svs_probe_free_tefuse;
}
svsp->main_clk = devm_clk_get(svsp->dev, "main");
@@ -2393,13 +2358,13 @@ static int svs_probe(struct platform_device *pdev)
dev_err(svsp->dev, "failed to get clock: %ld\n",
PTR_ERR(svsp->main_clk));
ret = PTR_ERR(svsp->main_clk);
- goto svs_probe_free_resource;
+ 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);
- goto svs_probe_free_resource;
+ goto svs_probe_free_tefuse;
}
svsp->base = of_iomap(svsp->dev->of_node, 0);
@@ -2439,7 +2404,7 @@ svs_probe_iounmap:
svs_probe_clk_disable:
clk_disable_unprepare(svsp->main_clk);
-svs_probe_free_resource:
+svs_probe_free_tefuse:
if (!IS_ERR_OR_NULL(svsp->tefuse))
kfree(svsp->tefuse);