Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'v5.19-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into arm/drivers

pmic wrapper:
- code style improvements

devapc:
- add support for MT8186

Smart Voltage Scaling (SVS)
- add support for MT8183 and MT8192

MMSYS:
- Add more display paths for MT8365

Mutex:
- Add common interface for MOD and SOF table
- Add support for MDP on MT8183
- Move binding to soc folder
- Add support to use CMDQ to enable the mutex, needed by MDP3

Power domains:
- Add support for MT6795

* tag 'v5.19-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux: (29 commits)
soc: mediatek: mutex: Simplify with devm_platform_get_and_ioremap_resource()
soc: mediatek: pm-domains: Add support for Helio X10 MT6795
dt-bindings: power: Add MediaTek Helio X10 MT6795 power domains
soc: mediatek: SVS: Use DEFINE_SIMPLE_DEV_PM_OPS for svs_pm_ops
soc: mediatek: mtk-pm-domains: Allow probing vreg supply on two MFGs
soc: mediatek: fix missing clk_disable_unprepare() on err in svs_resume()
soc: mediatek: mutex: Use DDP_COMPONENT_DITHER0 mod index for MT8365
soc: mediatek: mutex: add functions that operate registers by CMDQ
dt-bindings: soc: mediatek: add gce-client-reg for MUTEX
dt-bindings: soc: mediatek: move out common module from display folder
soc: mediatek: mutex: add 8183 MUTEX MOD settings for MDP
soc: mediatek: mutex: add common interface for modules setting
soc: mediatek: pm-domains: Add support always on flag
soc: mediatek: mt8365-mmsys: add DPI/HDMI display path
soc: mediatek: mutex: add MT8365 support
soc: mediatek: SVS: add mt8192 SVS GPU driver
dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
soc: mediatek: SVS: add debug commands
soc: mediatek: SVS: add monitor mode
soc: mediatek: SVS: introduce MTK SVS engine
...

