diff options
author | Arnd Bergmann <arnd@arndb.de> | 2023-04-14 22:39:49 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2023-04-14 22:39:59 +0200 |
commit | 4f2f29913684f729b70bbfa0c6c23c7025f1db89 (patch) | |
tree | 4bfb948135c21ded955217a0a04ce17f32d1cd6b /drivers/soc | |
parent | 04523aceae8c89d3c91ff33bdde6892f63a60f35 (diff) | |
parent | 5ce5e0d08e340ab13169a5f33ed5f98000891a61 (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/mediatek/mt8173-mmsys.h | 95 | ||||
-rw-r--r-- | drivers/soc/mediatek/mt8195-mmsys.h | 13 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-mmsys.c | 195 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-mmsys.h | 2 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-mutex.c | 218 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-svs.c | 149 |
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, ®s); @@ -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); |