Link: https://lore.kernel.org/r/b733bd82-6d99-23ef-0541-98e98eb8d3bc@gmail.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+2994 -149
+13 -1
Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - $id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml# 4 + $id: http://devicetree.org/schemas/soc/mediatek/mediatek,mutex.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 7 title: Mediatek mutex ··· 54 54 to gce. The event id is defined in the gce header 55 55 include/dt-bindings/gce/<chip>-gce.h of each chips. 56 56 $ref: /schemas/types.yaml#/definitions/uint32-array 57 + 58 + mediatek,gce-client-reg: 59 + $ref: /schemas/types.yaml#/definitions/phandle-array 60 + items: 61 + items: 62 + - description: phandle of GCE 63 + - description: GCE subsys id 64 + - description: register offset 65 + - description: register size 66 + description: The register of client driver can be configured by gce with 67 + 4 arguments defined in this property. Each GCE subsys id is mapping to 68 + a client defined in the header include/dt-bindings/gce/<chip>-gce.h. 57 69 58 70 required: 59 71 - compatible
+2
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
··· 23 23 24 24 compatible: 25 25 enum: 26 + - mediatek,mt6795-power-controller 26 27 - mediatek,mt8167-power-controller 27 28 - mediatek,mt8173-power-controller 28 29 - mediatek,mt8183-power-controller ··· 63 62 reg: 64 63 description: | 65 64 Power domain index. Valid values are defined in: 65 + "include/dt-bindings/power/mt6795-power.h" - for MT8167 type power domain. 66 66 "include/dt-bindings/power/mt8167-power.h" - for MT8167 type power domain. 67 67 "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain. 68 68 "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
+1
Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
··· 20 20 compatible: 21 21 enum: 22 22 - mediatek,mt6779-devapc 23 + - mediatek,mt8186-devapc 23 24 24 25 reg: 25 26 description: The base address of devapc register bank
+91
Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/soc/mediatek/mtk-svs.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek Smart Voltage Scaling (SVS) Device Tree Bindings 8 + 9 + maintainers: 10 + - Roger Lu <roger.lu@mediatek.com> 11 + - Matthias Brugger <matthias.bgg@gmail.com> 12 + - Kevin Hilman <khilman@kernel.org> 13 + 14 + description: |+ 15 + The SVS engine is a piece of hardware which has several 16 + controllers(banks) for calculating suitable voltage to 17 + different power domains(CPU/GPU/CCI) according to 18 + chip process corner, temperatures and other factors. Then DVFS 19 + driver could apply SVS bank voltage to PMIC/Buck. 20 + 21 + properties: 22 + compatible: 23 + enum: 24 + - mediatek,mt8183-svs 25 + - mediatek,mt8192-svs 26 + 27 + reg: 28 + maxItems: 1 29 + description: Address range of the MTK SVS controller. 30 + 31 + interrupts: 32 + maxItems: 1 33 + 34 + clocks: 35 + maxItems: 1 36 + description: Main clock for MTK SVS controller to work. 37 + 38 + clock-names: 39 + const: main 40 + 41 + nvmem-cells: 42 + minItems: 1 43 + description: 44 + Phandle to the calibration data provided by a nvmem device. 45 + items: 46 + - description: SVS efuse for SVS controller 47 + - description: Thermal efuse for SVS controller 48 + 49 + nvmem-cell-names: 50 + items: 51 + - const: svs-calibration-data 52 + - const: t-calibration-data 53 + 54 + resets: 55 + maxItems: 1 56 + 57 + reset-names: 58 + items: 59 + - const: svs_rst 60 + 61 + required: 62 + - compatible 63 + - reg 64 + - interrupts 65 + - clocks 66 + - clock-names 67 + - nvmem-cells 68 + - nvmem-cell-names 69 + 70 + additionalProperties: false 71 + 72 + examples: 73 + - | 74 + #include <dt-bindings/clock/mt8183-clk.h> 75 + #include <dt-bindings/interrupt-controller/arm-gic.h> 76 + #include <dt-bindings/interrupt-controller/irq.h> 77 + 78 + soc { 79 + #address-cells = <2>; 80 + #size-cells = <2>; 81 + 82 + svs@1100b000 { 83 + compatible = "mediatek,mt8183-svs"; 84 + reg = <0 0x1100b000 0 0x1000>; 85 + interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>; 86 + clocks = <&infracfg CLK_INFRA_THERM>; 87 + clock-names = "main"; 88 + nvmem-cells = <&svs_calibration>, <&thermal_calibration>; 89 + nvmem-cell-names = "svs-calibration-data", "t-calibration-data"; 90 + }; 91 + };
+10
drivers/soc/mediatek/Kconfig
··· 73 73 Say yes here to add support for the MediaTek Multimedia 74 74 Subsystem (MMSYS). 75 75 76 + config MTK_SVS 77 + tristate "MediaTek Smart Voltage Scaling(SVS)" 78 + depends on MTK_EFUSE && NVMEM 79 + help 80 + The Smart Voltage Scaling(SVS) engine is a piece of hardware 81 + which has several controllers(banks) for calculating suitable 82 + voltage to different power domains(CPU/GPU/CCI) according to 83 + chip process corner, temperatures and other factors. Then DVFS 84 + driver could apply SVS bank voltage to PMIC/Buck. 85 + 76 86 endmenu
+1
drivers/soc/mediatek/Makefile
··· 7 7 obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o 8 8 obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o 9 9 obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o 10 + obj-$(CONFIG_MTK_SVS) += mtk-svs.o
+112
drivers/soc/mediatek/mt6795-pm-domains.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __SOC_MEDIATEK_MT6795_PM_DOMAINS_H 4 + #define __SOC_MEDIATEK_MT6795_PM_DOMAINS_H 5 + 6 + #include "mtk-pm-domains.h" 7 + #include <dt-bindings/power/mt6795-power.h> 8 + 9 + /* 10 + * MT6795 power domain support 11 + */ 12 + 13 + static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = { 14 + [MT6795_POWER_DOMAIN_VDEC] = { 15 + .name = "vdec", 16 + .sta_mask = PWR_STATUS_VDEC, 17 + .ctl_offs = SPM_VDE_PWR_CON, 18 + .pwr_sta_offs = SPM_PWR_STATUS, 19 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 20 + .sram_pdn_bits = GENMASK(11, 8), 21 + .sram_pdn_ack_bits = GENMASK(12, 12), 22 + }, 23 + [MT6795_POWER_DOMAIN_VENC] = { 24 + .name = "venc", 25 + .sta_mask = PWR_STATUS_VENC, 26 + .ctl_offs = SPM_VEN_PWR_CON, 27 + .pwr_sta_offs = SPM_PWR_STATUS, 28 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 29 + .sram_pdn_bits = GENMASK(11, 8), 30 + .sram_pdn_ack_bits = GENMASK(15, 12), 31 + }, 32 + [MT6795_POWER_DOMAIN_ISP] = { 33 + .name = "isp", 34 + .sta_mask = PWR_STATUS_ISP, 35 + .ctl_offs = SPM_ISP_PWR_CON, 36 + .pwr_sta_offs = SPM_PWR_STATUS, 37 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 38 + .sram_pdn_bits = GENMASK(11, 8), 39 + .sram_pdn_ack_bits = GENMASK(13, 12), 40 + }, 41 + [MT6795_POWER_DOMAIN_MM] = { 42 + .name = "mm", 43 + .sta_mask = PWR_STATUS_DISP, 44 + .ctl_offs = SPM_DIS_PWR_CON, 45 + .pwr_sta_offs = SPM_PWR_STATUS, 46 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 47 + .sram_pdn_bits = GENMASK(11, 8), 48 + .sram_pdn_ack_bits = GENMASK(12, 12), 49 + .bp_infracfg = { 50 + BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 | 51 + MT8173_TOP_AXI_PROT_EN_MM_M1), 52 + }, 53 + }, 54 + [MT6795_POWER_DOMAIN_MJC] = { 55 + .name = "mjc", 56 + .sta_mask = BIT(20), 57 + .ctl_offs = 0x298, 58 + .pwr_sta_offs = SPM_PWR_STATUS, 59 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 60 + .sram_pdn_bits = GENMASK(11, 8), 61 + .sram_pdn_ack_bits = GENMASK(15, 12), 62 + }, 63 + [MT6795_POWER_DOMAIN_AUDIO] = { 64 + .name = "audio", 65 + .sta_mask = PWR_STATUS_AUDIO, 66 + .ctl_offs = SPM_AUDIO_PWR_CON, 67 + .pwr_sta_offs = SPM_PWR_STATUS, 68 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 69 + .sram_pdn_bits = GENMASK(11, 8), 70 + .sram_pdn_ack_bits = GENMASK(15, 12), 71 + }, 72 + [MT6795_POWER_DOMAIN_MFG_ASYNC] = { 73 + .name = "mfg_async", 74 + .sta_mask = PWR_STATUS_MFG_ASYNC, 75 + .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 76 + .pwr_sta_offs = SPM_PWR_STATUS, 77 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 78 + .sram_pdn_bits = GENMASK(11, 8), 79 + .sram_pdn_ack_bits = 0, 80 + }, 81 + [MT6795_POWER_DOMAIN_MFG_2D] = { 82 + .name = "mfg_2d", 83 + .sta_mask = PWR_STATUS_MFG_2D, 84 + .ctl_offs = SPM_MFG_2D_PWR_CON, 85 + .pwr_sta_offs = SPM_PWR_STATUS, 86 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 87 + .sram_pdn_bits = GENMASK(11, 8), 88 + .sram_pdn_ack_bits = GENMASK(13, 12), 89 + }, 90 + [MT6795_POWER_DOMAIN_MFG] = { 91 + .name = "mfg", 92 + .sta_mask = PWR_STATUS_MFG, 93 + .ctl_offs = SPM_MFG_PWR_CON, 94 + .pwr_sta_offs = SPM_PWR_STATUS, 95 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 96 + .sram_pdn_bits = GENMASK(13, 8), 97 + .sram_pdn_ack_bits = GENMASK(21, 16), 98 + .bp_infracfg = { 99 + BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S | 100 + MT8173_TOP_AXI_PROT_EN_MFG_M0 | 101 + MT8173_TOP_AXI_PROT_EN_MFG_M1 | 102 + MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT), 103 + }, 104 + }, 105 + }; 106 + 107 + static const struct scpsys_soc_data mt6795_scpsys_data = { 108 + .domains_data = scpsys_domain_data_mt6795, 109 + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt6795), 110 + }; 111 + 112 + #endif /* __SOC_MEDIATEK_MT6795_PM_DOMAINS_H */
+1
drivers/soc/mediatek/mt8183-pm-domains.h
··· 41 41 .pwr_sta2nd_offs = 0x0184, 42 42 .sram_pdn_bits = 0, 43 43 .sram_pdn_ack_bits = 0, 44 + .caps = MTK_SCPD_DOMAIN_SUPPLY, 44 45 }, 45 46 [MT8183_POWER_DOMAIN_MFG] = { 46 47 .name = "mfg",
+1 -1
drivers/soc/mediatek/mt8186-pm-domains.h
··· 51 51 MT8186_TOP_AXI_PROT_EN_1_CLR, 52 52 MT8186_TOP_AXI_PROT_EN_1_STA), 53 53 }, 54 - .caps = MTK_SCPD_KEEP_DEFAULT_OFF, 54 + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, 55 55 }, 56 56 [MT8186_POWER_DOMAIN_MFG2] = { 57 57 .name = "mfg2",
+2
drivers/soc/mediatek/mt8192-pm-domains.h
··· 58 58 .pwr_sta2nd_offs = 0x0170, 59 59 .sram_pdn_bits = GENMASK(8, 8), 60 60 .sram_pdn_ack_bits = GENMASK(12, 12), 61 + .caps = MTK_SCPD_DOMAIN_SUPPLY, 61 62 }, 62 63 [MT8192_POWER_DOMAIN_MFG1] = { 63 64 .name = "mfg1", ··· 86 85 MT8192_TOP_AXI_PROT_EN_2_CLR, 87 86 MT8192_TOP_AXI_PROT_EN_2_STA1), 88 87 }, 88 + .caps = MTK_SCPD_DOMAIN_SUPPLY, 89 89 }, 90 90 [MT8192_POWER_DOMAIN_MFG2] = { 91 91 .name = "mfg2",
+2 -2
drivers/soc/mediatek/mt8195-pm-domains.h
··· 67 67 .ctl_offs = 0x334, 68 68 .pwr_sta_offs = 0x174, 69 69 .pwr_sta2nd_offs = 0x178, 70 - .caps = MTK_SCPD_ACTIVE_WAKEUP, 70 + .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_ALWAYS_ON, 71 71 }, 72 72 [MT8195_POWER_DOMAIN_CSI_RX_TOP] = { 73 73 .name = "csi_rx_top", ··· 162 162 MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, 163 163 MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1), 164 164 }, 165 - .caps = MTK_SCPD_KEEP_DEFAULT_OFF, 165 + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, 166 166 }, 167 167 [MT8195_POWER_DOMAIN_MFG2] = { 168 168 .name = "mfg2",
+22
drivers/soc/mediatek/mt8365-mmsys.h
··· 10 10 #define MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN 0xf60 11 11 #define MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN 0xf64 12 12 #define MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN 0xf68 13 + #define MT8365_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL 0xfd0 14 + #define MT8365_DISP_REG_CONFIG_DISP_DPI0_SEL_IN 0xfd8 15 + #define MT8365_DISP_REG_CONFIG_DISP_LVDS_SYS_CFG_00 0xfdc 13 16 14 17 #define MT8365_RDMA0_SOUT_COLOR0 0x1 15 18 #define MT8365_DITHER_MOUT_EN_DSI0 0x1 ··· 21 18 #define MT8365_RDMA0_RSZ0_SEL_IN_RDMA0 0x0 22 19 #define MT8365_DISP_COLOR_SEL_IN_COLOR0 0x0 23 20 #define MT8365_OVL0_MOUT_PATH0_SEL BIT(0) 21 + #define MT8365_RDMA1_SOUT_DPI0 0x1 22 + #define MT8365_DPI0_SEL_IN_RDMA1 0x0 23 + #define MT8365_LVDS_SYS_CFG_00_SEL_LVDS_PXL_CLK 0x1 24 + #define MT8365_DPI0_SEL_IN_RDMA1 0x0 24 25 25 26 static const struct mtk_mmsys_routes mt8365_mmsys_routing_table[] = { 26 27 { ··· 61 54 DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0, 62 55 MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN, 63 56 MT8365_RDMA0_RSZ0_SEL_IN_RDMA0, MT8365_RDMA0_RSZ0_SEL_IN_RDMA0 57 + }, 58 + { 59 + DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, 60 + MT8365_DISP_REG_CONFIG_DISP_LVDS_SYS_CFG_00, 61 + MT8365_LVDS_SYS_CFG_00_SEL_LVDS_PXL_CLK, MT8365_LVDS_SYS_CFG_00_SEL_LVDS_PXL_CLK 62 + }, 63 + { 64 + DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, 65 + MT8365_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, 66 + MT8365_DPI0_SEL_IN_RDMA1, MT8365_DPI0_SEL_IN_RDMA1 67 + }, 68 + { 69 + DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, 70 + MT8365_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL, 71 + MT8365_RDMA1_SOUT_DPI0, MT8365_RDMA1_SOUT_DPI0 64 72 }, 65 73 }; 66 74
+30 -15
drivers/soc/mediatek/mtk-devapc.c
··· 31 31 u32 vio_dbg1; 32 32 }; 33 33 34 - struct mtk_devapc_data { 35 - /* numbers of violation index */ 36 - u32 vio_idx_num; 37 - 34 + struct mtk_devapc_regs_ofs { 38 35 /* reg offset */ 39 36 u32 vio_mask_offset; 40 37 u32 vio_sta_offset; ··· 41 44 u32 vio_shift_sta_offset; 42 45 u32 vio_shift_sel_offset; 43 46 u32 vio_shift_con_offset; 47 + }; 48 + 49 + struct mtk_devapc_data { 50 + /* numbers of violation index */ 51 + u32 vio_idx_num; 52 + const struct mtk_devapc_regs_ofs *regs_ofs; 44 53 }; 45 54 46 55 struct mtk_devapc_context { ··· 61 58 void __iomem *reg; 62 59 int i; 63 60 64 - reg = ctx->infra_base + ctx->data->vio_sta_offset; 61 + reg = ctx->infra_base + ctx->data->regs_ofs->vio_sta_offset; 65 62 66 63 for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++) 67 64 writel(GENMASK(31, 0), reg + 4 * i); ··· 76 73 u32 val; 77 74 int i; 78 75 79 - reg = ctx->infra_base + ctx->data->vio_mask_offset; 76 + reg = ctx->infra_base + ctx->data->regs_ofs->vio_mask_offset; 80 77 81 78 if (mask) 82 79 val = GENMASK(31, 0); ··· 119 116 u32 val; 120 117 121 118 pd_vio_shift_sta_reg = ctx->infra_base + 122 - ctx->data->vio_shift_sta_offset; 119 + ctx->data->regs_ofs->vio_shift_sta_offset; 123 120 pd_vio_shift_sel_reg = ctx->infra_base + 124 - ctx->data->vio_shift_sel_offset; 121 + ctx->data->regs_ofs->vio_shift_sel_offset; 125 122 pd_vio_shift_con_reg = ctx->infra_base + 126 - ctx->data->vio_shift_con_offset; 123 + ctx->data->regs_ofs->vio_shift_con_offset; 127 124 128 125 /* Find the minimum shift group which has violation */ 129 126 val = readl(pd_vio_shift_sta_reg); ··· 164 161 void __iomem *vio_dbg0_reg; 165 162 void __iomem *vio_dbg1_reg; 166 163 167 - vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset; 168 - vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset; 164 + vio_dbg0_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg0_offset; 165 + vio_dbg1_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg1_offset; 169 166 170 167 vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg); 171 168 vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg); ··· 203 200 */ 204 201 static void start_devapc(struct mtk_devapc_context *ctx) 205 202 { 206 - writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset); 203 + writel(BIT(31), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset); 207 204 208 205 mask_module_irq(ctx, false); 209 206 } ··· 215 212 { 216 213 mask_module_irq(ctx, true); 217 214 218 - writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset); 215 + writel(BIT(2), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset); 219 216 } 220 217 221 - static const struct mtk_devapc_data devapc_mt6779 = { 222 - .vio_idx_num = 511, 218 + static const struct mtk_devapc_regs_ofs devapc_regs_ofs_mt6779 = { 223 219 .vio_mask_offset = 0x0, 224 220 .vio_sta_offset = 0x400, 225 221 .vio_dbg0_offset = 0x900, ··· 229 227 .vio_shift_con_offset = 0xF20, 230 228 }; 231 229 230 + static const struct mtk_devapc_data devapc_mt6779 = { 231 + .vio_idx_num = 511, 232 + .regs_ofs = &devapc_regs_ofs_mt6779, 233 + }; 234 + 235 + static const struct mtk_devapc_data devapc_mt8186 = { 236 + .vio_idx_num = 519, 237 + .regs_ofs = &devapc_regs_ofs_mt6779, 238 + }; 239 + 232 240 static const struct of_device_id mtk_devapc_dt_match[] = { 233 241 { 234 242 .compatible = "mediatek,mt6779-devapc", 235 243 .data = &devapc_mt6779, 244 + }, { 245 + .compatible = "mediatek,mt8186-devapc", 246 + .data = &devapc_mt8186, 236 247 }, { 237 248 }, 238 249 };
+153 -2
drivers/soc/mediatek/mtk-mutex.c
··· 7 7 #include <linux/iopoll.h> 8 8 #include <linux/module.h> 9 9 #include <linux/of_device.h> 10 + #include <linux/of_address.h> 10 11 #include <linux/platform_device.h> 11 12 #include <linux/regmap.h> 12 13 #include <linux/soc/mediatek/mtk-mmsys.h> 13 14 #include <linux/soc/mediatek/mtk-mutex.h> 15 + #include <linux/soc/mediatek/mtk-cmdq.h> 14 16 15 17 #define MT2701_MUTEX0_MOD0 0x2c 16 18 #define MT2701_MUTEX0_SOF0 0x30 ··· 82 80 #define MT8183_MUTEX_MOD_DISP_GAMMA0 16 83 81 #define MT8183_MUTEX_MOD_DISP_DITHER0 17 84 82 83 + #define MT8183_MUTEX_MOD_MDP_RDMA0 2 84 + #define MT8183_MUTEX_MOD_MDP_RSZ0 4 85 + #define MT8183_MUTEX_MOD_MDP_RSZ1 5 86 + #define MT8183_MUTEX_MOD_MDP_TDSHP0 6 87 + #define MT8183_MUTEX_MOD_MDP_WROT0 7 88 + #define MT8183_MUTEX_MOD_MDP_WDMA 8 89 + #define MT8183_MUTEX_MOD_MDP_AAL0 23 90 + #define MT8183_MUTEX_MOD_MDP_CCORR0 24 91 + 85 92 #define MT8173_MUTEX_MOD_DISP_OVL0 11 86 93 #define MT8173_MUTEX_MOD_DISP_OVL1 12 87 94 #define MT8173_MUTEX_MOD_DISP_RDMA0 13 ··· 120 109 #define MT8195_MUTEX_MOD_DISP_VPP_MERGE 20 121 110 #define MT8195_MUTEX_MOD_DISP_DP_INTF0 21 122 111 #define MT8195_MUTEX_MOD_DISP_PWM0 27 112 + 113 + #define MT8365_MUTEX_MOD_DISP_OVL0 7 114 + #define MT8365_MUTEX_MOD_DISP_OVL0_2L 8 115 + #define MT8365_MUTEX_MOD_DISP_RDMA0 9 116 + #define MT8365_MUTEX_MOD_DISP_RDMA1 10 117 + #define MT8365_MUTEX_MOD_DISP_WDMA0 11 118 + #define MT8365_MUTEX_MOD_DISP_COLOR0 12 119 + #define MT8365_MUTEX_MOD_DISP_CCORR 13 120 + #define MT8365_MUTEX_MOD_DISP_AAL 14 121 + #define MT8365_MUTEX_MOD_DISP_GAMMA 15 122 + #define MT8365_MUTEX_MOD_DISP_DITHER 16 123 + #define MT8365_MUTEX_MOD_DISP_DSI0 17 124 + #define MT8365_MUTEX_MOD_DISP_PWM0 20 125 + #define MT8365_MUTEX_MOD_DISP_DPI0 22 123 126 124 127 #define MT2712_MUTEX_MOD_DISP_PWM2 10 125 128 #define MT2712_MUTEX_MOD_DISP_OVL0 11 ··· 210 185 const unsigned int *mutex_sof; 211 186 const unsigned int mutex_mod_reg; 212 187 const unsigned int mutex_sof_reg; 188 + const unsigned int *mutex_table_mod; 213 189 const bool no_clk; 214 190 }; 215 191 ··· 220 194 void __iomem *regs; 221 195 struct mtk_mutex mutex[10]; 222 196 const struct mtk_mutex_data *data; 197 + phys_addr_t addr; 198 + struct cmdq_client_reg cmdq_reg; 223 199 }; 224 200 225 201 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { ··· 300 272 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0, 301 273 }; 302 274 275 + static const unsigned int mt8183_mutex_table_mod[MUTEX_MOD_IDX_MAX] = { 276 + [MUTEX_MOD_IDX_MDP_RDMA0] = MT8183_MUTEX_MOD_MDP_RDMA0, 277 + [MUTEX_MOD_IDX_MDP_RSZ0] = MT8183_MUTEX_MOD_MDP_RSZ0, 278 + [MUTEX_MOD_IDX_MDP_RSZ1] = MT8183_MUTEX_MOD_MDP_RSZ1, 279 + [MUTEX_MOD_IDX_MDP_TDSHP0] = MT8183_MUTEX_MOD_MDP_TDSHP0, 280 + [MUTEX_MOD_IDX_MDP_WROT0] = MT8183_MUTEX_MOD_MDP_WROT0, 281 + [MUTEX_MOD_IDX_MDP_WDMA] = MT8183_MUTEX_MOD_MDP_WDMA, 282 + [MUTEX_MOD_IDX_MDP_AAL0] = MT8183_MUTEX_MOD_MDP_AAL0, 283 + [MUTEX_MOD_IDX_MDP_CCORR0] = MT8183_MUTEX_MOD_MDP_CCORR0, 284 + }; 285 + 303 286 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { 304 287 [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0, 305 288 [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0, ··· 352 313 [DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0, 353 314 [DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0, 354 315 [DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0, 316 + }; 317 + 318 + static const unsigned int mt8365_mutex_mod[DDP_COMPONENT_ID_MAX] = { 319 + [DDP_COMPONENT_AAL0] = MT8365_MUTEX_MOD_DISP_AAL, 320 + [DDP_COMPONENT_CCORR] = MT8365_MUTEX_MOD_DISP_CCORR, 321 + [DDP_COMPONENT_COLOR0] = MT8365_MUTEX_MOD_DISP_COLOR0, 322 + [DDP_COMPONENT_DITHER0] = MT8365_MUTEX_MOD_DISP_DITHER, 323 + [DDP_COMPONENT_DPI0] = MT8365_MUTEX_MOD_DISP_DPI0, 324 + [DDP_COMPONENT_DSI0] = MT8365_MUTEX_MOD_DISP_DSI0, 325 + [DDP_COMPONENT_GAMMA] = MT8365_MUTEX_MOD_DISP_GAMMA, 326 + [DDP_COMPONENT_OVL0] = MT8365_MUTEX_MOD_DISP_OVL0, 327 + [DDP_COMPONENT_OVL_2L0] = MT8365_MUTEX_MOD_DISP_OVL0_2L, 328 + [DDP_COMPONENT_PWM0] = MT8365_MUTEX_MOD_DISP_PWM0, 329 + [DDP_COMPONENT_RDMA0] = MT8365_MUTEX_MOD_DISP_RDMA0, 330 + [DDP_COMPONENT_RDMA1] = MT8365_MUTEX_MOD_DISP_RDMA1, 331 + [DDP_COMPONENT_WDMA0] = MT8365_MUTEX_MOD_DISP_WDMA0, 355 332 }; 356 333 357 334 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = { ··· 454 399 .mutex_sof = mt8183_mutex_sof, 455 400 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 456 401 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 402 + .mutex_table_mod = mt8183_mutex_table_mod, 457 403 .no_clk = true, 458 404 }; 459 405 ··· 477 421 .mutex_sof = mt8195_mutex_sof, 478 422 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 479 423 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 424 + }; 425 + 426 + static const struct mtk_mutex_data mt8365_mutex_driver_data = { 427 + .mutex_mod = mt8365_mutex_mod, 428 + .mutex_sof = mt8183_mutex_sof, 429 + .mutex_mod_reg = MT8183_MUTEX0_MOD0, 430 + .mutex_sof_reg = MT8183_MUTEX0_SOF0, 431 + .no_clk = true, 480 432 }; 481 433 482 434 struct mtk_mutex *mtk_mutex_get(struct device *dev) ··· 636 572 } 637 573 EXPORT_SYMBOL_GPL(mtk_mutex_enable); 638 574 575 + int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt) 576 + { 577 + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 578 + mutex[mutex->id]); 579 + #if IS_REACHABLE(CONFIG_MTK_CMDQ) 580 + struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt; 581 + 582 + WARN_ON(&mtx->mutex[mutex->id] != mutex); 583 + 584 + if (!mtx->cmdq_reg.size) { 585 + dev_err(mtx->dev, "mediatek,gce-client-reg hasn't been set"); 586 + return -EINVAL; 587 + } 588 + 589 + cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys, 590 + mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1); 591 + return 0; 592 + #else 593 + dev_err(mtx->dev, "Not support for enable MUTEX by CMDQ"); 594 + return -ENODEV; 595 + #endif 596 + } 597 + EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq); 598 + 639 599 void mtk_mutex_disable(struct mtk_mutex *mutex) 640 600 { 641 601 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, ··· 694 606 } 695 607 EXPORT_SYMBOL_GPL(mtk_mutex_release); 696 608 609 + int mtk_mutex_write_mod(struct mtk_mutex *mutex, 610 + enum mtk_mutex_mod_index idx, bool clear) 611 + { 612 + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 613 + mutex[mutex->id]); 614 + unsigned int reg; 615 + unsigned int offset; 616 + 617 + WARN_ON(&mtx->mutex[mutex->id] != mutex); 618 + 619 + if (idx < MUTEX_MOD_IDX_MDP_RDMA0 || 620 + idx >= MUTEX_MOD_IDX_MAX) { 621 + dev_err(mtx->dev, "Not supported MOD table index : %d", idx); 622 + return -EINVAL; 623 + } 624 + 625 + offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 626 + mutex->id); 627 + reg = readl_relaxed(mtx->regs + offset); 628 + 629 + if (clear) 630 + reg &= ~BIT(mtx->data->mutex_table_mod[idx]); 631 + else 632 + reg |= BIT(mtx->data->mutex_table_mod[idx]); 633 + 634 + writel_relaxed(reg, mtx->regs + offset); 635 + 636 + return 0; 637 + } 638 + EXPORT_SYMBOL_GPL(mtk_mutex_write_mod); 639 + 640 + int mtk_mutex_write_sof(struct mtk_mutex *mutex, 641 + enum mtk_mutex_sof_index idx) 642 + { 643 + struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 644 + mutex[mutex->id]); 645 + 646 + WARN_ON(&mtx->mutex[mutex->id] != mutex); 647 + 648 + if (idx < MUTEX_SOF_IDX_SINGLE_MODE || 649 + idx >= MUTEX_SOF_IDX_MAX) { 650 + dev_err(mtx->dev, "Not supported SOF index : %d", idx); 651 + return -EINVAL; 652 + } 653 + 654 + writel_relaxed(idx, mtx->regs + 655 + DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id)); 656 + 657 + return 0; 658 + } 659 + EXPORT_SYMBOL_GPL(mtk_mutex_write_sof); 660 + 697 661 static int mtk_mutex_probe(struct platform_device *pdev) 698 662 { 699 663 struct device *dev = &pdev->dev; 700 664 struct mtk_mutex_ctx *mtx; 701 665 struct resource *regs; 702 666 int i; 667 + #if IS_REACHABLE(CONFIG_MTK_CMDQ) 668 + int ret; 669 + #endif 703 670 704 671 mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); 705 672 if (!mtx) ··· 774 631 } 775 632 } 776 633 777 - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 778 - mtx->regs = devm_ioremap_resource(dev, regs); 634 + mtx->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &regs); 779 635 if (IS_ERR(mtx->regs)) { 780 636 dev_err(dev, "Failed to map mutex registers\n"); 781 637 return PTR_ERR(mtx->regs); 782 638 } 639 + mtx->addr = regs->start; 640 + 641 + #if IS_REACHABLE(CONFIG_MTK_CMDQ) 642 + ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0); 643 + if (ret) 644 + dev_dbg(dev, "No mediatek,gce-client-reg!\n"); 645 + #endif 783 646 784 647 platform_set_drvdata(pdev, mtx); 785 648 ··· 814 665 .data = &mt8192_mutex_driver_data}, 815 666 { .compatible = "mediatek,mt8195-disp-mutex", 816 667 .data = &mt8195_mutex_driver_data}, 668 + { .compatible = "mediatek,mt8365-disp-mutex", 669 + .data = &mt8365_mutex_driver_data}, 817 670 {}, 818 671 }; 819 672 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
+8
drivers/soc/mediatek/mtk-pm-domains.c
··· 16 16 #include <linux/regulator/consumer.h> 17 17 #include <linux/soc/mediatek/infracfg.h> 18 18 19 + #include "mt6795-pm-domains.h" 19 20 #include "mt8167-pm-domains.h" 20 21 #include "mt8173-pm-domains.h" 21 22 #include "mt8183-pm-domains.h" ··· 429 428 dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret); 430 429 goto err_put_subsys_clocks; 431 430 } 431 + 432 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_ALWAYS_ON)) 433 + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; 432 434 } 433 435 434 436 if (scpsys->domains[id]) { ··· 559 555 } 560 556 561 557 static const struct of_device_id scpsys_of_match[] = { 558 + { 559 + .compatible = "mediatek,mt6795-power-controller", 560 + .data = &mt6795_scpsys_data, 561 + }, 562 562 { 563 563 .compatible = "mediatek,mt8167-power-controller", 564 564 .data = &mt8167_scpsys_data,
+2
drivers/soc/mediatek/mtk-pm-domains.h
··· 8 8 #define MTK_SCPD_SRAM_ISO BIT(2) 9 9 #define MTK_SCPD_KEEP_DEFAULT_OFF BIT(3) 10 10 #define MTK_SCPD_DOMAIN_SUPPLY BIT(4) 11 + /* can't set MTK_SCPD_KEEP_DEFAULT_OFF at the same time */ 12 + #define MTK_SCPD_ALWAYS_ON BIT(5) 11 13 #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) 12 14 13 15 #define SPM_VDE_PWR_CON 0x0210
+97 -128
drivers/soc/mediatek/mtk-pmic-wrap.c
··· 13 13 #include <linux/regmap.h> 14 14 #include <linux/reset.h> 15 15 16 + #define PWRAP_POLL_DELAY_US 10 17 + #define PWRAP_POLL_TIMEOUT_US 10000 18 + 16 19 #define PWRAP_MT8135_BRIDGE_IORD_ARB_EN 0x4 17 20 #define PWRAP_MT8135_BRIDGE_WACS3_EN 0x10 18 21 #define PWRAP_MT8135_BRIDGE_INIT_DONE3 0x14 ··· 1143 1140 }; 1144 1141 1145 1142 struct pmic_wrapper; 1146 - struct pwrap_slv_type { 1147 - const u32 *dew_regs; 1148 - enum pmic_type type; 1143 + 1144 + struct pwrap_slv_regops { 1149 1145 const struct regmap_config *regmap; 1150 - /* Flags indicating the capability for the target slave */ 1151 - u32 caps; 1152 1146 /* 1153 1147 * pwrap operations are highly associated with the PMIC types, 1154 1148 * so the pointers added increases flexibility allowing determination ··· 1153 1153 */ 1154 1154 int (*pwrap_read)(struct pmic_wrapper *wrp, u32 adr, u32 *rdata); 1155 1155 int (*pwrap_write)(struct pmic_wrapper *wrp, u32 adr, u32 wdata); 1156 + }; 1157 + 1158 + struct pwrap_slv_type { 1159 + const u32 *dew_regs; 1160 + enum pmic_type type; 1161 + const struct pwrap_slv_regops *regops; 1162 + /* Flags indicating the capability for the target slave */ 1163 + u32 caps; 1156 1164 }; 1157 1165 1158 1166 struct pmic_wrapper { ··· 1249 1241 (val & PWRAP_STATE_SYNC_IDLE0); 1250 1242 } 1251 1243 1252 - static int pwrap_wait_for_state(struct pmic_wrapper *wrp, 1253 - bool (*fp)(struct pmic_wrapper *)) 1254 - { 1255 - unsigned long timeout; 1256 - 1257 - timeout = jiffies + usecs_to_jiffies(10000); 1258 - 1259 - do { 1260 - if (time_after(jiffies, timeout)) 1261 - return fp(wrp) ? 0 : -ETIMEDOUT; 1262 - if (fp(wrp)) 1263 - return 0; 1264 - } while (1); 1265 - } 1266 - 1267 1244 static int pwrap_read16(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) 1268 1245 { 1246 + bool tmp; 1269 1247 int ret; 1270 1248 u32 val; 1271 1249 1272 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); 1250 + ret = readx_poll_timeout(pwrap_is_fsm_idle, wrp, tmp, tmp, 1251 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1273 1252 if (ret) { 1274 1253 pwrap_leave_fsm_vldclr(wrp); 1275 1254 return ret; ··· 1268 1273 val = (adr >> 1) << 16; 1269 1274 pwrap_writel(wrp, val, PWRAP_WACS2_CMD); 1270 1275 1271 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr); 1276 + ret = readx_poll_timeout(pwrap_is_fsm_vldclr, wrp, tmp, tmp, 1277 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1272 1278 if (ret) 1273 1279 return ret; 1274 1280 ··· 1286 1290 1287 1291 static int pwrap_read32(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) 1288 1292 { 1293 + bool tmp; 1289 1294 int ret, msb; 1290 1295 1291 1296 *rdata = 0; 1292 1297 for (msb = 0; msb < 2; msb++) { 1293 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); 1298 + ret = readx_poll_timeout(pwrap_is_fsm_idle, wrp, tmp, tmp, 1299 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1300 + 1294 1301 if (ret) { 1295 1302 pwrap_leave_fsm_vldclr(wrp); 1296 1303 return ret; ··· 1302 1303 pwrap_writel(wrp, ((msb << 30) | (adr << 16)), 1303 1304 PWRAP_WACS2_CMD); 1304 1305 1305 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr); 1306 + ret = readx_poll_timeout(pwrap_is_fsm_vldclr, wrp, tmp, tmp, 1307 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1306 1308 if (ret) 1307 1309 return ret; 1308 1310 ··· 1318 1318 1319 1319 static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) 1320 1320 { 1321 - return wrp->slave->pwrap_read(wrp, adr, rdata); 1321 + return wrp->slave->regops->pwrap_read(wrp, adr, rdata); 1322 1322 } 1323 1323 1324 1324 static int pwrap_write16(struct pmic_wrapper *wrp, u32 adr, u32 wdata) 1325 1325 { 1326 + bool tmp; 1326 1327 int ret; 1327 1328 1328 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); 1329 + ret = readx_poll_timeout(pwrap_is_fsm_idle, wrp, tmp, tmp, 1330 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1329 1331 if (ret) { 1330 1332 pwrap_leave_fsm_vldclr(wrp); 1331 1333 return ret; ··· 1346 1344 1347 1345 static int pwrap_write32(struct pmic_wrapper *wrp, u32 adr, u32 wdata) 1348 1346 { 1347 + bool tmp; 1349 1348 int ret, msb, rdata; 1350 1349 1351 1350 for (msb = 0; msb < 2; msb++) { 1352 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); 1351 + ret = readx_poll_timeout(pwrap_is_fsm_idle, wrp, tmp, tmp, 1352 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1353 1353 if (ret) { 1354 1354 pwrap_leave_fsm_vldclr(wrp); 1355 1355 return ret; ··· 1377 1373 1378 1374 static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata) 1379 1375 { 1380 - return wrp->slave->pwrap_write(wrp, adr, wdata); 1376 + return wrp->slave->regops->pwrap_write(wrp, adr, wdata); 1381 1377 } 1382 1378 1383 1379 static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata) ··· 1392 1388 1393 1389 static int pwrap_reset_spislave(struct pmic_wrapper *wrp) 1394 1390 { 1391 + bool tmp; 1395 1392 int ret, i; 1396 1393 1397 1394 pwrap_writel(wrp, 0, PWRAP_HIPRIO_ARB_EN); ··· 1412 1407 pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_OUTS, 1413 1408 PWRAP_MAN_CMD); 1414 1409 1415 - ret = pwrap_wait_for_state(wrp, pwrap_is_sync_idle); 1410 + ret = readx_poll_timeout(pwrap_is_sync_idle, wrp, tmp, tmp, 1411 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1416 1412 if (ret) { 1417 1413 dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret); 1418 1414 return ret; ··· 1464 1458 static int pwrap_init_dual_io(struct pmic_wrapper *wrp) 1465 1459 { 1466 1460 int ret; 1461 + bool tmp; 1467 1462 u32 rdata; 1468 1463 1469 1464 /* Enable dual IO mode */ 1470 1465 pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1); 1471 1466 1472 1467 /* Check IDLE & INIT_DONE in advance */ 1473 - ret = pwrap_wait_for_state(wrp, 1474 - pwrap_is_fsm_idle_and_sync_idle); 1468 + ret = readx_poll_timeout(pwrap_is_fsm_idle_and_sync_idle, wrp, tmp, tmp, 1469 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1475 1470 if (ret) { 1476 1471 dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret); 1477 1472 return ret; ··· 1577 1570 static int pwrap_init_cipher(struct pmic_wrapper *wrp) 1578 1571 { 1579 1572 int ret; 1573 + bool tmp; 1580 1574 u32 rdata = 0; 1581 1575 1582 1576 pwrap_writel(wrp, 0x1, PWRAP_CIPHER_SWRST); ··· 1632 1624 } 1633 1625 1634 1626 /* wait for cipher data ready@AP */ 1635 - ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready); 1627 + ret = readx_poll_timeout(pwrap_is_cipher_ready, wrp, tmp, tmp, 1628 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1636 1629 if (ret) { 1637 1630 dev_err(wrp->dev, "cipher data ready@AP fail, ret=%d\n", ret); 1638 1631 return ret; 1639 1632 } 1640 1633 1641 1634 /* wait for cipher data ready@PMIC */ 1642 - ret = pwrap_wait_for_state(wrp, pwrap_is_pmic_cipher_ready); 1635 + ret = readx_poll_timeout(pwrap_is_pmic_cipher_ready, wrp, tmp, tmp, 1636 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1643 1637 if (ret) { 1644 1638 dev_err(wrp->dev, 1645 1639 "timeout waiting for cipher data ready@PMIC\n"); ··· 1650 1640 1651 1641 /* wait for cipher mode idle */ 1652 1642 pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_MODE], 0x1); 1653 - ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle); 1643 + ret = readx_poll_timeout(pwrap_is_fsm_idle_and_sync_idle, wrp, tmp, tmp, 1644 + PWRAP_POLL_DELAY_US, PWRAP_POLL_TIMEOUT_US); 1654 1645 if (ret) { 1655 1646 dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret); 1656 1647 return ret; ··· 1896 1885 .max_register = 0xffff, 1897 1886 }; 1898 1887 1888 + static const struct pwrap_slv_regops pwrap_regops16 = { 1889 + .pwrap_read = pwrap_read16, 1890 + .pwrap_write = pwrap_write16, 1891 + .regmap = &pwrap_regmap_config16, 1892 + }; 1893 + 1894 + static const struct pwrap_slv_regops pwrap_regops32 = { 1895 + .pwrap_read = pwrap_read32, 1896 + .pwrap_write = pwrap_write32, 1897 + .regmap = &pwrap_regmap_config32, 1898 + }; 1899 + 1899 1900 static const struct pwrap_slv_type pmic_mt6323 = { 1900 1901 .dew_regs = mt6323_regs, 1901 1902 .type = PMIC_MT6323, 1902 - .regmap = &pwrap_regmap_config16, 1903 + .regops = &pwrap_regops16, 1903 1904 .caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO | 1904 1905 PWRAP_SLV_CAP_SECURITY, 1905 - .pwrap_read = pwrap_read16, 1906 - .pwrap_write = pwrap_write16, 1907 1906 }; 1908 1907 1909 1908 static const struct pwrap_slv_type pmic_mt6351 = { 1910 1909 .dew_regs = mt6351_regs, 1911 1910 .type = PMIC_MT6351, 1912 - .regmap = &pwrap_regmap_config16, 1911 + .regops = &pwrap_regops16, 1913 1912 .caps = 0, 1914 - .pwrap_read = pwrap_read16, 1915 - .pwrap_write = pwrap_write16, 1916 1913 }; 1917 1914 1918 1915 static const struct pwrap_slv_type pmic_mt6357 = { 1919 1916 .dew_regs = mt6357_regs, 1920 1917 .type = PMIC_MT6357, 1921 - .regmap = &pwrap_regmap_config16, 1918 + .regops = &pwrap_regops16, 1922 1919 .caps = 0, 1923 - .pwrap_read = pwrap_read16, 1924 - .pwrap_write = pwrap_write16, 1925 1920 }; 1926 1921 1927 1922 static const struct pwrap_slv_type pmic_mt6358 = { 1928 1923 .dew_regs = mt6358_regs, 1929 1924 .type = PMIC_MT6358, 1930 - .regmap = &pwrap_regmap_config16, 1925 + .regops = &pwrap_regops16, 1931 1926 .caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO, 1932 - .pwrap_read = pwrap_read16, 1933 - .pwrap_write = pwrap_write16, 1934 1927 }; 1935 1928 1936 1929 static const struct pwrap_slv_type pmic_mt6359 = { 1937 1930 .dew_regs = mt6359_regs, 1938 1931 .type = PMIC_MT6359, 1939 - .regmap = &pwrap_regmap_config16, 1932 + .regops = &pwrap_regops16, 1940 1933 .caps = PWRAP_SLV_CAP_DUALIO, 1941 - .pwrap_read = pwrap_read16, 1942 - .pwrap_write = pwrap_write16, 1943 1934 }; 1944 1935 1945 1936 static const struct pwrap_slv_type pmic_mt6380 = { 1946 1937 .dew_regs = NULL, 1947 1938 .type = PMIC_MT6380, 1948 - .regmap = &pwrap_regmap_config32, 1939 + .regops = &pwrap_regops32, 1949 1940 .caps = 0, 1950 - .pwrap_read = pwrap_read32, 1951 - .pwrap_write = pwrap_write32, 1952 1941 }; 1953 1942 1954 1943 static const struct pwrap_slv_type pmic_mt6397 = { 1955 1944 .dew_regs = mt6397_regs, 1956 1945 .type = PMIC_MT6397, 1957 - .regmap = &pwrap_regmap_config16, 1946 + .regops = &pwrap_regops16, 1958 1947 .caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO | 1959 1948 PWRAP_SLV_CAP_SECURITY, 1960 - .pwrap_read = pwrap_read16, 1961 - .pwrap_write = pwrap_write16, 1962 1949 }; 1963 1950 1964 1951 static const struct of_device_id of_slave_match_tbl[] = { 1965 - { 1966 - .compatible = "mediatek,mt6323", 1967 - .data = &pmic_mt6323, 1968 - }, { 1969 - .compatible = "mediatek,mt6351", 1970 - .data = &pmic_mt6351, 1971 - }, { 1972 - .compatible = "mediatek,mt6357", 1973 - .data = &pmic_mt6357, 1974 - }, { 1975 - .compatible = "mediatek,mt6358", 1976 - .data = &pmic_mt6358, 1977 - }, { 1978 - .compatible = "mediatek,mt6359", 1979 - .data = &pmic_mt6359, 1980 - }, { 1981 - /* The MT6380 PMIC only implements a regulator, so we bind it 1982 - * directly instead of using a MFD. 1983 - */ 1984 - .compatible = "mediatek,mt6380-regulator", 1985 - .data = &pmic_mt6380, 1986 - }, { 1987 - .compatible = "mediatek,mt6397", 1988 - .data = &pmic_mt6397, 1989 - }, { 1990 - /* sentinel */ 1991 - } 1952 + { .compatible = "mediatek,mt6323", .data = &pmic_mt6323 }, 1953 + { .compatible = "mediatek,mt6351", .data = &pmic_mt6351 }, 1954 + { .compatible = "mediatek,mt6357", .data = &pmic_mt6357 }, 1955 + { .compatible = "mediatek,mt6358", .data = &pmic_mt6358 }, 1956 + { .compatible = "mediatek,mt6359", .data = &pmic_mt6359 }, 1957 + 1958 + /* The MT6380 PMIC only implements a regulator, so we bind it 1959 + * directly instead of using a MFD. 1960 + */ 1961 + { .compatible = "mediatek,mt6380-regulator", .data = &pmic_mt6380 }, 1962 + { .compatible = "mediatek,mt6397", .data = &pmic_mt6397 }, 1963 + { /* sentinel */ } 1992 1964 }; 1993 1965 MODULE_DEVICE_TABLE(of, of_slave_match_tbl); 1994 1966 ··· 2130 2136 }; 2131 2137 2132 2138 static const struct of_device_id of_pwrap_match_tbl[] = { 2133 - { 2134 - .compatible = "mediatek,mt2701-pwrap", 2135 - .data = &pwrap_mt2701, 2136 - }, { 2137 - .compatible = "mediatek,mt6765-pwrap", 2138 - .data = &pwrap_mt6765, 2139 - }, { 2140 - .compatible = "mediatek,mt6779-pwrap", 2141 - .data = &pwrap_mt6779, 2142 - }, { 2143 - .compatible = "mediatek,mt6797-pwrap", 2144 - .data = &pwrap_mt6797, 2145 - }, { 2146 - .compatible = "mediatek,mt6873-pwrap", 2147 - .data = &pwrap_mt6873, 2148 - }, { 2149 - .compatible = "mediatek,mt7622-pwrap", 2150 - .data = &pwrap_mt7622, 2151 - }, { 2152 - .compatible = "mediatek,mt8135-pwrap", 2153 - .data = &pwrap_mt8135, 2154 - }, { 2155 - .compatible = "mediatek,mt8173-pwrap", 2156 - .data = &pwrap_mt8173, 2157 - }, { 2158 - .compatible = "mediatek,mt8183-pwrap", 2159 - .data = &pwrap_mt8183, 2160 - }, { 2161 - .compatible = "mediatek,mt8186-pwrap", 2162 - .data = &pwrap_mt8186, 2163 - }, { 2164 - .compatible = "mediatek,mt8195-pwrap", 2165 - .data = &pwrap_mt8195, 2166 - }, { 2167 - .compatible = "mediatek,mt8516-pwrap", 2168 - .data = &pwrap_mt8516, 2169 - }, { 2170 - /* sentinel */ 2171 - } 2139 + { .compatible = "mediatek,mt2701-pwrap", .data = &pwrap_mt2701 }, 2140 + { .compatible = "mediatek,mt6765-pwrap", .data = &pwrap_mt6765 }, 2141 + { .compatible = "mediatek,mt6779-pwrap", .data = &pwrap_mt6779 }, 2142 + { .compatible = "mediatek,mt6797-pwrap", .data = &pwrap_mt6797 }, 2143 + { .compatible = "mediatek,mt6873-pwrap", .data = &pwrap_mt6873 }, 2144 + { .compatible = "mediatek,mt7622-pwrap", .data = &pwrap_mt7622 }, 2145 + { .compatible = "mediatek,mt8135-pwrap", .data = &pwrap_mt8135 }, 2146 + { .compatible = "mediatek,mt8173-pwrap", .data = &pwrap_mt8173 }, 2147 + { .compatible = "mediatek,mt8183-pwrap", .data = &pwrap_mt8183 }, 2148 + { .compatible = "mediatek,mt8186-pwrap", .data = &pwrap_mt8186 }, 2149 + { .compatible = "mediatek,mt8195-pwrap", .data = &pwrap_mt8195 }, 2150 + { .compatible = "mediatek,mt8516-pwrap", .data = &pwrap_mt8516 }, 2151 + { /* sentinel */ } 2172 2152 }; 2173 2153 MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); 2174 2154 ··· 2153 2185 struct pmic_wrapper *wrp; 2154 2186 struct device_node *np = pdev->dev.of_node; 2155 2187 const struct of_device_id *of_slave_id = NULL; 2156 - struct resource *res; 2157 2188 2158 2189 if (np->child) 2159 2190 of_slave_id = of_match_node(of_slave_match_tbl, np->child); ··· 2172 2205 wrp->slave = of_slave_id->data; 2173 2206 wrp->dev = &pdev->dev; 2174 2207 2175 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap"); 2176 - wrp->base = devm_ioremap_resource(wrp->dev, res); 2208 + wrp->base = devm_platform_ioremap_resource_byname(pdev, "pwrap"); 2177 2209 if (IS_ERR(wrp->base)) 2178 2210 return PTR_ERR(wrp->base); 2179 2211 ··· 2186 2220 } 2187 2221 2188 2222 if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) { 2189 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 2190 - "pwrap-bridge"); 2191 - wrp->bridge_base = devm_ioremap_resource(wrp->dev, res); 2223 + wrp->bridge_base = devm_platform_ioremap_resource_byname(pdev, "pwrap-bridge"); 2192 2224 if (IS_ERR(wrp->bridge_base)) 2193 2225 return PTR_ERR(wrp->bridge_base); 2194 2226 ··· 2279 2315 pwrap_writel(wrp, wrp->master->int1_en_all, PWRAP_INT1_EN); 2280 2316 2281 2317 irq = platform_get_irq(pdev, 0); 2318 + if (irq < 0) { 2319 + ret = irq; 2320 + goto err_out2; 2321 + } 2322 + 2282 2323 ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, 2283 2324 IRQF_TRIGGER_HIGH, 2284 2325 "mt-pmic-pwrap", wrp); 2285 2326 if (ret) 2286 2327 goto err_out2; 2287 2328 2288 - wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, wrp->slave->regmap); 2329 + wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, wrp->slave->regops->regmap); 2289 2330 if (IS_ERR(wrp->regmap)) { 2290 2331 ret = PTR_ERR(wrp->regmap); 2291 2332 goto err_out2;
+2403
drivers/soc/mediatek/mtk-svs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2022 MediaTek Inc. 4 + */ 5 + 6 + #include <linux/bits.h> 7 + #include <linux/clk.h> 8 + #include <linux/completion.h> 9 + #include <linux/cpuidle.h> 10 + #include <linux/debugfs.h> 11 + #include <linux/device.h> 12 + #include <linux/init.h> 13 + #include <linux/interrupt.h> 14 + #include <linux/kernel.h> 15 + #include <linux/kthread.h> 16 + #include <linux/module.h> 17 + #include <linux/mutex.h> 18 + #include <linux/nvmem-consumer.h> 19 + #include <linux/of_address.h> 20 + #include <linux/of_irq.h> 21 + #include <linux/of_platform.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/pm_domain.h> 24 + #include <linux/pm_opp.h> 25 + #include <linux/pm_runtime.h> 26 + #include <linux/regulator/consumer.h> 27 + #include <linux/reset.h> 28 + #include <linux/seq_file.h> 29 + #include <linux/slab.h> 30 + #include <linux/spinlock.h> 31 + #include <linux/thermal.h> 32 + 33 + /* svs bank 1-line software id */ 34 + #define SVSB_CPU_LITTLE BIT(0) 35 + #define SVSB_CPU_BIG BIT(1) 36 + #define SVSB_CCI BIT(2) 37 + #define SVSB_GPU BIT(3) 38 + 39 + /* svs bank 2-line type */ 40 + #define SVSB_LOW BIT(8) 41 + #define SVSB_HIGH BIT(9) 42 + 43 + /* svs bank mode support */ 44 + #define SVSB_MODE_ALL_DISABLE 0 45 + #define SVSB_MODE_INIT01 BIT(1) 46 + #define SVSB_MODE_INIT02 BIT(2) 47 + #define SVSB_MODE_MON BIT(3) 48 + 49 + /* svs bank volt flags */ 50 + #define SVSB_INIT01_PD_REQ BIT(0) 51 + #define SVSB_INIT01_VOLT_IGNORE BIT(1) 52 + #define SVSB_INIT01_VOLT_INC_ONLY BIT(2) 53 + #define SVSB_MON_VOLT_IGNORE BIT(16) 54 + #define SVSB_REMOVE_DVTFIXED_VOLT BIT(24) 55 + 56 + /* svs bank register common configuration */ 57 + #define SVSB_DET_MAX 0xffff 58 + #define SVSB_DET_WINDOW 0xa28 59 + #define SVSB_DTHI 0x1 60 + #define SVSB_DTLO 0xfe 61 + #define SVSB_EN_INIT01 0x1 62 + #define SVSB_EN_INIT02 0x5 63 + #define SVSB_EN_MON 0x2 64 + #define SVSB_EN_OFF 0x0 65 + #define SVSB_INTEN_INIT0x 0x00005f01 66 + #define SVSB_INTEN_MONVOPEN 0x00ff0000 67 + #define SVSB_INTSTS_CLEAN 0x00ffffff 68 + #define SVSB_INTSTS_COMPLETE 0x1 69 + #define SVSB_INTSTS_MONVOP 0x00ff0000 70 + #define SVSB_RUNCONFIG_DEFAULT 0x80000000 71 + 72 + /* svs bank related setting */ 73 + #define BITS8 8 74 + #define MAX_OPP_ENTRIES 16 75 + #define REG_BYTES 4 76 + #define SVSB_DC_SIGNED_BIT BIT(15) 77 + #define SVSB_DET_CLK_EN BIT(31) 78 + #define SVSB_TEMP_LOWER_BOUND 0xb2 79 + #define SVSB_TEMP_UPPER_BOUND 0x64 80 + 81 + static DEFINE_SPINLOCK(svs_lock); 82 + 83 + #define debug_fops_ro(name) \ 84 + static int svs_##name##_debug_open(struct inode *inode, \ 85 + struct file *filp) \ 86 + { \ 87 + return single_open(filp, svs_##name##_debug_show, \ 88 + inode->i_private); \ 89 + } \ 90 + static const struct file_operations svs_##name##_debug_fops = { \ 91 + .owner = THIS_MODULE, \ 92 + .open = svs_##name##_debug_open, \ 93 + .read = seq_read, \ 94 + .llseek = seq_lseek, \ 95 + .release = single_release, \ 96 + } 97 + 98 + #define debug_fops_rw(name) \ 99 + static int svs_##name##_debug_open(struct inode *inode, \ 100 + struct file *filp) \ 101 + { \ 102 + return single_open(filp, svs_##name##_debug_show, \ 103 + inode->i_private); \ 104 + } \ 105 + static const struct file_operations svs_##name##_debug_fops = { \ 106 + .owner = THIS_MODULE, \ 107 + .open = svs_##name##_debug_open, \ 108 + .read = seq_read, \ 109 + .write = svs_##name##_debug_write, \ 110 + .llseek = seq_lseek, \ 111 + .release = single_release, \ 112 + } 113 + 114 + #define svs_dentry_data(name) {__stringify(name), &svs_##name##_debug_fops} 115 + 116 + /** 117 + * enum svsb_phase - svs bank phase enumeration 118 + * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition 119 + * @SVSB_PHASE_INIT01: svs bank basic init for data calibration 120 + * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table 121 + * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect 122 + * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose) 123 + * 124 + * Each svs bank has its own independent phase and we enable each svs bank by 125 + * running their phase orderly. However, when svs bank encounters unexpected 126 + * condition, it will fire an irq (PHASE_ERROR) to inform svs software. 127 + * 128 + * svs bank general phase-enabled order: 129 + * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON 130 + */ 131 + enum svsb_phase { 132 + SVSB_PHASE_ERROR = 0, 133 + SVSB_PHASE_INIT01, 134 + SVSB_PHASE_INIT02, 135 + SVSB_PHASE_MON, 136 + SVSB_PHASE_MAX, 137 + }; 138 + 139 + enum svs_reg_index { 140 + DESCHAR = 0, 141 + TEMPCHAR, 142 + DETCHAR, 143 + AGECHAR, 144 + DCCONFIG, 145 + AGECONFIG, 146 + FREQPCT30, 147 + FREQPCT74, 148 + LIMITVALS, 149 + VBOOT, 150 + DETWINDOW, 151 + CONFIG, 152 + TSCALCS, 153 + RUNCONFIG, 154 + SVSEN, 155 + INIT2VALS, 156 + DCVALUES, 157 + AGEVALUES, 158 + VOP30, 159 + VOP74, 160 + TEMP, 161 + INTSTS, 162 + INTSTSRAW, 163 + INTEN, 164 + CHKINT, 165 + CHKSHIFT, 166 + STATUS, 167 + VDESIGN30, 168 + VDESIGN74, 169 + DVT30, 170 + DVT74, 171 + AGECOUNT, 172 + SMSTATE0, 173 + SMSTATE1, 174 + CTL0, 175 + DESDETSEC, 176 + TEMPAGESEC, 177 + CTRLSPARE0, 178 + CTRLSPARE1, 179 + CTRLSPARE2, 180 + CTRLSPARE3, 181 + CORESEL, 182 + THERMINTST, 183 + INTST, 184 + THSTAGE0ST, 185 + THSTAGE1ST, 186 + THSTAGE2ST, 187 + THAHBST0, 188 + THAHBST1, 189 + SPARE0, 190 + SPARE1, 191 + SPARE2, 192 + SPARE3, 193 + THSLPEVEB, 194 + SVS_REG_MAX, 195 + }; 196 + 197 + static const u32 svs_regs_v2[] = { 198 + [DESCHAR] = 0xc00, 199 + [TEMPCHAR] = 0xc04, 200 + [DETCHAR] = 0xc08, 201 + [AGECHAR] = 0xc0c, 202 + [DCCONFIG] = 0xc10, 203 + [AGECONFIG] = 0xc14, 204 + [FREQPCT30] = 0xc18, 205 + [FREQPCT74] = 0xc1c, 206 + [LIMITVALS] = 0xc20, 207 + [VBOOT] = 0xc24, 208 + [DETWINDOW] = 0xc28, 209 + [CONFIG] = 0xc2c, 210 + [TSCALCS] = 0xc30, 211 + [RUNCONFIG] = 0xc34, 212 + [SVSEN] = 0xc38, 213 + [INIT2VALS] = 0xc3c, 214 + [DCVALUES] = 0xc40, 215 + [AGEVALUES] = 0xc44, 216 + [VOP30] = 0xc48, 217 + [VOP74] = 0xc4c, 218 + [TEMP] = 0xc50, 219 + [INTSTS] = 0xc54, 220 + [INTSTSRAW] = 0xc58, 221 + [INTEN] = 0xc5c, 222 + [CHKINT] = 0xc60, 223 + [CHKSHIFT] = 0xc64, 224 + [STATUS] = 0xc68, 225 + [VDESIGN30] = 0xc6c, 226 + [VDESIGN74] = 0xc70, 227 + [DVT30] = 0xc74, 228 + [DVT74] = 0xc78, 229 + [AGECOUNT] = 0xc7c, 230 + [SMSTATE0] = 0xc80, 231 + [SMSTATE1] = 0xc84, 232 + [CTL0] = 0xc88, 233 + [DESDETSEC] = 0xce0, 234 + [TEMPAGESEC] = 0xce4, 235 + [CTRLSPARE0] = 0xcf0, 236 + [CTRLSPARE1] = 0xcf4, 237 + [CTRLSPARE2] = 0xcf8, 238 + [CTRLSPARE3] = 0xcfc, 239 + [CORESEL] = 0xf00, 240 + [THERMINTST] = 0xf04, 241 + [INTST] = 0xf08, 242 + [THSTAGE0ST] = 0xf0c, 243 + [THSTAGE1ST] = 0xf10, 244 + [THSTAGE2ST] = 0xf14, 245 + [THAHBST0] = 0xf18, 246 + [THAHBST1] = 0xf1c, 247 + [SPARE0] = 0xf20, 248 + [SPARE1] = 0xf24, 249 + [SPARE2] = 0xf28, 250 + [SPARE3] = 0xf2c, 251 + [THSLPEVEB] = 0xf30, 252 + }; 253 + 254 + /** 255 + * struct svs_platform - svs platform control 256 + * @name: svs platform name 257 + * @base: svs platform register base 258 + * @dev: svs platform device 259 + * @main_clk: main clock for svs bank 260 + * @pbank: svs bank pointer needing to be protected by spin_lock section 261 + * @banks: svs banks that svs platform supports 262 + * @rst: svs platform reset control 263 + * @efuse_parsing: svs platform efuse parsing function pointer 264 + * @probe: svs platform probe function pointer 265 + * @irqflags: svs platform irq settings flags 266 + * @efuse_max: total number of svs efuse 267 + * @tefuse_max: total number of thermal efuse 268 + * @regs: svs platform registers map 269 + * @bank_max: total number of svs banks 270 + * @efuse: svs efuse data received from NVMEM framework 271 + * @tefuse: thermal efuse data received from NVMEM framework 272 + */ 273 + struct svs_platform { 274 + char *name; 275 + void __iomem *base; 276 + struct device *dev; 277 + struct clk *main_clk; 278 + struct svs_bank *pbank; 279 + struct svs_bank *banks; 280 + struct reset_control *rst; 281 + bool (*efuse_parsing)(struct svs_platform *svsp); 282 + int (*probe)(struct svs_platform *svsp); 283 + unsigned long irqflags; 284 + size_t efuse_max; 285 + size_t tefuse_max; 286 + const u32 *regs; 287 + u32 bank_max; 288 + u32 *efuse; 289 + u32 *tefuse; 290 + }; 291 + 292 + struct svs_platform_data { 293 + char *name; 294 + struct svs_bank *banks; 295 + bool (*efuse_parsing)(struct svs_platform *svsp); 296 + int (*probe)(struct svs_platform *svsp); 297 + unsigned long irqflags; 298 + const u32 *regs; 299 + u32 bank_max; 300 + }; 301 + 302 + /** 303 + * struct svs_bank - svs bank representation 304 + * @dev: bank device 305 + * @opp_dev: device for opp table/buck control 306 + * @init_completion: the timeout completion for bank init 307 + * @buck: regulator used by opp_dev 308 + * @tzd: thermal zone device for getting temperature 309 + * @lock: mutex lock to protect voltage update process 310 + * @set_freq_pct: function pointer to set bank frequency percent table 311 + * @get_volts: function pointer to get bank voltages 312 + * @name: bank name 313 + * @buck_name: regulator name 314 + * @tzone_name: thermal zone name 315 + * @phase: bank current phase 316 + * @volt_od: bank voltage overdrive 317 + * @reg_data: bank register data in different phase for debug purpose 318 + * @pm_runtime_enabled_count: bank pm runtime enabled count 319 + * @mode_support: bank mode support. 320 + * @freq_base: reference frequency for bank init 321 + * @turn_freq_base: refenrece frequency for 2-line turn point 322 + * @vboot: voltage request for bank init01 only 323 + * @opp_dfreq: default opp frequency table 324 + * @opp_dvolt: default opp voltage table 325 + * @freq_pct: frequency percent table for bank init 326 + * @volt: bank voltage table 327 + * @volt_step: bank voltage step 328 + * @volt_base: bank voltage base 329 + * @volt_flags: bank voltage flags 330 + * @vmax: bank voltage maximum 331 + * @vmin: bank voltage minimum 332 + * @age_config: bank age configuration 333 + * @age_voffset_in: bank age voltage offset 334 + * @dc_config: bank dc configuration 335 + * @dc_voffset_in: bank dc voltage offset 336 + * @dvt_fixed: bank dvt fixed value 337 + * @vco: bank VCO value 338 + * @chk_shift: bank chicken shift 339 + * @core_sel: bank selection 340 + * @opp_count: bank opp count 341 + * @int_st: bank interrupt identification 342 + * @sw_id: bank software identification 343 + * @cpu_id: cpu core id for SVS CPU bank use only 344 + * @ctl0: TS-x selection 345 + * @temp: bank temperature 346 + * @tzone_htemp: thermal zone high temperature threshold 347 + * @tzone_htemp_voffset: thermal zone high temperature voltage offset 348 + * @tzone_ltemp: thermal zone low temperature threshold 349 + * @tzone_ltemp_voffset: thermal zone low temperature voltage offset 350 + * @bts: svs efuse data 351 + * @mts: svs efuse data 352 + * @bdes: svs efuse data 353 + * @mdes: svs efuse data 354 + * @mtdes: svs efuse data 355 + * @dcbdet: svs efuse data 356 + * @dcmdet: svs efuse data 357 + * @turn_pt: 2-line turn point tells which opp_volt calculated by high/low bank 358 + * @type: bank type to represent it is 2-line (high/low) bank or 1-line bank 359 + * 360 + * Svs bank will generate suitalbe voltages by below general math equation 361 + * and provide these voltages to opp voltage table. 362 + * 363 + * opp_volt[i] = (volt[i] * volt_step) + volt_base; 364 + */ 365 + struct svs_bank { 366 + struct device *dev; 367 + struct device *opp_dev; 368 + struct completion init_completion; 369 + struct regulator *buck; 370 + struct thermal_zone_device *tzd; 371 + struct mutex lock; /* lock to protect voltage update process */ 372 + void (*set_freq_pct)(struct svs_platform *svsp); 373 + void (*get_volts)(struct svs_platform *svsp); 374 + char *name; 375 + char *buck_name; 376 + char *tzone_name; 377 + enum svsb_phase phase; 378 + s32 volt_od; 379 + u32 reg_data[SVSB_PHASE_MAX][SVS_REG_MAX]; 380 + u32 pm_runtime_enabled_count; 381 + u32 mode_support; 382 + u32 freq_base; 383 + u32 turn_freq_base; 384 + u32 vboot; 385 + u32 opp_dfreq[MAX_OPP_ENTRIES]; 386 + u32 opp_dvolt[MAX_OPP_ENTRIES]; 387 + u32 freq_pct[MAX_OPP_ENTRIES]; 388 + u32 volt[MAX_OPP_ENTRIES]; 389 + u32 volt_step; 390 + u32 volt_base; 391 + u32 volt_flags; 392 + u32 vmax; 393 + u32 vmin; 394 + u32 age_config; 395 + u32 age_voffset_in; 396 + u32 dc_config; 397 + u32 dc_voffset_in; 398 + u32 dvt_fixed; 399 + u32 vco; 400 + u32 chk_shift; 401 + u32 core_sel; 402 + u32 opp_count; 403 + u32 int_st; 404 + u32 sw_id; 405 + u32 cpu_id; 406 + u32 ctl0; 407 + u32 temp; 408 + u32 tzone_htemp; 409 + u32 tzone_htemp_voffset; 410 + u32 tzone_ltemp; 411 + u32 tzone_ltemp_voffset; 412 + u32 bts; 413 + u32 mts; 414 + u32 bdes; 415 + u32 mdes; 416 + u32 mtdes; 417 + u32 dcbdet; 418 + u32 dcmdet; 419 + u32 turn_pt; 420 + u32 type; 421 + }; 422 + 423 + static u32 percent(u32 numerator, u32 denominator) 424 + { 425 + /* If not divide 1000, "numerator * 100" will have data overflow. */ 426 + numerator /= 1000; 427 + denominator /= 1000; 428 + 429 + return DIV_ROUND_UP(numerator * 100, denominator); 430 + } 431 + 432 + static u32 svs_readl_relaxed(struct svs_platform *svsp, enum svs_reg_index rg_i) 433 + { 434 + return readl_relaxed(svsp->base + svsp->regs[rg_i]); 435 + } 436 + 437 + static void svs_writel_relaxed(struct svs_platform *svsp, u32 val, 438 + enum svs_reg_index rg_i) 439 + { 440 + writel_relaxed(val, svsp->base + svsp->regs[rg_i]); 441 + } 442 + 443 + static void svs_switch_bank(struct svs_platform *svsp) 444 + { 445 + struct svs_bank *svsb = svsp->pbank; 446 + 447 + svs_writel_relaxed(svsp, svsb->core_sel, CORESEL); 448 + } 449 + 450 + static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step, 451 + u32 svsb_volt_base) 452 + { 453 + return (svsb_volt * svsb_volt_step) + svsb_volt_base; 454 + } 455 + 456 + static u32 svs_opp_volt_to_bank_volt(u32 opp_u_volt, u32 svsb_volt_step, 457 + u32 svsb_volt_base) 458 + { 459 + return (opp_u_volt - svsb_volt_base) / svsb_volt_step; 460 + } 461 + 462 + static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb) 463 + { 464 + struct dev_pm_opp *opp; 465 + u32 i, opp_u_volt; 466 + 467 + for (i = 0; i < svsb->opp_count; i++) { 468 + opp = dev_pm_opp_find_freq_exact(svsb->opp_dev, 469 + svsb->opp_dfreq[i], 470 + true); 471 + if (IS_ERR(opp)) { 472 + dev_err(svsb->dev, "cannot find freq = %u (%ld)\n", 473 + svsb->opp_dfreq[i], PTR_ERR(opp)); 474 + return PTR_ERR(opp); 475 + } 476 + 477 + opp_u_volt = dev_pm_opp_get_voltage(opp); 478 + svsb->volt[i] = svs_opp_volt_to_bank_volt(opp_u_volt, 479 + svsb->volt_step, 480 + svsb->volt_base); 481 + dev_pm_opp_put(opp); 482 + } 483 + 484 + return 0; 485 + } 486 + 487 + static int svs_adjust_pm_opp_volts(struct svs_bank *svsb) 488 + { 489 + int ret = -EPERM, tzone_temp = 0; 490 + u32 i, svsb_volt, opp_volt, temp_voffset = 0, opp_start, opp_stop; 491 + 492 + mutex_lock(&svsb->lock); 493 + 494 + /* 495 + * 2-line bank updates its corresponding opp volts. 496 + * 1-line bank updates all opp volts. 497 + */ 498 + if (svsb->type == SVSB_HIGH) { 499 + opp_start = 0; 500 + opp_stop = svsb->turn_pt; 501 + } else if (svsb->type == SVSB_LOW) { 502 + opp_start = svsb->turn_pt; 503 + opp_stop = svsb->opp_count; 504 + } else { 505 + opp_start = 0; 506 + opp_stop = svsb->opp_count; 507 + } 508 + 509 + /* Get thermal effect */ 510 + if (svsb->phase == SVSB_PHASE_MON) { 511 + ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp); 512 + if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND && 513 + svsb->temp < SVSB_TEMP_LOWER_BOUND)) { 514 + dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n", 515 + svsb->tzone_name, ret, svsb->temp); 516 + svsb->phase = SVSB_PHASE_ERROR; 517 + } 518 + 519 + if (tzone_temp >= svsb->tzone_htemp) 520 + temp_voffset += svsb->tzone_htemp_voffset; 521 + else if (tzone_temp <= svsb->tzone_ltemp) 522 + temp_voffset += svsb->tzone_ltemp_voffset; 523 + 524 + /* 2-line bank update all opp volts when running mon mode */ 525 + if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) { 526 + opp_start = 0; 527 + opp_stop = svsb->opp_count; 528 + } 529 + } 530 + 531 + /* vmin <= svsb_volt (opp_volt) <= default opp voltage */ 532 + for (i = opp_start; i < opp_stop; i++) { 533 + switch (svsb->phase) { 534 + case SVSB_PHASE_ERROR: 535 + opp_volt = svsb->opp_dvolt[i]; 536 + break; 537 + case SVSB_PHASE_INIT01: 538 + /* do nothing */ 539 + goto unlock_mutex; 540 + case SVSB_PHASE_INIT02: 541 + svsb_volt = max(svsb->volt[i], svsb->vmin); 542 + opp_volt = svs_bank_volt_to_opp_volt(svsb_volt, 543 + svsb->volt_step, 544 + svsb->volt_base); 545 + break; 546 + case SVSB_PHASE_MON: 547 + svsb_volt = max(svsb->volt[i] + temp_voffset, svsb->vmin); 548 + opp_volt = svs_bank_volt_to_opp_volt(svsb_volt, 549 + svsb->volt_step, 550 + svsb->volt_base); 551 + break; 552 + default: 553 + dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase); 554 + ret = -EINVAL; 555 + goto unlock_mutex; 556 + } 557 + 558 + opp_volt = min(opp_volt, svsb->opp_dvolt[i]); 559 + ret = dev_pm_opp_adjust_voltage(svsb->opp_dev, 560 + svsb->opp_dfreq[i], 561 + opp_volt, opp_volt, 562 + svsb->opp_dvolt[i]); 563 + if (ret) { 564 + dev_err(svsb->dev, "set %uuV fail: %d\n", 565 + opp_volt, ret); 566 + goto unlock_mutex; 567 + } 568 + } 569 + 570 + unlock_mutex: 571 + mutex_unlock(&svsb->lock); 572 + 573 + return ret; 574 + } 575 + 576 + static int svs_dump_debug_show(struct seq_file *m, void *p) 577 + { 578 + struct svs_platform *svsp = (struct svs_platform *)m->private; 579 + struct svs_bank *svsb; 580 + unsigned long svs_reg_addr; 581 + u32 idx, i, j, bank_id; 582 + 583 + for (i = 0; i < svsp->efuse_max; i++) 584 + if (svsp->efuse && svsp->efuse[i]) 585 + seq_printf(m, "M_HW_RES%d = 0x%08x\n", 586 + i, svsp->efuse[i]); 587 + 588 + for (i = 0; i < svsp->tefuse_max; i++) 589 + if (svsp->tefuse) 590 + seq_printf(m, "THERMAL_EFUSE%d = 0x%08x\n", 591 + i, svsp->tefuse[i]); 592 + 593 + for (bank_id = 0, idx = 0; idx < svsp->bank_max; idx++, bank_id++) { 594 + svsb = &svsp->banks[idx]; 595 + 596 + for (i = SVSB_PHASE_INIT01; i <= SVSB_PHASE_MON; i++) { 597 + seq_printf(m, "Bank_number = %u\n", bank_id); 598 + 599 + if (i == SVSB_PHASE_INIT01 || i == SVSB_PHASE_INIT02) 600 + seq_printf(m, "mode = init%d\n", i); 601 + else if (i == SVSB_PHASE_MON) 602 + seq_puts(m, "mode = mon\n"); 603 + else 604 + seq_puts(m, "mode = error\n"); 605 + 606 + for (j = DESCHAR; j < SVS_REG_MAX; j++) { 607 + svs_reg_addr = (unsigned long)(svsp->base + 608 + svsp->regs[j]); 609 + seq_printf(m, "0x%08lx = 0x%08x\n", 610 + svs_reg_addr, svsb->reg_data[i][j]); 611 + } 612 + } 613 + } 614 + 615 + return 0; 616 + } 617 + 618 + debug_fops_ro(dump); 619 + 620 + static int svs_enable_debug_show(struct seq_file *m, void *v) 621 + { 622 + struct svs_bank *svsb = (struct svs_bank *)m->private; 623 + 624 + switch (svsb->phase) { 625 + case SVSB_PHASE_ERROR: 626 + seq_puts(m, "disabled\n"); 627 + break; 628 + case SVSB_PHASE_INIT01: 629 + seq_puts(m, "init1\n"); 630 + break; 631 + case SVSB_PHASE_INIT02: 632 + seq_puts(m, "init2\n"); 633 + break; 634 + case SVSB_PHASE_MON: 635 + seq_puts(m, "mon mode\n"); 636 + break; 637 + default: 638 + seq_puts(m, "unknown\n"); 639 + break; 640 + } 641 + 642 + return 0; 643 + } 644 + 645 + static ssize_t svs_enable_debug_write(struct file *filp, 646 + const char __user *buffer, 647 + size_t count, loff_t *pos) 648 + { 649 + struct svs_bank *svsb = file_inode(filp)->i_private; 650 + struct svs_platform *svsp = dev_get_drvdata(svsb->dev); 651 + unsigned long flags; 652 + int enabled, ret; 653 + char *buf = NULL; 654 + 655 + if (count >= PAGE_SIZE) 656 + return -EINVAL; 657 + 658 + buf = (char *)memdup_user_nul(buffer, count); 659 + if (IS_ERR(buf)) 660 + return PTR_ERR(buf); 661 + 662 + ret = kstrtoint(buf, 10, &enabled); 663 + if (ret) 664 + return ret; 665 + 666 + if (!enabled) { 667 + spin_lock_irqsave(&svs_lock, flags); 668 + svsp->pbank = svsb; 669 + svsb->mode_support = SVSB_MODE_ALL_DISABLE; 670 + svs_switch_bank(svsp); 671 + svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); 672 + svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); 673 + spin_unlock_irqrestore(&svs_lock, flags); 674 + 675 + svsb->phase = SVSB_PHASE_ERROR; 676 + svs_adjust_pm_opp_volts(svsb); 677 + } 678 + 679 + kfree(buf); 680 + 681 + return count; 682 + } 683 + 684 + debug_fops_rw(enable); 685 + 686 + static int svs_status_debug_show(struct seq_file *m, void *v) 687 + { 688 + struct svs_bank *svsb = (struct svs_bank *)m->private; 689 + struct dev_pm_opp *opp; 690 + int tzone_temp = 0, ret; 691 + u32 i; 692 + 693 + ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp); 694 + if (ret) 695 + seq_printf(m, "%s: temperature ignore, turn_pt = %u\n", 696 + svsb->name, svsb->turn_pt); 697 + else 698 + seq_printf(m, "%s: temperature = %d, turn_pt = %u\n", 699 + svsb->name, tzone_temp, svsb->turn_pt); 700 + 701 + for (i = 0; i < svsb->opp_count; i++) { 702 + opp = dev_pm_opp_find_freq_exact(svsb->opp_dev, 703 + svsb->opp_dfreq[i], true); 704 + if (IS_ERR(opp)) { 705 + seq_printf(m, "%s: cannot find freq = %u (%ld)\n", 706 + svsb->name, svsb->opp_dfreq[i], 707 + PTR_ERR(opp)); 708 + return PTR_ERR(opp); 709 + } 710 + 711 + seq_printf(m, "opp_freq[%02u]: %u, opp_volt[%02u]: %lu, ", 712 + i, svsb->opp_dfreq[i], i, 713 + dev_pm_opp_get_voltage(opp)); 714 + seq_printf(m, "svsb_volt[%02u]: 0x%x, freq_pct[%02u]: %u\n", 715 + i, svsb->volt[i], i, svsb->freq_pct[i]); 716 + dev_pm_opp_put(opp); 717 + } 718 + 719 + return 0; 720 + } 721 + 722 + debug_fops_ro(status); 723 + 724 + static int svs_create_debug_cmds(struct svs_platform *svsp) 725 + { 726 + struct svs_bank *svsb; 727 + struct dentry *svs_dir, *svsb_dir, *file_entry; 728 + const char *d = "/sys/kernel/debug/svs"; 729 + u32 i, idx; 730 + 731 + struct svs_dentry { 732 + const char *name; 733 + const struct file_operations *fops; 734 + }; 735 + 736 + struct svs_dentry svs_entries[] = { 737 + svs_dentry_data(dump), 738 + }; 739 + 740 + struct svs_dentry svsb_entries[] = { 741 + svs_dentry_data(enable), 742 + svs_dentry_data(status), 743 + }; 744 + 745 + svs_dir = debugfs_create_dir("svs", NULL); 746 + if (IS_ERR(svs_dir)) { 747 + dev_err(svsp->dev, "cannot create %s: %ld\n", 748 + d, PTR_ERR(svs_dir)); 749 + return PTR_ERR(svs_dir); 750 + } 751 + 752 + for (i = 0; i < ARRAY_SIZE(svs_entries); i++) { 753 + file_entry = debugfs_create_file(svs_entries[i].name, 0664, 754 + svs_dir, svsp, 755 + svs_entries[i].fops); 756 + if (IS_ERR(file_entry)) { 757 + dev_err(svsp->dev, "cannot create %s/%s: %ld\n", 758 + d, svs_entries[i].name, PTR_ERR(file_entry)); 759 + return PTR_ERR(file_entry); 760 + } 761 + } 762 + 763 + for (idx = 0; idx < svsp->bank_max; idx++) { 764 + svsb = &svsp->banks[idx]; 765 + 766 + if (svsb->mode_support == SVSB_MODE_ALL_DISABLE) 767 + continue; 768 + 769 + svsb_dir = debugfs_create_dir(svsb->name, svs_dir); 770 + if (IS_ERR(svsb_dir)) { 771 + dev_err(svsp->dev, "cannot create %s/%s: %ld\n", 772 + d, svsb->name, PTR_ERR(svsb_dir)); 773 + return PTR_ERR(svsb_dir); 774 + } 775 + 776 + for (i = 0; i < ARRAY_SIZE(svsb_entries); i++) { 777 + file_entry = debugfs_create_file(svsb_entries[i].name, 778 + 0664, svsb_dir, svsb, 779 + svsb_entries[i].fops); 780 + if (IS_ERR(file_entry)) { 781 + dev_err(svsp->dev, "no %s/%s/%s?: %ld\n", 782 + d, svsb->name, svsb_entries[i].name, 783 + PTR_ERR(file_entry)); 784 + return PTR_ERR(file_entry); 785 + } 786 + } 787 + } 788 + 789 + return 0; 790 + } 791 + 792 + static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx) 793 + { 794 + u32 vx; 795 + 796 + if (v0 == v1 || f0 == f1) 797 + return v0; 798 + 799 + /* *100 to have decimal fraction factor */ 800 + vx = (v0 * 100) - ((((v0 - v1) * 100) / (f0 - f1)) * (f0 - fx)); 801 + 802 + return DIV_ROUND_UP(vx, 100); 803 + } 804 + 805 + static void svs_get_bank_volts_v3(struct svs_platform *svsp) 806 + { 807 + struct svs_bank *svsb = svsp->pbank; 808 + u32 i, j, *vop, vop74, vop30, turn_pt = svsb->turn_pt; 809 + u32 b_sft, shift_byte = 0, opp_start = 0, opp_stop = 0; 810 + u32 middle_index = (svsb->opp_count / 2); 811 + 812 + if (svsb->phase == SVSB_PHASE_MON && 813 + svsb->volt_flags & SVSB_MON_VOLT_IGNORE) 814 + return; 815 + 816 + vop74 = svs_readl_relaxed(svsp, VOP74); 817 + vop30 = svs_readl_relaxed(svsp, VOP30); 818 + 819 + /* Target is to set svsb->volt[] by algorithm */ 820 + if (turn_pt < middle_index) { 821 + if (svsb->type == SVSB_HIGH) { 822 + /* volt[0] ~ volt[turn_pt - 1] */ 823 + for (i = 0; i < turn_pt; i++) { 824 + b_sft = BITS8 * (shift_byte % REG_BYTES); 825 + vop = (shift_byte < REG_BYTES) ? &vop30 : 826 + &vop74; 827 + svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0); 828 + shift_byte++; 829 + } 830 + } else if (svsb->type == SVSB_LOW) { 831 + /* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */ 832 + j = svsb->opp_count - 7; 833 + svsb->volt[turn_pt] = vop30 & GENMASK(7, 0); 834 + shift_byte++; 835 + for (i = j; i < svsb->opp_count; i++) { 836 + b_sft = BITS8 * (shift_byte % REG_BYTES); 837 + vop = (shift_byte < REG_BYTES) ? &vop30 : 838 + &vop74; 839 + svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0); 840 + shift_byte++; 841 + } 842 + 843 + /* volt[turn_pt + 1] ~ volt[j - 1] by interpolate */ 844 + for (i = turn_pt + 1; i < j; i++) 845 + svsb->volt[i] = interpolate(svsb->freq_pct[turn_pt], 846 + svsb->freq_pct[j], 847 + svsb->volt[turn_pt], 848 + svsb->volt[j], 849 + svsb->freq_pct[i]); 850 + } 851 + } else { 852 + if (svsb->type == SVSB_HIGH) { 853 + /* volt[0] + volt[j] ~ volt[turn_pt - 1] */ 854 + j = turn_pt - 7; 855 + svsb->volt[0] = vop30 & GENMASK(7, 0); 856 + shift_byte++; 857 + for (i = j; i < turn_pt; i++) { 858 + b_sft = BITS8 * (shift_byte % REG_BYTES); 859 + vop = (shift_byte < REG_BYTES) ? &vop30 : 860 + &vop74; 861 + svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0); 862 + shift_byte++; 863 + } 864 + 865 + /* volt[1] ~ volt[j - 1] by interpolate */ 866 + for (i = 1; i < j; i++) 867 + svsb->volt[i] = interpolate(svsb->freq_pct[0], 868 + svsb->freq_pct[j], 869 + svsb->volt[0], 870 + svsb->volt[j], 871 + svsb->freq_pct[i]); 872 + } else if (svsb->type == SVSB_LOW) { 873 + /* volt[turn_pt] ~ volt[opp_count - 1] */ 874 + for (i = turn_pt; i < svsb->opp_count; i++) { 875 + b_sft = BITS8 * (shift_byte % REG_BYTES); 876 + vop = (shift_byte < REG_BYTES) ? &vop30 : 877 + &vop74; 878 + svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0); 879 + shift_byte++; 880 + } 881 + } 882 + } 883 + 884 + if (svsb->type == SVSB_HIGH) { 885 + opp_start = 0; 886 + opp_stop = svsb->turn_pt; 887 + } else if (svsb->type == SVSB_LOW) { 888 + opp_start = svsb->turn_pt; 889 + opp_stop = svsb->opp_count; 890 + } 891 + 892 + for (i = opp_start; i < opp_stop; i++) 893 + if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT) 894 + svsb->volt[i] -= svsb->dvt_fixed; 895 + } 896 + 897 + static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp) 898 + { 899 + struct svs_bank *svsb = svsp->pbank; 900 + u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0; 901 + u32 b_sft, shift_byte = 0, turn_pt; 902 + u32 middle_index = (svsb->opp_count / 2); 903 + 904 + for (i = 0; i < svsb->opp_count; i++) { 905 + if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) { 906 + svsb->turn_pt = i; 907 + break; 908 + } 909 + } 910 + 911 + turn_pt = svsb->turn_pt; 912 + 913 + /* Target is to fill out freq_pct74 / freq_pct30 by algorithm */ 914 + if (turn_pt < middle_index) { 915 + if (svsb->type == SVSB_HIGH) { 916 + /* 917 + * If we don't handle this situation, 918 + * SVSB_HIGH's FREQPCT74 / FREQPCT30 would keep "0" 919 + * and this leads SVSB_LOW to work abnormally. 920 + */ 921 + if (turn_pt == 0) 922 + freq_pct30 = svsb->freq_pct[0]; 923 + 924 + /* freq_pct[0] ~ freq_pct[turn_pt - 1] */ 925 + for (i = 0; i < turn_pt; i++) { 926 + b_sft = BITS8 * (shift_byte % REG_BYTES); 927 + freq_pct = (shift_byte < REG_BYTES) ? 928 + &freq_pct30 : &freq_pct74; 929 + *freq_pct |= (svsb->freq_pct[i] << b_sft); 930 + shift_byte++; 931 + } 932 + } else if (svsb->type == SVSB_LOW) { 933 + /* 934 + * freq_pct[turn_pt] + 935 + * freq_pct[opp_count - 7] ~ freq_pct[opp_count -1] 936 + */ 937 + freq_pct30 = svsb->freq_pct[turn_pt]; 938 + shift_byte++; 939 + j = svsb->opp_count - 7; 940 + for (i = j; i < svsb->opp_count; i++) { 941 + b_sft = BITS8 * (shift_byte % REG_BYTES); 942 + freq_pct = (shift_byte < REG_BYTES) ? 943 + &freq_pct30 : &freq_pct74; 944 + *freq_pct |= (svsb->freq_pct[i] << b_sft); 945 + shift_byte++; 946 + } 947 + } 948 + } else { 949 + if (svsb->type == SVSB_HIGH) { 950 + /* 951 + * freq_pct[0] + 952 + * freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1] 953 + */ 954 + freq_pct30 = svsb->freq_pct[0]; 955 + shift_byte++; 956 + j = turn_pt - 7; 957 + for (i = j; i < turn_pt; i++) { 958 + b_sft = BITS8 * (shift_byte % REG_BYTES); 959 + freq_pct = (shift_byte < REG_BYTES) ? 960 + &freq_pct30 : &freq_pct74; 961 + *freq_pct |= (svsb->freq_pct[i] << b_sft); 962 + shift_byte++; 963 + } 964 + } else if (svsb->type == SVSB_LOW) { 965 + /* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */ 966 + for (i = turn_pt; i < svsb->opp_count; i++) { 967 + b_sft = BITS8 * (shift_byte % REG_BYTES); 968 + freq_pct = (shift_byte < REG_BYTES) ? 969 + &freq_pct30 : &freq_pct74; 970 + *freq_pct |= (svsb->freq_pct[i] << b_sft); 971 + shift_byte++; 972 + } 973 + } 974 + } 975 + 976 + svs_writel_relaxed(svsp, freq_pct74, FREQPCT74); 977 + svs_writel_relaxed(svsp, freq_pct30, FREQPCT30); 978 + } 979 + 980 + static void svs_get_bank_volts_v2(struct svs_platform *svsp) 981 + { 982 + struct svs_bank *svsb = svsp->pbank; 983 + u32 temp, i; 984 + 985 + temp = svs_readl_relaxed(svsp, VOP74); 986 + svsb->volt[14] = (temp >> 24) & GENMASK(7, 0); 987 + svsb->volt[12] = (temp >> 16) & GENMASK(7, 0); 988 + svsb->volt[10] = (temp >> 8) & GENMASK(7, 0); 989 + svsb->volt[8] = (temp & GENMASK(7, 0)); 990 + 991 + temp = svs_readl_relaxed(svsp, VOP30); 992 + svsb->volt[6] = (temp >> 24) & GENMASK(7, 0); 993 + svsb->volt[4] = (temp >> 16) & GENMASK(7, 0); 994 + svsb->volt[2] = (temp >> 8) & GENMASK(7, 0); 995 + svsb->volt[0] = (temp & GENMASK(7, 0)); 996 + 997 + for (i = 0; i <= 12; i += 2) 998 + svsb->volt[i + 1] = interpolate(svsb->freq_pct[i], 999 + svsb->freq_pct[i + 2], 1000 + svsb->volt[i], 1001 + svsb->volt[i + 2], 1002 + svsb->freq_pct[i + 1]); 1003 + 1004 + svsb->volt[15] = interpolate(svsb->freq_pct[12], 1005 + svsb->freq_pct[14], 1006 + svsb->volt[12], 1007 + svsb->volt[14], 1008 + svsb->freq_pct[15]); 1009 + 1010 + for (i = 0; i < svsb->opp_count; i++) 1011 + svsb->volt[i] += svsb->volt_od; 1012 + } 1013 + 1014 + static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp) 1015 + { 1016 + struct svs_bank *svsb = svsp->pbank; 1017 + 1018 + svs_writel_relaxed(svsp, 1019 + (svsb->freq_pct[14] << 24) | 1020 + (svsb->freq_pct[12] << 16) | 1021 + (svsb->freq_pct[10] << 8) | 1022 + svsb->freq_pct[8], 1023 + FREQPCT74); 1024 + 1025 + svs_writel_relaxed(svsp, 1026 + (svsb->freq_pct[6] << 24) | 1027 + (svsb->freq_pct[4] << 16) | 1028 + (svsb->freq_pct[2] << 8) | 1029 + svsb->freq_pct[0], 1030 + FREQPCT30); 1031 + } 1032 + 1033 + static void svs_set_bank_phase(struct svs_platform *svsp, 1034 + enum svsb_phase target_phase) 1035 + { 1036 + struct svs_bank *svsb = svsp->pbank; 1037 + u32 des_char, temp_char, det_char, limit_vals, init2vals, ts_calcs; 1038 + 1039 + svs_switch_bank(svsp); 1040 + 1041 + des_char = (svsb->bdes << 8) | svsb->mdes; 1042 + svs_writel_relaxed(svsp, des_char, DESCHAR); 1043 + 1044 + temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed; 1045 + svs_writel_relaxed(svsp, temp_char, TEMPCHAR); 1046 + 1047 + det_char = (svsb->dcbdet << 8) | svsb->dcmdet; 1048 + svs_writel_relaxed(svsp, det_char, DETCHAR); 1049 + 1050 + svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG); 1051 + svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG); 1052 + svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG); 1053 + 1054 + svsb->set_freq_pct(svsp); 1055 + 1056 + limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) | 1057 + (SVSB_DTHI << 8) | SVSB_DTLO; 1058 + svs_writel_relaxed(svsp, limit_vals, LIMITVALS); 1059 + 1060 + svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW); 1061 + svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG); 1062 + svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT); 1063 + svs_writel_relaxed(svsp, svsb->ctl0, CTL0); 1064 + svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); 1065 + 1066 + switch (target_phase) { 1067 + case SVSB_PHASE_INIT01: 1068 + svs_writel_relaxed(svsp, svsb->vboot, VBOOT); 1069 + svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); 1070 + svs_writel_relaxed(svsp, SVSB_EN_INIT01, SVSEN); 1071 + break; 1072 + case SVSB_PHASE_INIT02: 1073 + svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); 1074 + init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in; 1075 + svs_writel_relaxed(svsp, init2vals, INIT2VALS); 1076 + svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN); 1077 + break; 1078 + case SVSB_PHASE_MON: 1079 + ts_calcs = (svsb->bts << 12) | svsb->mts; 1080 + svs_writel_relaxed(svsp, ts_calcs, TSCALCS); 1081 + svs_writel_relaxed(svsp, SVSB_INTEN_MONVOPEN, INTEN); 1082 + svs_writel_relaxed(svsp, SVSB_EN_MON, SVSEN); 1083 + break; 1084 + default: 1085 + dev_err(svsb->dev, "requested unknown target phase: %u\n", 1086 + target_phase); 1087 + break; 1088 + } 1089 + } 1090 + 1091 + static inline void svs_save_bank_register_data(struct svs_platform *svsp, 1092 + enum svsb_phase phase) 1093 + { 1094 + struct svs_bank *svsb = svsp->pbank; 1095 + enum svs_reg_index rg_i; 1096 + 1097 + for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++) 1098 + svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i); 1099 + } 1100 + 1101 + static inline void svs_error_isr_handler(struct svs_platform *svsp) 1102 + { 1103 + struct svs_bank *svsb = svsp->pbank; 1104 + 1105 + dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n", 1106 + __func__, svs_readl_relaxed(svsp, CORESEL)); 1107 + dev_err(svsb->dev, "SVSEN = 0x%08x, INTSTS = 0x%08x\n", 1108 + svs_readl_relaxed(svsp, SVSEN), 1109 + svs_readl_relaxed(svsp, INTSTS)); 1110 + dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n", 1111 + svs_readl_relaxed(svsp, SMSTATE0), 1112 + svs_readl_relaxed(svsp, SMSTATE1)); 1113 + dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP)); 1114 + 1115 + svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR); 1116 + 1117 + svsb->phase = SVSB_PHASE_ERROR; 1118 + svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); 1119 + svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); 1120 + } 1121 + 1122 + static inline void svs_init01_isr_handler(struct svs_platform *svsp) 1123 + { 1124 + struct svs_bank *svsb = svsp->pbank; 1125 + 1126 + dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n", 1127 + __func__, svs_readl_relaxed(svsp, VDESIGN74), 1128 + svs_readl_relaxed(svsp, VDESIGN30), 1129 + svs_readl_relaxed(svsp, DCVALUES)); 1130 + 1131 + svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01); 1132 + 1133 + svsb->phase = SVSB_PHASE_INIT01; 1134 + svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) & 1135 + GENMASK(15, 0)) + 1; 1136 + if (svsb->volt_flags & SVSB_INIT01_VOLT_IGNORE || 1137 + (svsb->dc_voffset_in & SVSB_DC_SIGNED_BIT && 1138 + svsb->volt_flags & SVSB_INIT01_VOLT_INC_ONLY)) 1139 + svsb->dc_voffset_in = 0; 1140 + 1141 + svsb->age_voffset_in = svs_readl_relaxed(svsp, AGEVALUES) & 1142 + GENMASK(15, 0); 1143 + 1144 + svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); 1145 + svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS); 1146 + svsb->core_sel &= ~SVSB_DET_CLK_EN; 1147 + } 1148 + 1149 + static inline void svs_init02_isr_handler(struct svs_platform *svsp) 1150 + { 1151 + struct svs_bank *svsb = svsp->pbank; 1152 + 1153 + dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n", 1154 + __func__, svs_readl_relaxed(svsp, VOP74), 1155 + svs_readl_relaxed(svsp, VOP30), 1156 + svs_readl_relaxed(svsp, DCVALUES)); 1157 + 1158 + svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02); 1159 + 1160 + svsb->phase = SVSB_PHASE_INIT02; 1161 + svsb->get_volts(svsp); 1162 + 1163 + svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); 1164 + svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS); 1165 + } 1166 + 1167 + static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp) 1168 + { 1169 + struct svs_bank *svsb = svsp->pbank; 1170 + 1171 + svs_save_bank_register_data(svsp, SVSB_PHASE_MON); 1172 + 1173 + svsb->phase = SVSB_PHASE_MON; 1174 + svsb->get_volts(svsp); 1175 + 1176 + svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0); 1177 + svs_writel_relaxed(svsp, SVSB_INTSTS_MONVOP, INTSTS); 1178 + } 1179 + 1180 + static irqreturn_t svs_isr(int irq, void *data) 1181 + { 1182 + struct svs_platform *svsp = data; 1183 + struct svs_bank *svsb = NULL; 1184 + unsigned long flags; 1185 + u32 idx, int_sts, svs_en; 1186 + 1187 + for (idx = 0; idx < svsp->bank_max; idx++) { 1188 + svsb = &svsp->banks[idx]; 1189 + WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name); 1190 + 1191 + spin_lock_irqsave(&svs_lock, flags); 1192 + svsp->pbank = svsb; 1193 + 1194 + /* Find out which svs bank fires interrupt */ 1195 + if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) { 1196 + spin_unlock_irqrestore(&svs_lock, flags); 1197 + continue; 1198 + } 1199 + 1200 + svs_switch_bank(svsp); 1201 + int_sts = svs_readl_relaxed(svsp, INTSTS); 1202 + svs_en = svs_readl_relaxed(svsp, SVSEN); 1203 + 1204 + if (int_sts == SVSB_INTSTS_COMPLETE && 1205 + svs_en == SVSB_EN_INIT01) 1206 + svs_init01_isr_handler(svsp); 1207 + else if (int_sts == SVSB_INTSTS_COMPLETE && 1208 + svs_en == SVSB_EN_INIT02) 1209 + svs_init02_isr_handler(svsp); 1210 + else if (int_sts & SVSB_INTSTS_MONVOP) 1211 + svs_mon_mode_isr_handler(svsp); 1212 + else 1213 + svs_error_isr_handler(svsp); 1214 + 1215 + spin_unlock_irqrestore(&svs_lock, flags); 1216 + break; 1217 + } 1218 + 1219 + svs_adjust_pm_opp_volts(svsb); 1220 + 1221 + if (svsb->phase == SVSB_PHASE_INIT01 || 1222 + svsb->phase == SVSB_PHASE_INIT02) 1223 + complete(&svsb->init_completion); 1224 + 1225 + return IRQ_HANDLED; 1226 + } 1227 + 1228 + static int svs_init01(struct svs_platform *svsp) 1229 + { 1230 + struct svs_bank *svsb; 1231 + unsigned long flags, time_left; 1232 + bool search_done; 1233 + int ret = 0, r; 1234 + u32 opp_freq, opp_vboot, buck_volt, idx, i; 1235 + 1236 + /* Keep CPUs' core power on for svs_init01 initialization */ 1237 + cpuidle_pause_and_lock(); 1238 + 1239 + /* Svs bank init01 preparation - power enable */ 1240 + for (idx = 0; idx < svsp->bank_max; idx++) { 1241 + svsb = &svsp->banks[idx]; 1242 + 1243 + if (!(svsb->mode_support & SVSB_MODE_INIT01)) 1244 + continue; 1245 + 1246 + ret = regulator_enable(svsb->buck); 1247 + if (ret) { 1248 + dev_err(svsb->dev, "%s enable fail: %d\n", 1249 + svsb->buck_name, ret); 1250 + goto svs_init01_resume_cpuidle; 1251 + } 1252 + 1253 + /* Some buck doesn't support mode change. Show fail msg only */ 1254 + ret = regulator_set_mode(svsb->buck, REGULATOR_MODE_FAST); 1255 + if (ret) 1256 + dev_notice(svsb->dev, "set fast mode fail: %d\n", ret); 1257 + 1258 + if (svsb->volt_flags & SVSB_INIT01_PD_REQ) { 1259 + if (!pm_runtime_enabled(svsb->opp_dev)) { 1260 + pm_runtime_enable(svsb->opp_dev); 1261 + svsb->pm_runtime_enabled_count++; 1262 + } 1263 + 1264 + ret = pm_runtime_get_sync(svsb->opp_dev); 1265 + if (ret < 0) { 1266 + dev_err(svsb->dev, "mtcmos on fail: %d\n", ret); 1267 + goto svs_init01_resume_cpuidle; 1268 + } 1269 + } 1270 + } 1271 + 1272 + /* 1273 + * Svs bank init01 preparation - vboot voltage adjustment 1274 + * Sometimes two svs banks use the same buck. Therefore, 1275 + * we have to set each svs bank to target voltage(vboot) first. 1276 + */ 1277 + for (idx = 0; idx < svsp->bank_max; idx++) { 1278 + svsb = &svsp->banks[idx]; 1279 + 1280 + if (!(svsb->mode_support & SVSB_MODE_INIT01)) 1281 + continue; 1282 + 1283 + /* 1284 + * Find the fastest freq that can be run at vboot and 1285 + * fix to that freq until svs_init01 is done. 1286 + */ 1287 + search_done = false; 1288 + opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot, 1289 + svsb->volt_step, 1290 + svsb->volt_base); 1291 + 1292 + for (i = 0; i < svsb->opp_count; i++) { 1293 + opp_freq = svsb->opp_dfreq[i]; 1294 + if (!search_done && svsb->opp_dvolt[i] <= opp_vboot) { 1295 + ret = dev_pm_opp_adjust_voltage(svsb->opp_dev, 1296 + opp_freq, 1297 + opp_vboot, 1298 + opp_vboot, 1299 + opp_vboot); 1300 + if (ret) { 1301 + dev_err(svsb->dev, 1302 + "set opp %uuV vboot fail: %d\n", 1303 + opp_vboot, ret); 1304 + goto svs_init01_finish; 1305 + } 1306 + 1307 + search_done = true; 1308 + } else { 1309 + ret = dev_pm_opp_disable(svsb->opp_dev, 1310 + svsb->opp_dfreq[i]); 1311 + if (ret) { 1312 + dev_err(svsb->dev, 1313 + "opp %uHz disable fail: %d\n", 1314 + svsb->opp_dfreq[i], ret); 1315 + goto svs_init01_finish; 1316 + } 1317 + } 1318 + } 1319 + } 1320 + 1321 + /* Svs bank init01 begins */ 1322 + for (idx = 0; idx < svsp->bank_max; idx++) { 1323 + svsb = &svsp->banks[idx]; 1324 + 1325 + if (!(svsb->mode_support & SVSB_MODE_INIT01)) 1326 + continue; 1327 + 1328 + opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot, 1329 + svsb->volt_step, 1330 + svsb->volt_base); 1331 + 1332 + buck_volt = regulator_get_voltage(svsb->buck); 1333 + if (buck_volt != opp_vboot) { 1334 + dev_err(svsb->dev, 1335 + "buck voltage: %uuV, expected vboot: %uuV\n", 1336 + buck_volt, opp_vboot); 1337 + ret = -EPERM; 1338 + goto svs_init01_finish; 1339 + } 1340 + 1341 + spin_lock_irqsave(&svs_lock, flags); 1342 + svsp->pbank = svsb; 1343 + svs_set_bank_phase(svsp, SVSB_PHASE_INIT01); 1344 + spin_unlock_irqrestore(&svs_lock, flags); 1345 + 1346 + time_left = wait_for_completion_timeout(&svsb->init_completion, 1347 + msecs_to_jiffies(5000)); 1348 + if (!time_left) { 1349 + dev_err(svsb->dev, "init01 completion timeout\n"); 1350 + ret = -EBUSY; 1351 + goto svs_init01_finish; 1352 + } 1353 + } 1354 + 1355 + svs_init01_finish: 1356 + for (idx = 0; idx < svsp->bank_max; idx++) { 1357 + svsb = &svsp->banks[idx]; 1358 + 1359 + if (!(svsb->mode_support & SVSB_MODE_INIT01)) 1360 + continue; 1361 + 1362 + for (i = 0; i < svsb->opp_count; i++) { 1363 + r = dev_pm_opp_enable(svsb->opp_dev, 1364 + svsb->opp_dfreq[i]); 1365 + if (r) 1366 + dev_err(svsb->dev, "opp %uHz enable fail: %d\n", 1367 + svsb->opp_dfreq[i], r); 1368 + } 1369 + 1370 + if (svsb->volt_flags & SVSB_INIT01_PD_REQ) { 1371 + r = pm_runtime_put_sync(svsb->opp_dev); 1372 + if (r) 1373 + dev_err(svsb->dev, "mtcmos off fail: %d\n", r); 1374 + 1375 + if (svsb->pm_runtime_enabled_count > 0) { 1376 + pm_runtime_disable(svsb->opp_dev); 1377 + svsb->pm_runtime_enabled_count--; 1378 + } 1379 + } 1380 + 1381 + r = regulator_set_mode(svsb->buck, REGULATOR_MODE_NORMAL); 1382 + if (r) 1383 + dev_notice(svsb->dev, "set normal mode fail: %d\n", r); 1384 + 1385 + r = regulator_disable(svsb->buck); 1386 + if (r) 1387 + dev_err(svsb->dev, "%s disable fail: %d\n", 1388 + svsb->buck_name, r); 1389 + } 1390 + 1391 + svs_init01_resume_cpuidle: 1392 + cpuidle_resume_and_unlock(); 1393 + 1394 + return ret; 1395 + } 1396 + 1397 + static int svs_init02(struct svs_platform *svsp) 1398 + { 1399 + struct svs_bank *svsb; 1400 + unsigned long flags, time_left; 1401 + u32 idx; 1402 + 1403 + for (idx = 0; idx < svsp->bank_max; idx++) { 1404 + svsb = &svsp->banks[idx]; 1405 + 1406 + if (!(svsb->mode_support & SVSB_MODE_INIT02)) 1407 + continue; 1408 + 1409 + reinit_completion(&svsb->init_completion); 1410 + spin_lock_irqsave(&svs_lock, flags); 1411 + svsp->pbank = svsb; 1412 + svs_set_bank_phase(svsp, SVSB_PHASE_INIT02); 1413 + spin_unlock_irqrestore(&svs_lock, flags); 1414 + 1415 + time_left = wait_for_completion_timeout(&svsb->init_completion, 1416 + msecs_to_jiffies(5000)); 1417 + if (!time_left) { 1418 + dev_err(svsb->dev, "init02 completion timeout\n"); 1419 + return -EBUSY; 1420 + } 1421 + } 1422 + 1423 + /* 1424 + * 2-line high/low bank update its corresponding opp voltages only. 1425 + * Therefore, we sync voltages from opp for high/low bank voltages 1426 + * consistency. 1427 + */ 1428 + for (idx = 0; idx < svsp->bank_max; idx++) { 1429 + svsb = &svsp->banks[idx]; 1430 + 1431 + if (!(svsb->mode_support & SVSB_MODE_INIT02)) 1432 + continue; 1433 + 1434 + if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) { 1435 + if (svs_sync_bank_volts_from_opp(svsb)) { 1436 + dev_err(svsb->dev, "sync volt fail\n"); 1437 + return -EPERM; 1438 + } 1439 + } 1440 + } 1441 + 1442 + return 0; 1443 + } 1444 + 1445 + static void svs_mon_mode(struct svs_platform *svsp) 1446 + { 1447 + struct svs_bank *svsb; 1448 + unsigned long flags; 1449 + u32 idx; 1450 + 1451 + for (idx = 0; idx < svsp->bank_max; idx++) { 1452 + svsb = &svsp->banks[idx]; 1453 + 1454 + if (!(svsb->mode_support & SVSB_MODE_MON)) 1455 + continue; 1456 + 1457 + spin_lock_irqsave(&svs_lock, flags); 1458 + svsp->pbank = svsb; 1459 + svs_set_bank_phase(svsp, SVSB_PHASE_MON); 1460 + spin_unlock_irqrestore(&svs_lock, flags); 1461 + } 1462 + } 1463 + 1464 + static int svs_start(struct svs_platform *svsp) 1465 + { 1466 + int ret; 1467 + 1468 + ret = svs_init01(svsp); 1469 + if (ret) 1470 + return ret; 1471 + 1472 + ret = svs_init02(svsp); 1473 + if (ret) 1474 + return ret; 1475 + 1476 + svs_mon_mode(svsp); 1477 + 1478 + return 0; 1479 + } 1480 + 1481 + static int svs_suspend(struct device *dev) 1482 + { 1483 + struct svs_platform *svsp = dev_get_drvdata(dev); 1484 + struct svs_bank *svsb; 1485 + unsigned long flags; 1486 + int ret; 1487 + u32 idx; 1488 + 1489 + for (idx = 0; idx < svsp->bank_max; idx++) { 1490 + svsb = &svsp->banks[idx]; 1491 + 1492 + /* This might wait for svs_isr() process */ 1493 + spin_lock_irqsave(&svs_lock, flags); 1494 + svsp->pbank = svsb; 1495 + svs_switch_bank(svsp); 1496 + svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); 1497 + svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); 1498 + spin_unlock_irqrestore(&svs_lock, flags); 1499 + 1500 + svsb->phase = SVSB_PHASE_ERROR; 1501 + svs_adjust_pm_opp_volts(svsb); 1502 + } 1503 + 1504 + ret = reset_control_assert(svsp->rst); 1505 + if (ret) { 1506 + dev_err(svsp->dev, "cannot assert reset %d\n", ret); 1507 + return ret; 1508 + } 1509 + 1510 + clk_disable_unprepare(svsp->main_clk); 1511 + 1512 + return 0; 1513 + } 1514 + 1515 + static int svs_resume(struct device *dev) 1516 + { 1517 + struct svs_platform *svsp = dev_get_drvdata(dev); 1518 + int ret; 1519 + 1520 + ret = clk_prepare_enable(svsp->main_clk); 1521 + if (ret) { 1522 + dev_err(svsp->dev, "cannot enable main_clk, disable svs\n"); 1523 + return ret; 1524 + } 1525 + 1526 + ret = reset_control_deassert(svsp->rst); 1527 + if (ret) { 1528 + dev_err(svsp->dev, "cannot deassert reset %d\n", ret); 1529 + goto out_of_resume; 1530 + } 1531 + 1532 + ret = svs_init02(svsp); 1533 + if (ret) 1534 + goto out_of_resume; 1535 + 1536 + svs_mon_mode(svsp); 1537 + 1538 + return 0; 1539 + 1540 + out_of_resume: 1541 + clk_disable_unprepare(svsp->main_clk); 1542 + return ret; 1543 + } 1544 + 1545 + static int svs_bank_resource_setup(struct svs_platform *svsp) 1546 + { 1547 + struct svs_bank *svsb; 1548 + struct dev_pm_opp *opp; 1549 + unsigned long freq; 1550 + int count, ret; 1551 + u32 idx, i; 1552 + 1553 + dev_set_drvdata(svsp->dev, svsp); 1554 + 1555 + for (idx = 0; idx < svsp->bank_max; idx++) { 1556 + svsb = &svsp->banks[idx]; 1557 + 1558 + switch (svsb->sw_id) { 1559 + case SVSB_CPU_LITTLE: 1560 + svsb->name = "SVSB_CPU_LITTLE"; 1561 + break; 1562 + case SVSB_CPU_BIG: 1563 + svsb->name = "SVSB_CPU_BIG"; 1564 + break; 1565 + case SVSB_CCI: 1566 + svsb->name = "SVSB_CCI"; 1567 + break; 1568 + case SVSB_GPU: 1569 + if (svsb->type == SVSB_HIGH) 1570 + svsb->name = "SVSB_GPU_HIGH"; 1571 + else if (svsb->type == SVSB_LOW) 1572 + svsb->name = "SVSB_GPU_LOW"; 1573 + else 1574 + svsb->name = "SVSB_GPU"; 1575 + break; 1576 + default: 1577 + dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id); 1578 + return -EINVAL; 1579 + } 1580 + 1581 + svsb->dev = devm_kzalloc(svsp->dev, sizeof(*svsb->dev), 1582 + GFP_KERNEL); 1583 + if (!svsb->dev) 1584 + return -ENOMEM; 1585 + 1586 + ret = dev_set_name(svsb->dev, "%s", svsb->name); 1587 + if (ret) 1588 + return ret; 1589 + 1590 + dev_set_drvdata(svsb->dev, svsp); 1591 + 1592 + ret = dev_pm_opp_of_add_table(svsb->opp_dev); 1593 + if (ret) { 1594 + dev_err(svsb->dev, "add opp table fail: %d\n", ret); 1595 + return ret; 1596 + } 1597 + 1598 + mutex_init(&svsb->lock); 1599 + init_completion(&svsb->init_completion); 1600 + 1601 + if (svsb->mode_support & SVSB_MODE_INIT01) { 1602 + svsb->buck = devm_regulator_get_optional(svsb->opp_dev, 1603 + svsb->buck_name); 1604 + if (IS_ERR(svsb->buck)) { 1605 + dev_err(svsb->dev, "cannot get \"%s-supply\"\n", 1606 + svsb->buck_name); 1607 + return PTR_ERR(svsb->buck); 1608 + } 1609 + } 1610 + 1611 + if (svsb->mode_support & SVSB_MODE_MON) { 1612 + svsb->tzd = thermal_zone_get_zone_by_name(svsb->tzone_name); 1613 + if (IS_ERR(svsb->tzd)) { 1614 + dev_err(svsb->dev, "cannot get \"%s\" thermal zone\n", 1615 + svsb->tzone_name); 1616 + return PTR_ERR(svsb->tzd); 1617 + } 1618 + } 1619 + 1620 + count = dev_pm_opp_get_opp_count(svsb->opp_dev); 1621 + if (svsb->opp_count != count) { 1622 + dev_err(svsb->dev, 1623 + "opp_count not \"%u\" but get \"%d\"?\n", 1624 + svsb->opp_count, count); 1625 + return count; 1626 + } 1627 + 1628 + for (i = 0, freq = U32_MAX; i < svsb->opp_count; i++, freq--) { 1629 + opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq); 1630 + if (IS_ERR(opp)) { 1631 + dev_err(svsb->dev, "cannot find freq = %ld\n", 1632 + PTR_ERR(opp)); 1633 + return PTR_ERR(opp); 1634 + } 1635 + 1636 + svsb->opp_dfreq[i] = freq; 1637 + svsb->opp_dvolt[i] = dev_pm_opp_get_voltage(opp); 1638 + svsb->freq_pct[i] = percent(svsb->opp_dfreq[i], 1639 + svsb->freq_base); 1640 + dev_pm_opp_put(opp); 1641 + } 1642 + } 1643 + 1644 + return 0; 1645 + } 1646 + 1647 + static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp) 1648 + { 1649 + struct svs_bank *svsb; 1650 + struct nvmem_cell *cell; 1651 + u32 idx, i, vmin, golden_temp; 1652 + 1653 + for (i = 0; i < svsp->efuse_max; i++) 1654 + if (svsp->efuse[i]) 1655 + dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n", 1656 + i, svsp->efuse[i]); 1657 + 1658 + if (!svsp->efuse[9]) { 1659 + dev_notice(svsp->dev, "svs_efuse[9] = 0x0?\n"); 1660 + return false; 1661 + } 1662 + 1663 + /* Svs efuse parsing */ 1664 + vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0); 1665 + 1666 + for (idx = 0; idx < svsp->bank_max; idx++) { 1667 + svsb = &svsp->banks[idx]; 1668 + 1669 + if (vmin == 0x1) 1670 + svsb->vmin = 0x1e; 1671 + 1672 + if (svsb->type == SVSB_LOW) { 1673 + svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0); 1674 + svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0); 1675 + svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0); 1676 + svsb->dcbdet = (svsp->efuse[17]) & GENMASK(7, 0); 1677 + svsb->dcmdet = (svsp->efuse[17] >> 8) & GENMASK(7, 0); 1678 + } else if (svsb->type == SVSB_HIGH) { 1679 + svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0); 1680 + svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0); 1681 + svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0); 1682 + svsb->dcbdet = (svsp->efuse[17] >> 16) & GENMASK(7, 0); 1683 + svsb->dcmdet = (svsp->efuse[17] >> 24) & GENMASK(7, 0); 1684 + } 1685 + 1686 + svsb->vmax += svsb->dvt_fixed; 1687 + } 1688 + 1689 + /* Thermal efuse parsing */ 1690 + cell = nvmem_cell_get(svsp->dev, "t-calibration-data"); 1691 + if (IS_ERR_OR_NULL(cell)) { 1692 + dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", 1693 + PTR_ERR(cell)); 1694 + return false; 1695 + } 1696 + 1697 + svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max); 1698 + if (IS_ERR(svsp->tefuse)) { 1699 + dev_err(svsp->dev, "cannot read thermal efuse: %ld\n", 1700 + PTR_ERR(svsp->tefuse)); 1701 + nvmem_cell_put(cell); 1702 + return false; 1703 + } 1704 + 1705 + svsp->tefuse_max /= sizeof(u32); 1706 + nvmem_cell_put(cell); 1707 + 1708 + for (i = 0; i < svsp->tefuse_max; i++) 1709 + if (svsp->tefuse[i] != 0) 1710 + break; 1711 + 1712 + if (i == svsp->tefuse_max) 1713 + golden_temp = 50; /* All thermal efuse data are 0 */ 1714 + else 1715 + golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0); 1716 + 1717 + for (idx = 0; idx < svsp->bank_max; idx++) { 1718 + svsb = &svsp->banks[idx]; 1719 + svsb->mts = 500; 1720 + svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4; 1721 + } 1722 + 1723 + return true; 1724 + } 1725 + 1726 + static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp) 1727 + { 1728 + struct svs_bank *svsb; 1729 + struct nvmem_cell *cell; 1730 + int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0; 1731 + int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t; 1732 + int o_slope, o_slope_sign, ts_id; 1733 + u32 idx, i, ft_pgm, mts, temp0, temp1, temp2; 1734 + 1735 + for (i = 0; i < svsp->efuse_max; i++) 1736 + if (svsp->efuse[i]) 1737 + dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n", 1738 + i, svsp->efuse[i]); 1739 + 1740 + if (!svsp->efuse[2]) { 1741 + dev_notice(svsp->dev, "svs_efuse[2] = 0x0?\n"); 1742 + return false; 1743 + } 1744 + 1745 + /* Svs efuse parsing */ 1746 + ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0); 1747 + 1748 + for (idx = 0; idx < svsp->bank_max; idx++) { 1749 + svsb = &svsp->banks[idx]; 1750 + 1751 + if (ft_pgm <= 1) 1752 + svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE; 1753 + 1754 + switch (svsb->sw_id) { 1755 + case SVSB_CPU_LITTLE: 1756 + svsb->bdes = svsp->efuse[16] & GENMASK(7, 0); 1757 + svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0); 1758 + svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0); 1759 + svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0); 1760 + svsb->mtdes = (svsp->efuse[17] >> 16) & GENMASK(7, 0); 1761 + 1762 + if (ft_pgm <= 3) 1763 + svsb->volt_od += 10; 1764 + else 1765 + svsb->volt_od += 2; 1766 + break; 1767 + case SVSB_CPU_BIG: 1768 + svsb->bdes = svsp->efuse[18] & GENMASK(7, 0); 1769 + svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0); 1770 + svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0); 1771 + svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0); 1772 + svsb->mtdes = svsp->efuse[17] & GENMASK(7, 0); 1773 + 1774 + if (ft_pgm <= 3) 1775 + svsb->volt_od += 15; 1776 + else 1777 + svsb->volt_od += 12; 1778 + break; 1779 + case SVSB_CCI: 1780 + svsb->bdes = svsp->efuse[4] & GENMASK(7, 0); 1781 + svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0); 1782 + svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0); 1783 + svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0); 1784 + svsb->mtdes = (svsp->efuse[5] >> 16) & GENMASK(7, 0); 1785 + 1786 + if (ft_pgm <= 3) 1787 + svsb->volt_od += 10; 1788 + else 1789 + svsb->volt_od += 2; 1790 + break; 1791 + case SVSB_GPU: 1792 + svsb->bdes = svsp->efuse[6] & GENMASK(7, 0); 1793 + svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0); 1794 + svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0); 1795 + svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0); 1796 + svsb->mtdes = svsp->efuse[5] & GENMASK(7, 0); 1797 + 1798 + if (ft_pgm >= 2) { 1799 + svsb->freq_base = 800000000; /* 800MHz */ 1800 + svsb->dvt_fixed = 2; 1801 + } 1802 + break; 1803 + default: 1804 + dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id); 1805 + return false; 1806 + } 1807 + } 1808 + 1809 + /* Get thermal efuse by nvmem */ 1810 + cell = nvmem_cell_get(svsp->dev, "t-calibration-data"); 1811 + if (IS_ERR(cell)) { 1812 + dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", 1813 + PTR_ERR(cell)); 1814 + goto remove_mt8183_svsb_mon_mode; 1815 + } 1816 + 1817 + svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max); 1818 + if (IS_ERR(svsp->tefuse)) { 1819 + dev_err(svsp->dev, "cannot read thermal efuse: %ld\n", 1820 + PTR_ERR(svsp->tefuse)); 1821 + nvmem_cell_put(cell); 1822 + goto remove_mt8183_svsb_mon_mode; 1823 + } 1824 + 1825 + svsp->tefuse_max /= sizeof(u32); 1826 + nvmem_cell_put(cell); 1827 + 1828 + /* Thermal efuse parsing */ 1829 + adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0); 1830 + adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0); 1831 + 1832 + o_vtsmcu[0] = (svsp->tefuse[0] >> 17) & GENMASK(8, 0); 1833 + o_vtsmcu[1] = (svsp->tefuse[0] >> 8) & GENMASK(8, 0); 1834 + o_vtsmcu[2] = svsp->tefuse[1] & GENMASK(8, 0); 1835 + o_vtsmcu[3] = (svsp->tefuse[2] >> 23) & GENMASK(8, 0); 1836 + o_vtsmcu[4] = (svsp->tefuse[2] >> 5) & GENMASK(8, 0); 1837 + o_vtsabb = (svsp->tefuse[2] >> 14) & GENMASK(8, 0); 1838 + 1839 + degc_cali = (svsp->tefuse[0] >> 1) & GENMASK(5, 0); 1840 + adc_cali_en_t = svsp->tefuse[0] & BIT(0); 1841 + o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0); 1842 + 1843 + ts_id = (svsp->tefuse[1] >> 9) & BIT(0); 1844 + o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0); 1845 + 1846 + if (adc_cali_en_t == 1) { 1847 + if (!ts_id) 1848 + o_slope = 0; 1849 + 1850 + if (adc_ge_t < 265 || adc_ge_t > 758 || 1851 + adc_oe_t < 265 || adc_oe_t > 758 || 1852 + o_vtsmcu[0] < -8 || o_vtsmcu[0] > 484 || 1853 + o_vtsmcu[1] < -8 || o_vtsmcu[1] > 484 || 1854 + o_vtsmcu[2] < -8 || o_vtsmcu[2] > 484 || 1855 + o_vtsmcu[3] < -8 || o_vtsmcu[3] > 484 || 1856 + o_vtsmcu[4] < -8 || o_vtsmcu[4] > 484 || 1857 + o_vtsabb < -8 || o_vtsabb > 484 || 1858 + degc_cali < 1 || degc_cali > 63) { 1859 + dev_err(svsp->dev, "bad thermal efuse, no mon mode\n"); 1860 + goto remove_mt8183_svsb_mon_mode; 1861 + } 1862 + } else { 1863 + dev_err(svsp->dev, "no thermal efuse, no mon mode\n"); 1864 + goto remove_mt8183_svsb_mon_mode; 1865 + } 1866 + 1867 + ge = ((adc_ge_t - 512) * 10000) / 4096; 1868 + oe = (adc_oe_t - 512); 1869 + gain = (10000 + ge); 1870 + 1871 + format[0] = (o_vtsmcu[0] + 3350 - oe); 1872 + format[1] = (o_vtsmcu[1] + 3350 - oe); 1873 + format[2] = (o_vtsmcu[2] + 3350 - oe); 1874 + format[3] = (o_vtsmcu[3] + 3350 - oe); 1875 + format[4] = (o_vtsmcu[4] + 3350 - oe); 1876 + format[5] = (o_vtsabb + 3350 - oe); 1877 + 1878 + for (i = 0; i < 6; i++) 1879 + x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / gain; 1880 + 1881 + temp0 = (10000 * 100000 / gain) * 15 / 18; 1882 + 1883 + if (!o_slope_sign) 1884 + mts = (temp0 * 10) / (1534 + o_slope * 10); 1885 + else 1886 + mts = (temp0 * 10) / (1534 - o_slope * 10); 1887 + 1888 + for (idx = 0; idx < svsp->bank_max; idx++) { 1889 + svsb = &svsp->banks[idx]; 1890 + svsb->mts = mts; 1891 + 1892 + switch (svsb->sw_id) { 1893 + case SVSB_CPU_LITTLE: 1894 + tb_roomt = x_roomt[3]; 1895 + break; 1896 + case SVSB_CPU_BIG: 1897 + tb_roomt = x_roomt[4]; 1898 + break; 1899 + case SVSB_CCI: 1900 + tb_roomt = x_roomt[3]; 1901 + break; 1902 + case SVSB_GPU: 1903 + tb_roomt = x_roomt[1]; 1904 + break; 1905 + default: 1906 + dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id); 1907 + goto remove_mt8183_svsb_mon_mode; 1908 + } 1909 + 1910 + temp0 = (degc_cali * 10 / 2); 1911 + temp1 = ((10000 * 100000 / 4096 / gain) * 1912 + oe + tb_roomt * 10) * 15 / 18; 1913 + 1914 + if (!o_slope_sign) 1915 + temp2 = temp1 * 100 / (1534 + o_slope * 10); 1916 + else 1917 + temp2 = temp1 * 100 / (1534 - o_slope * 10); 1918 + 1919 + svsb->bts = (temp0 + temp2 - 250) * 4 / 10; 1920 + } 1921 + 1922 + return true; 1923 + 1924 + remove_mt8183_svsb_mon_mode: 1925 + for (idx = 0; idx < svsp->bank_max; idx++) { 1926 + svsb = &svsp->banks[idx]; 1927 + svsb->mode_support &= ~SVSB_MODE_MON; 1928 + } 1929 + 1930 + return true; 1931 + } 1932 + 1933 + static bool svs_is_efuse_data_correct(struct svs_platform *svsp) 1934 + { 1935 + struct nvmem_cell *cell; 1936 + 1937 + /* Get svs efuse by nvmem */ 1938 + cell = nvmem_cell_get(svsp->dev, "svs-calibration-data"); 1939 + if (IS_ERR(cell)) { 1940 + dev_err(svsp->dev, "no \"svs-calibration-data\"? %ld\n", 1941 + PTR_ERR(cell)); 1942 + return false; 1943 + } 1944 + 1945 + svsp->efuse = nvmem_cell_read(cell, &svsp->efuse_max); 1946 + if (IS_ERR(svsp->efuse)) { 1947 + dev_err(svsp->dev, "cannot read svs efuse: %ld\n", 1948 + PTR_ERR(svsp->efuse)); 1949 + nvmem_cell_put(cell); 1950 + return false; 1951 + } 1952 + 1953 + svsp->efuse_max /= sizeof(u32); 1954 + nvmem_cell_put(cell); 1955 + 1956 + return svsp->efuse_parsing(svsp); 1957 + } 1958 + 1959 + static struct device *svs_get_subsys_device(struct svs_platform *svsp, 1960 + const char *node_name) 1961 + { 1962 + struct platform_device *pdev; 1963 + struct device_node *np; 1964 + 1965 + np = of_find_node_by_name(NULL, node_name); 1966 + if (!np) { 1967 + dev_err(svsp->dev, "cannot find %s node\n", node_name); 1968 + return ERR_PTR(-ENODEV); 1969 + } 1970 + 1971 + pdev = of_find_device_by_node(np); 1972 + if (!pdev) { 1973 + of_node_put(np); 1974 + dev_err(svsp->dev, "cannot find pdev by %s\n", node_name); 1975 + return ERR_PTR(-ENXIO); 1976 + } 1977 + 1978 + of_node_put(np); 1979 + 1980 + return &pdev->dev; 1981 + } 1982 + 1983 + static struct device *svs_add_device_link(struct svs_platform *svsp, 1984 + const char *node_name) 1985 + { 1986 + struct device *dev; 1987 + struct device_link *sup_link; 1988 + 1989 + if (!node_name) { 1990 + dev_err(svsp->dev, "node name cannot be null\n"); 1991 + return ERR_PTR(-EINVAL); 1992 + } 1993 + 1994 + dev = svs_get_subsys_device(svsp, node_name); 1995 + if (IS_ERR(dev)) 1996 + return dev; 1997 + 1998 + sup_link = device_link_add(svsp->dev, dev, 1999 + DL_FLAG_AUTOREMOVE_CONSUMER); 2000 + if (!sup_link) { 2001 + dev_err(svsp->dev, "sup_link is NULL\n"); 2002 + return ERR_PTR(-EINVAL); 2003 + } 2004 + 2005 + if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) 2006 + return ERR_PTR(-EPROBE_DEFER); 2007 + 2008 + return dev; 2009 + } 2010 + 2011 + static int svs_mt8192_platform_probe(struct svs_platform *svsp) 2012 + { 2013 + struct device *dev; 2014 + struct svs_bank *svsb; 2015 + u32 idx; 2016 + 2017 + svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst"); 2018 + if (IS_ERR(svsp->rst)) 2019 + return dev_err_probe(svsp->dev, PTR_ERR(svsp->rst), 2020 + "cannot get svs reset control\n"); 2021 + 2022 + dev = svs_add_device_link(svsp, "lvts"); 2023 + if (IS_ERR(dev)) 2024 + return dev_err_probe(svsp->dev, PTR_ERR(dev), 2025 + "failed to get lvts device\n"); 2026 + 2027 + for (idx = 0; idx < svsp->bank_max; idx++) { 2028 + svsb = &svsp->banks[idx]; 2029 + 2030 + if (svsb->type == SVSB_HIGH) 2031 + svsb->opp_dev = svs_add_device_link(svsp, "mali"); 2032 + else if (svsb->type == SVSB_LOW) 2033 + svsb->opp_dev = svs_get_subsys_device(svsp, "mali"); 2034 + 2035 + if (IS_ERR(svsb->opp_dev)) 2036 + return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev), 2037 + "failed to get OPP device for bank %d\n", 2038 + idx); 2039 + } 2040 + 2041 + return 0; 2042 + } 2043 + 2044 + static int svs_mt8183_platform_probe(struct svs_platform *svsp) 2045 + { 2046 + struct device *dev; 2047 + struct svs_bank *svsb; 2048 + u32 idx; 2049 + 2050 + dev = svs_add_device_link(svsp, "thermal"); 2051 + if (IS_ERR(dev)) 2052 + return dev_err_probe(svsp->dev, PTR_ERR(dev), 2053 + "failed to get thermal device\n"); 2054 + 2055 + for (idx = 0; idx < svsp->bank_max; idx++) { 2056 + svsb = &svsp->banks[idx]; 2057 + 2058 + switch (svsb->sw_id) { 2059 + case SVSB_CPU_LITTLE: 2060 + case SVSB_CPU_BIG: 2061 + svsb->opp_dev = get_cpu_device(svsb->cpu_id); 2062 + break; 2063 + case SVSB_CCI: 2064 + svsb->opp_dev = svs_add_device_link(svsp, "cci"); 2065 + break; 2066 + case SVSB_GPU: 2067 + svsb->opp_dev = svs_add_device_link(svsp, "gpu"); 2068 + break; 2069 + default: 2070 + dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id); 2071 + return -EINVAL; 2072 + } 2073 + 2074 + if (IS_ERR(svsb->opp_dev)) 2075 + return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev), 2076 + "failed to get OPP device for bank %d\n", 2077 + idx); 2078 + } 2079 + 2080 + return 0; 2081 + } 2082 + 2083 + static struct svs_bank svs_mt8192_banks[] = { 2084 + { 2085 + .sw_id = SVSB_GPU, 2086 + .type = SVSB_LOW, 2087 + .set_freq_pct = svs_set_bank_freq_pct_v3, 2088 + .get_volts = svs_get_bank_volts_v3, 2089 + .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT, 2090 + .mode_support = SVSB_MODE_INIT02, 2091 + .opp_count = MAX_OPP_ENTRIES, 2092 + .freq_base = 688000000, 2093 + .turn_freq_base = 688000000, 2094 + .volt_step = 6250, 2095 + .volt_base = 400000, 2096 + .vmax = 0x60, 2097 + .vmin = 0x1a, 2098 + .age_config = 0x555555, 2099 + .dc_config = 0x1, 2100 + .dvt_fixed = 0x1, 2101 + .vco = 0x18, 2102 + .chk_shift = 0x87, 2103 + .core_sel = 0x0fff0100, 2104 + .int_st = BIT(0), 2105 + .ctl0 = 0x00540003, 2106 + }, 2107 + { 2108 + .sw_id = SVSB_GPU, 2109 + .type = SVSB_HIGH, 2110 + .set_freq_pct = svs_set_bank_freq_pct_v3, 2111 + .get_volts = svs_get_bank_volts_v3, 2112 + .tzone_name = "gpu1", 2113 + .volt_flags = SVSB_REMOVE_DVTFIXED_VOLT | 2114 + SVSB_MON_VOLT_IGNORE, 2115 + .mode_support = SVSB_MODE_INIT02 | SVSB_MODE_MON, 2116 + .opp_count = MAX_OPP_ENTRIES, 2117 + .freq_base = 902000000, 2118 + .turn_freq_base = 688000000, 2119 + .volt_step = 6250, 2120 + .volt_base = 400000, 2121 + .vmax = 0x60, 2122 + .vmin = 0x1a, 2123 + .age_config = 0x555555, 2124 + .dc_config = 0x1, 2125 + .dvt_fixed = 0x6, 2126 + .vco = 0x18, 2127 + .chk_shift = 0x87, 2128 + .core_sel = 0x0fff0101, 2129 + .int_st = BIT(1), 2130 + .ctl0 = 0x00540003, 2131 + .tzone_htemp = 85000, 2132 + .tzone_htemp_voffset = 0, 2133 + .tzone_ltemp = 25000, 2134 + .tzone_ltemp_voffset = 7, 2135 + }, 2136 + }; 2137 + 2138 + static struct svs_bank svs_mt8183_banks[] = { 2139 + { 2140 + .sw_id = SVSB_CPU_LITTLE, 2141 + .set_freq_pct = svs_set_bank_freq_pct_v2, 2142 + .get_volts = svs_get_bank_volts_v2, 2143 + .cpu_id = 0, 2144 + .buck_name = "proc", 2145 + .volt_flags = SVSB_INIT01_VOLT_INC_ONLY, 2146 + .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02, 2147 + .opp_count = MAX_OPP_ENTRIES, 2148 + .freq_base = 1989000000, 2149 + .vboot = 0x30, 2150 + .volt_step = 6250, 2151 + .volt_base = 500000, 2152 + .vmax = 0x64, 2153 + .vmin = 0x18, 2154 + .age_config = 0x555555, 2155 + .dc_config = 0x555555, 2156 + .dvt_fixed = 0x7, 2157 + .vco = 0x10, 2158 + .chk_shift = 0x77, 2159 + .core_sel = 0x8fff0000, 2160 + .int_st = BIT(0), 2161 + .ctl0 = 0x00010001, 2162 + }, 2163 + { 2164 + .sw_id = SVSB_CPU_BIG, 2165 + .set_freq_pct = svs_set_bank_freq_pct_v2, 2166 + .get_volts = svs_get_bank_volts_v2, 2167 + .cpu_id = 4, 2168 + .buck_name = "proc", 2169 + .volt_flags = SVSB_INIT01_VOLT_INC_ONLY, 2170 + .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02, 2171 + .opp_count = MAX_OPP_ENTRIES, 2172 + .freq_base = 1989000000, 2173 + .vboot = 0x30, 2174 + .volt_step = 6250, 2175 + .volt_base = 500000, 2176 + .vmax = 0x58, 2177 + .vmin = 0x10, 2178 + .age_config = 0x555555, 2179 + .dc_config = 0x555555, 2180 + .dvt_fixed = 0x7, 2181 + .vco = 0x10, 2182 + .chk_shift = 0x77, 2183 + .core_sel = 0x8fff0001, 2184 + .int_st = BIT(1), 2185 + .ctl0 = 0x00000001, 2186 + }, 2187 + { 2188 + .sw_id = SVSB_CCI, 2189 + .set_freq_pct = svs_set_bank_freq_pct_v2, 2190 + .get_volts = svs_get_bank_volts_v2, 2191 + .buck_name = "proc", 2192 + .volt_flags = SVSB_INIT01_VOLT_INC_ONLY, 2193 + .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02, 2194 + .opp_count = MAX_OPP_ENTRIES, 2195 + .freq_base = 1196000000, 2196 + .vboot = 0x30, 2197 + .volt_step = 6250, 2198 + .volt_base = 500000, 2199 + .vmax = 0x64, 2200 + .vmin = 0x18, 2201 + .age_config = 0x555555, 2202 + .dc_config = 0x555555, 2203 + .dvt_fixed = 0x7, 2204 + .vco = 0x10, 2205 + .chk_shift = 0x77, 2206 + .core_sel = 0x8fff0002, 2207 + .int_st = BIT(2), 2208 + .ctl0 = 0x00100003, 2209 + }, 2210 + { 2211 + .sw_id = SVSB_GPU, 2212 + .set_freq_pct = svs_set_bank_freq_pct_v2, 2213 + .get_volts = svs_get_bank_volts_v2, 2214 + .buck_name = "mali", 2215 + .tzone_name = "tzts2", 2216 + .volt_flags = SVSB_INIT01_PD_REQ | 2217 + SVSB_INIT01_VOLT_INC_ONLY, 2218 + .mode_support = SVSB_MODE_INIT01 | SVSB_MODE_INIT02 | 2219 + SVSB_MODE_MON, 2220 + .opp_count = MAX_OPP_ENTRIES, 2221 + .freq_base = 900000000, 2222 + .vboot = 0x30, 2223 + .volt_step = 6250, 2224 + .volt_base = 500000, 2225 + .vmax = 0x40, 2226 + .vmin = 0x14, 2227 + .age_config = 0x555555, 2228 + .dc_config = 0x555555, 2229 + .dvt_fixed = 0x3, 2230 + .vco = 0x10, 2231 + .chk_shift = 0x77, 2232 + .core_sel = 0x8fff0003, 2233 + .int_st = BIT(3), 2234 + .ctl0 = 0x00050001, 2235 + .tzone_htemp = 85000, 2236 + .tzone_htemp_voffset = 0, 2237 + .tzone_ltemp = 25000, 2238 + .tzone_ltemp_voffset = 3, 2239 + }, 2240 + }; 2241 + 2242 + static const struct svs_platform_data svs_mt8192_platform_data = { 2243 + .name = "mt8192-svs", 2244 + .banks = svs_mt8192_banks, 2245 + .efuse_parsing = svs_mt8192_efuse_parsing, 2246 + .probe = svs_mt8192_platform_probe, 2247 + .irqflags = IRQF_TRIGGER_HIGH, 2248 + .regs = svs_regs_v2, 2249 + .bank_max = ARRAY_SIZE(svs_mt8192_banks), 2250 + }; 2251 + 2252 + static const struct svs_platform_data svs_mt8183_platform_data = { 2253 + .name = "mt8183-svs", 2254 + .banks = svs_mt8183_banks, 2255 + .efuse_parsing = svs_mt8183_efuse_parsing, 2256 + .probe = svs_mt8183_platform_probe, 2257 + .irqflags = IRQF_TRIGGER_LOW, 2258 + .regs = svs_regs_v2, 2259 + .bank_max = ARRAY_SIZE(svs_mt8183_banks), 2260 + }; 2261 + 2262 + static const struct of_device_id svs_of_match[] = { 2263 + { 2264 + .compatible = "mediatek,mt8192-svs", 2265 + .data = &svs_mt8192_platform_data, 2266 + }, { 2267 + .compatible = "mediatek,mt8183-svs", 2268 + .data = &svs_mt8183_platform_data, 2269 + }, { 2270 + /* Sentinel */ 2271 + }, 2272 + }; 2273 + 2274 + static struct svs_platform *svs_platform_probe(struct platform_device *pdev) 2275 + { 2276 + struct svs_platform *svsp; 2277 + const struct svs_platform_data *svsp_data; 2278 + int ret; 2279 + 2280 + svsp_data = of_device_get_match_data(&pdev->dev); 2281 + if (!svsp_data) { 2282 + dev_err(&pdev->dev, "no svs platform data?\n"); 2283 + return ERR_PTR(-EPERM); 2284 + } 2285 + 2286 + svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL); 2287 + if (!svsp) 2288 + return ERR_PTR(-ENOMEM); 2289 + 2290 + svsp->dev = &pdev->dev; 2291 + svsp->name = svsp_data->name; 2292 + svsp->banks = svsp_data->banks; 2293 + svsp->efuse_parsing = svsp_data->efuse_parsing; 2294 + svsp->probe = svsp_data->probe; 2295 + svsp->irqflags = svsp_data->irqflags; 2296 + svsp->regs = svsp_data->regs; 2297 + svsp->bank_max = svsp_data->bank_max; 2298 + 2299 + ret = svsp->probe(svsp); 2300 + if (ret) 2301 + return ERR_PTR(ret); 2302 + 2303 + return svsp; 2304 + } 2305 + 2306 + static int svs_probe(struct platform_device *pdev) 2307 + { 2308 + struct svs_platform *svsp; 2309 + unsigned int svsp_irq; 2310 + int ret; 2311 + 2312 + svsp = svs_platform_probe(pdev); 2313 + if (IS_ERR(svsp)) 2314 + return PTR_ERR(svsp); 2315 + 2316 + if (!svs_is_efuse_data_correct(svsp)) { 2317 + dev_notice(svsp->dev, "efuse data isn't correct\n"); 2318 + ret = -EPERM; 2319 + goto svs_probe_free_resource; 2320 + } 2321 + 2322 + ret = svs_bank_resource_setup(svsp); 2323 + if (ret) { 2324 + dev_err(svsp->dev, "svs bank resource setup fail: %d\n", ret); 2325 + goto svs_probe_free_resource; 2326 + } 2327 + 2328 + svsp_irq = irq_of_parse_and_map(svsp->dev->of_node, 0); 2329 + ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr, 2330 + svsp->irqflags | IRQF_ONESHOT, 2331 + svsp->name, svsp); 2332 + if (ret) { 2333 + dev_err(svsp->dev, "register irq(%d) failed: %d\n", 2334 + svsp_irq, ret); 2335 + goto svs_probe_free_resource; 2336 + } 2337 + 2338 + svsp->main_clk = devm_clk_get(svsp->dev, "main"); 2339 + if (IS_ERR(svsp->main_clk)) { 2340 + dev_err(svsp->dev, "failed to get clock: %ld\n", 2341 + PTR_ERR(svsp->main_clk)); 2342 + ret = PTR_ERR(svsp->main_clk); 2343 + goto svs_probe_free_resource; 2344 + } 2345 + 2346 + ret = clk_prepare_enable(svsp->main_clk); 2347 + if (ret) { 2348 + dev_err(svsp->dev, "cannot enable main clk: %d\n", ret); 2349 + goto svs_probe_free_resource; 2350 + } 2351 + 2352 + svsp->base = of_iomap(svsp->dev->of_node, 0); 2353 + if (IS_ERR_OR_NULL(svsp->base)) { 2354 + dev_err(svsp->dev, "cannot find svs register base\n"); 2355 + ret = -EINVAL; 2356 + goto svs_probe_clk_disable; 2357 + } 2358 + 2359 + ret = svs_start(svsp); 2360 + if (ret) { 2361 + dev_err(svsp->dev, "svs start fail: %d\n", ret); 2362 + goto svs_probe_iounmap; 2363 + } 2364 + 2365 + ret = svs_create_debug_cmds(svsp); 2366 + if (ret) { 2367 + dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret); 2368 + goto svs_probe_iounmap; 2369 + } 2370 + 2371 + return 0; 2372 + 2373 + svs_probe_iounmap: 2374 + iounmap(svsp->base); 2375 + 2376 + svs_probe_clk_disable: 2377 + clk_disable_unprepare(svsp->main_clk); 2378 + 2379 + svs_probe_free_resource: 2380 + if (!IS_ERR_OR_NULL(svsp->efuse)) 2381 + kfree(svsp->efuse); 2382 + if (!IS_ERR_OR_NULL(svsp->tefuse)) 2383 + kfree(svsp->tefuse); 2384 + 2385 + return ret; 2386 + } 2387 + 2388 + static DEFINE_SIMPLE_DEV_PM_OPS(svs_pm_ops, svs_suspend, svs_resume); 2389 + 2390 + static struct platform_driver svs_driver = { 2391 + .probe = svs_probe, 2392 + .driver = { 2393 + .name = "mtk-svs", 2394 + .pm = &svs_pm_ops, 2395 + .of_match_table = of_match_ptr(svs_of_match), 2396 + }, 2397 + }; 2398 + 2399 + module_platform_driver(svs_driver); 2400 + 2401 + MODULE_AUTHOR("Roger Lu <roger.lu@mediatek.com>"); 2402 + MODULE_DESCRIPTION("MediaTek SVS driver"); 2403 + MODULE_LICENSE("GPL");
+16
include/dt-bindings/power/mt6795-power.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 + #ifndef _DT_BINDINGS_POWER_MT6795_POWER_H 3 + #define _DT_BINDINGS_POWER_MT6795_POWER_H 4 + 5 + #define MT6795_POWER_DOMAIN_MM 0 6 + #define MT6795_POWER_DOMAIN_VDEC 1 7 + #define MT6795_POWER_DOMAIN_VENC 2 8 + #define MT6795_POWER_DOMAIN_ISP 3 9 + #define MT6795_POWER_DOMAIN_MJC 4 10 + #define MT6795_POWER_DOMAIN_AUDIO 5 11 + #define MT6795_POWER_DOMAIN_MFG_ASYNC 6 12 + #define MT6795_POWER_DOMAIN_MFG_2D 7 13 + #define MT6795_POWER_DOMAIN_MFG 8 14 + #define MT6795_POWER_DOMAIN_MODEM 9 15 + 16 + #endif /* _DT_BINDINGS_POWER_MT6795_POWER_H */
+27
include/linux/soc/mediatek/mtk-mutex.h
··· 10 10 struct device; 11 11 struct mtk_mutex; 12 12 13 + enum mtk_mutex_mod_index { 14 + /* MDP table index */ 15 + MUTEX_MOD_IDX_MDP_RDMA0, 16 + MUTEX_MOD_IDX_MDP_RSZ0, 17 + MUTEX_MOD_IDX_MDP_RSZ1, 18 + MUTEX_MOD_IDX_MDP_TDSHP0, 19 + MUTEX_MOD_IDX_MDP_WROT0, 20 + MUTEX_MOD_IDX_MDP_WDMA, 21 + MUTEX_MOD_IDX_MDP_AAL0, 22 + MUTEX_MOD_IDX_MDP_CCORR0, 23 + 24 + MUTEX_MOD_IDX_MAX /* ALWAYS keep at the end */ 25 + }; 26 + 27 + enum mtk_mutex_sof_index { 28 + MUTEX_SOF_IDX_SINGLE_MODE, 29 + 30 + MUTEX_SOF_IDX_MAX /* ALWAYS keep at the end */ 31 + }; 32 + 13 33 struct mtk_mutex *mtk_mutex_get(struct device *dev); 14 34 int mtk_mutex_prepare(struct mtk_mutex *mutex); 15 35 void mtk_mutex_add_comp(struct mtk_mutex *mutex, 16 36 enum mtk_ddp_comp_id id); 17 37 void mtk_mutex_enable(struct mtk_mutex *mutex); 38 + int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, 39 + void *pkt); 18 40 void mtk_mutex_disable(struct mtk_mutex *mutex); 19 41 void mtk_mutex_remove_comp(struct mtk_mutex *mutex, 20 42 enum mtk_ddp_comp_id id); ··· 44 22 void mtk_mutex_put(struct mtk_mutex *mutex); 45 23 void mtk_mutex_acquire(struct mtk_mutex *mutex); 46 24 void mtk_mutex_release(struct mtk_mutex *mutex); 25 + int mtk_mutex_write_mod(struct mtk_mutex *mutex, 26 + enum mtk_mutex_mod_index idx, 27 + bool clear); 28 + int mtk_mutex_write_sof(struct mtk_mutex *mutex, 29 + enum mtk_mutex_sof_index idx); 47 30 48 31 #endif /* MTK_MUTEX_H */