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

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

power-domains:
- add support for new power domain driver.
- add support for mt8183 and mt8192

devapc:
- add support for the devapc device found on mt6779 to identify of
malicious bus accesses from a controller to a device

mmsys:
- move DDP routing IDs into the driver

cmdq:
- drop timeout handler support as not usefull

scpsys:
- print warning on theoretical error

* tag 'v5.10-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux: (21 commits)
soc: mediatek: mmsys: Use devm_platform_ioremap_resource()
soc / drm: mediatek: Move DDP component defines into mtk-mmsys.h
soc: mediatek: add mt6779 devapc driver
dt-bindings: devapc: add bindings for mtk-devapc
soc / drm: mediatek: cmdq: Remove timeout handler in helper function
soc: mediatek: pm-domains: Add support for mt8192
soc: mediatek: pm-domains: Add default power off flag
soc: mediatek: pm-domains: Add support for mt8183
soc: mediatek: pm-domains: Allow bus protection to ignore clear ack
soc: mediatek: pm-domains: Add subsystem clocks
soc: mediatek: pm-domains: Add extra sram control
soc: mediatek: pm-domains: Add SMI block as bus protection block
soc: mediatek: pm_domains: Make bus protection generic
soc: mediatek: pm-domains: Add bus protection protocol
soc: mediatek: Add MediaTek SCPSYS power domains
dt-bindings: power: Add MT8192 power domains
dt-bindings: power: Add MT8183 power domains
dt-bindings: power: Add bindings for the Mediatek SCPSYS power domains controller
mfd: syscon: Add syscon_regmap_lookup_by_phandle_optional() function.
MAINTAINERS: change mediatek wiki page
...

Link: https://lore.kernel.org/r/b03fe343-e183-c6f3-f2dc-4c58aae3146b@gmail.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+2243 -100
+293
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/power/mediatek,power-controller.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Mediatek Power Domains Controller 8 + 9 + maintainers: 10 + - Weiyi Lu <weiyi.lu@mediatek.com> 11 + - Matthias Brugger <mbrugger@suse.com> 12 + 13 + description: | 14 + Mediatek processors include support for multiple power domains which can be 15 + powered up/down by software based on different application scenes to save power. 16 + 17 + IP cores belonging to a power domain should contain a 'power-domains' 18 + property that is a phandle for SCPSYS node representing the domain. 19 + 20 + properties: 21 + $nodename: 22 + const: power-controller 23 + 24 + compatible: 25 + enum: 26 + - mediatek,mt8173-power-controller 27 + - mediatek,mt8183-power-controller 28 + - mediatek,mt8192-power-controller 29 + 30 + '#power-domain-cells': 31 + const: 1 32 + 33 + '#address-cells': 34 + const: 1 35 + 36 + '#size-cells': 37 + const: 0 38 + 39 + patternProperties: 40 + "^power-domain@[0-9a-f]+$": 41 + type: object 42 + description: | 43 + Represents the power domains within the power controller node as documented 44 + in Documentation/devicetree/bindings/power/power-domain.yaml. 45 + 46 + properties: 47 + 48 + '#power-domain-cells': 49 + description: 50 + Must be 0 for nodes representing a single PM domain and 1 for nodes 51 + providing multiple PM domains. 52 + 53 + '#address-cells': 54 + const: 1 55 + 56 + '#size-cells': 57 + const: 0 58 + 59 + reg: 60 + description: | 61 + Power domain index. Valid values are defined in: 62 + "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain. 63 + "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain. 64 + "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain. 65 + maxItems: 1 66 + 67 + clocks: 68 + description: | 69 + A number of phandles to clocks that need to be enabled during domain 70 + power-up sequencing. 71 + 72 + clock-names: 73 + description: | 74 + List of names of clocks, in order to match the power-up sequencing 75 + for each power domain we need to group the clocks by name. BASIC 76 + clocks need to be enabled before enabling the corresponding power 77 + domain, and should not have a '-' in their name (i.e mm, mfg, venc). 78 + SUSBYS clocks need to be enabled before releasing the bus protection, 79 + and should contain a '-' in their name (i.e mm-0, isp-0, cam-0). 80 + 81 + In order to follow properly the power-up sequencing, the clocks must 82 + be specified by order, adding first the BASIC clocks followed by the 83 + SUSBSYS clocks. 84 + 85 + mediatek,infracfg: 86 + $ref: /schemas/types.yaml#definitions/phandle 87 + description: phandle to the device containing the INFRACFG register range. 88 + 89 + mediatek,smi: 90 + $ref: /schemas/types.yaml#definitions/phandle 91 + description: phandle to the device containing the SMI register range. 92 + 93 + patternProperties: 94 + "^power-domain@[0-9a-f]+$": 95 + type: object 96 + description: | 97 + Represents a power domain child within a power domain parent node. 98 + 99 + properties: 100 + 101 + '#power-domain-cells': 102 + description: 103 + Must be 0 for nodes representing a single PM domain and 1 for nodes 104 + providing multiple PM domains. 105 + 106 + '#address-cells': 107 + const: 1 108 + 109 + '#size-cells': 110 + const: 0 111 + 112 + reg: 113 + maxItems: 1 114 + 115 + clocks: 116 + description: | 117 + A number of phandles to clocks that need to be enabled during domain 118 + power-up sequencing. 119 + 120 + clock-names: 121 + description: | 122 + List of names of clocks, in order to match the power-up sequencing 123 + for each power domain we need to group the clocks by name. BASIC 124 + clocks need to be enabled before enabling the corresponding power 125 + domain, and should not have a '-' in their name (i.e mm, mfg, venc). 126 + SUSBYS clocks need to be enabled before releasing the bus protection, 127 + and should contain a '-' in their name (i.e mm-0, isp-0, cam-0). 128 + 129 + In order to follow properly the power-up sequencing, the clocks must 130 + be specified by order, adding first the BASIC clocks followed by the 131 + SUSBSYS clocks. 132 + 133 + mediatek,infracfg: 134 + $ref: /schemas/types.yaml#definitions/phandle 135 + description: phandle to the device containing the INFRACFG register range. 136 + 137 + mediatek,smi: 138 + $ref: /schemas/types.yaml#definitions/phandle 139 + description: phandle to the device containing the SMI register range. 140 + 141 + patternProperties: 142 + "^power-domain@[0-9a-f]+$": 143 + type: object 144 + description: | 145 + Represents a power domain child within a power domain parent node. 146 + 147 + properties: 148 + 149 + '#power-domain-cells': 150 + description: 151 + Must be 0 for nodes representing a single PM domain and 1 for nodes 152 + providing multiple PM domains. 153 + 154 + '#address-cells': 155 + const: 1 156 + 157 + '#size-cells': 158 + const: 0 159 + 160 + reg: 161 + maxItems: 1 162 + 163 + clocks: 164 + description: | 165 + A number of phandles to clocks that need to be enabled during domain 166 + power-up sequencing. 167 + 168 + clock-names: 169 + description: | 170 + List of names of clocks, in order to match the power-up sequencing 171 + for each power domain we need to group the clocks by name. BASIC 172 + clocks need to be enabled before enabling the corresponding power 173 + domain, and should not have a '-' in their name (i.e mm, mfg, venc). 174 + SUSBYS clocks need to be enabled before releasing the bus protection, 175 + and should contain a '-' in their name (i.e mm-0, isp-0, cam-0). 176 + 177 + In order to follow properly the power-up sequencing, the clocks must 178 + be specified by order, adding first the BASIC clocks followed by the 179 + SUSBSYS clocks. 180 + 181 + mediatek,infracfg: 182 + $ref: /schemas/types.yaml#definitions/phandle 183 + description: phandle to the device containing the INFRACFG register range. 184 + 185 + mediatek,smi: 186 + $ref: /schemas/types.yaml#definitions/phandle 187 + description: phandle to the device containing the SMI register range. 188 + 189 + required: 190 + - reg 191 + 192 + additionalProperties: false 193 + 194 + required: 195 + - reg 196 + 197 + additionalProperties: false 198 + 199 + required: 200 + - reg 201 + 202 + additionalProperties: false 203 + 204 + required: 205 + - compatible 206 + 207 + additionalProperties: false 208 + 209 + examples: 210 + - | 211 + #include <dt-bindings/clock/mt8173-clk.h> 212 + #include <dt-bindings/power/mt8173-power.h> 213 + 214 + soc { 215 + #address-cells = <2>; 216 + #size-cells = <2>; 217 + 218 + scpsys: syscon@10006000 { 219 + compatible = "syscon", "simple-mfd"; 220 + reg = <0 0x10006000 0 0x1000>; 221 + 222 + spm: power-controller { 223 + compatible = "mediatek,mt8173-power-controller"; 224 + #address-cells = <1>; 225 + #size-cells = <0>; 226 + #power-domain-cells = <1>; 227 + 228 + /* power domains of the SoC */ 229 + power-domain@MT8173_POWER_DOMAIN_VDEC { 230 + reg = <MT8173_POWER_DOMAIN_VDEC>; 231 + clocks = <&topckgen CLK_TOP_MM_SEL>; 232 + clock-names = "mm"; 233 + #power-domain-cells = <0>; 234 + }; 235 + power-domain@MT8173_POWER_DOMAIN_VENC { 236 + reg = <MT8173_POWER_DOMAIN_VENC>; 237 + clocks = <&topckgen CLK_TOP_MM_SEL>, 238 + <&topckgen CLK_TOP_VENC_SEL>; 239 + clock-names = "mm", "venc"; 240 + #power-domain-cells = <0>; 241 + }; 242 + power-domain@MT8173_POWER_DOMAIN_ISP { 243 + reg = <MT8173_POWER_DOMAIN_ISP>; 244 + clocks = <&topckgen CLK_TOP_MM_SEL>; 245 + clock-names = "mm"; 246 + #power-domain-cells = <0>; 247 + }; 248 + power-domain@MT8173_POWER_DOMAIN_MM { 249 + reg = <MT8173_POWER_DOMAIN_MM>; 250 + clocks = <&topckgen CLK_TOP_MM_SEL>; 251 + clock-names = "mm"; 252 + #power-domain-cells = <0>; 253 + mediatek,infracfg = <&infracfg>; 254 + }; 255 + power-domain@MT8173_POWER_DOMAIN_VENC_LT { 256 + reg = <MT8173_POWER_DOMAIN_VENC_LT>; 257 + clocks = <&topckgen CLK_TOP_MM_SEL>, 258 + <&topckgen CLK_TOP_VENC_LT_SEL>; 259 + clock-names = "mm", "venclt"; 260 + #power-domain-cells = <0>; 261 + }; 262 + power-domain@MT8173_POWER_DOMAIN_AUDIO { 263 + reg = <MT8173_POWER_DOMAIN_AUDIO>; 264 + #power-domain-cells = <0>; 265 + }; 266 + power-domain@MT8173_POWER_DOMAIN_USB { 267 + reg = <MT8173_POWER_DOMAIN_USB>; 268 + #power-domain-cells = <0>; 269 + }; 270 + power-domain@MT8173_POWER_DOMAIN_MFG_ASYNC { 271 + reg = <MT8173_POWER_DOMAIN_MFG_ASYNC>; 272 + clocks = <&clk26m>; 273 + clock-names = "mfg"; 274 + #address-cells = <1>; 275 + #size-cells = <0>; 276 + #power-domain-cells = <1>; 277 + 278 + power-domain@MT8173_POWER_DOMAIN_MFG_2D { 279 + reg = <MT8173_POWER_DOMAIN_MFG_2D>; 280 + #address-cells = <1>; 281 + #size-cells = <0>; 282 + #power-domain-cells = <1>; 283 + 284 + power-domain@MT8173_POWER_DOMAIN_MFG { 285 + reg = <MT8173_POWER_DOMAIN_MFG>; 286 + #power-domain-cells = <0>; 287 + mediatek,infracfg = <&infracfg>; 288 + }; 289 + }; 290 + }; 291 + }; 292 + }; 293 + };
+58
Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # # Copyright 2020 MediaTek Inc. 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/soc/mediatek/devapc.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: MediaTek Device Access Permission Control driver 9 + 10 + description: | 11 + MediaTek bus fabric provides TrustZone security support and data 12 + protection to prevent slaves from being accessed by unexpected masters. 13 + The security violation is logged and sent to the processor for further 14 + analysis and countermeasures. 15 + 16 + maintainers: 17 + - Neal Liu <neal.liu@mediatek.com> 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - mediatek,mt6779-devapc 23 + 24 + reg: 25 + description: The base address of devapc register bank 26 + maxItems: 1 27 + 28 + interrupts: 29 + description: A single interrupt specifier 30 + maxItems: 1 31 + 32 + clocks: 33 + description: Contains module clock source and clock names 34 + maxItems: 1 35 + 36 + clock-names: 37 + description: Names of the clocks list in clocks property 38 + maxItems: 1 39 + 40 + required: 41 + - compatible 42 + - reg 43 + - interrupts 44 + - clocks 45 + - clock-names 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/interrupt-controller/arm-gic.h> 50 + #include <dt-bindings/clock/mt6779-clk.h> 51 + 52 + devapc: devapc@10207000 { 53 + compatible = "mediatek,mt6779-devapc"; 54 + reg = <0x10207000 0x1000>; 55 + interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>; 56 + clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>; 57 + clock-names = "devapc-infra-clock"; 58 + };
+1 -1
MAINTAINERS
··· 2067 2067 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2068 2068 L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) 2069 2069 S: Maintained 2070 - W: https://mtk.bcnfs.org/ 2070 + W: https://mtk.wiki.kernel.org/ 2071 2071 C: irc://chat.freenode.net/linux-mediatek 2072 2072 F: arch/arm/boot/dts/mt6* 2073 2073 F: arch/arm/boot/dts/mt7*
+1 -2
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
··· 824 824 #if IS_REACHABLE(CONFIG_MTK_CMDQ) 825 825 mtk_crtc->cmdq_client = 826 826 cmdq_mbox_create(mtk_crtc->mmsys_dev, 827 - drm_crtc_index(&mtk_crtc->base), 828 - 2000); 827 + drm_crtc_index(&mtk_crtc->base)); 829 828 if (IS_ERR(mtk_crtc->cmdq_client)) { 830 829 dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n", 831 830 drm_crtc_index(&mtk_crtc->base));
+1 -33
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
··· 7 7 #define MTK_DRM_DDP_COMP_H 8 8 9 9 #include <linux/io.h> 10 + #include <linux/soc/mediatek/mtk-mmsys.h> 10 11 11 12 struct device; 12 13 struct device_node; ··· 34 33 MTK_DISP_OD, 35 34 MTK_DISP_BLS, 36 35 MTK_DDP_COMP_TYPE_MAX, 37 - }; 38 - 39 - enum mtk_ddp_comp_id { 40 - DDP_COMPONENT_AAL0, 41 - DDP_COMPONENT_AAL1, 42 - DDP_COMPONENT_BLS, 43 - DDP_COMPONENT_CCORR, 44 - DDP_COMPONENT_COLOR0, 45 - DDP_COMPONENT_COLOR1, 46 - DDP_COMPONENT_DITHER, 47 - DDP_COMPONENT_DPI0, 48 - DDP_COMPONENT_DPI1, 49 - DDP_COMPONENT_DSI0, 50 - DDP_COMPONENT_DSI1, 51 - DDP_COMPONENT_DSI2, 52 - DDP_COMPONENT_DSI3, 53 - DDP_COMPONENT_GAMMA, 54 - DDP_COMPONENT_OD0, 55 - DDP_COMPONENT_OD1, 56 - DDP_COMPONENT_OVL0, 57 - DDP_COMPONENT_OVL_2L0, 58 - DDP_COMPONENT_OVL_2L1, 59 - DDP_COMPONENT_OVL1, 60 - DDP_COMPONENT_PWM0, 61 - DDP_COMPONENT_PWM1, 62 - DDP_COMPONENT_PWM2, 63 - DDP_COMPONENT_RDMA0, 64 - DDP_COMPONENT_RDMA1, 65 - DDP_COMPONENT_RDMA2, 66 - DDP_COMPONENT_UFOE, 67 - DDP_COMPONENT_WDMA0, 68 - DDP_COMPONENT_WDMA1, 69 - DDP_COMPONENT_ID_MAX, 70 36 }; 71 37 72 38 struct mtk_ddp_comp;
+18
drivers/mfd/syscon.c
··· 255 255 } 256 256 EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_args); 257 257 258 + /* 259 + * It behaves the same as syscon_regmap_lookup_by_phandle() except where 260 + * there is no regmap phandle. In this case, instead of returning -ENODEV, 261 + * the function returns NULL. 262 + */ 263 + struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np, 264 + const char *property) 265 + { 266 + struct regmap *regmap; 267 + 268 + regmap = syscon_regmap_lookup_by_phandle(np, property); 269 + if (IS_ERR(regmap) && PTR_ERR(regmap) == -ENODEV) 270 + return NULL; 271 + 272 + return regmap; 273 + } 274 + EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional); 275 + 258 276 static int syscon_probe(struct platform_device *pdev) 259 277 { 260 278 struct device *dev = &pdev->dev;
+21
drivers/soc/mediatek/Kconfig
··· 17 17 time limitation, such as updating display configuration during the 18 18 vblank. 19 19 20 + config MTK_DEVAPC 21 + tristate "Mediatek Device APC Support" 22 + help 23 + Say yes here to enable support for Mediatek Device APC driver. 24 + This driver is mainly used to handle the violation which catches 25 + unexpected transaction. 26 + The violation information is logged for further analysis or 27 + countermeasures. 28 + 20 29 config MTK_INFRACFG 21 30 bool "MediaTek INFRACFG Support" 22 31 select REGMAP ··· 52 43 help 53 44 Say yes here to add support for the MediaTek SCPSYS power domain 54 45 driver. 46 + 47 + config MTK_SCPSYS_PM_DOMAINS 48 + bool "MediaTek SCPSYS generic power domain" 49 + default ARCH_MEDIATEK 50 + depends on PM 51 + select PM_GENERIC_DOMAINS 52 + select REGMAP 53 + help 54 + Say y here to enable power domain support. 55 + In order to meet high performance and low power requirements, the System 56 + Control Processor System (SCPSYS) has several power management related 57 + tasks in the system. 55 58 56 59 config MTK_MMSYS 57 60 bool "MediaTek MMSYS Support"
+2
drivers/soc/mediatek/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o 3 + obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o 3 4 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o 4 5 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o 5 6 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o 7 + obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o 6 8 obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
+94
drivers/soc/mediatek/mt8173-pm-domains.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __SOC_MEDIATEK_MT8173_PM_DOMAINS_H 4 + #define __SOC_MEDIATEK_MT8173_PM_DOMAINS_H 5 + 6 + #include "mtk-pm-domains.h" 7 + #include <dt-bindings/power/mt8173-power.h> 8 + 9 + /* 10 + * MT8173 power domain support 11 + */ 12 + 13 + static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { 14 + [MT8173_POWER_DOMAIN_VDEC] = { 15 + .sta_mask = PWR_STATUS_VDEC, 16 + .ctl_offs = SPM_VDE_PWR_CON, 17 + .sram_pdn_bits = GENMASK(11, 8), 18 + .sram_pdn_ack_bits = GENMASK(12, 12), 19 + }, 20 + [MT8173_POWER_DOMAIN_VENC] = { 21 + .sta_mask = PWR_STATUS_VENC, 22 + .ctl_offs = SPM_VEN_PWR_CON, 23 + .sram_pdn_bits = GENMASK(11, 8), 24 + .sram_pdn_ack_bits = GENMASK(15, 12), 25 + }, 26 + [MT8173_POWER_DOMAIN_ISP] = { 27 + .sta_mask = PWR_STATUS_ISP, 28 + .ctl_offs = SPM_ISP_PWR_CON, 29 + .sram_pdn_bits = GENMASK(11, 8), 30 + .sram_pdn_ack_bits = GENMASK(13, 12), 31 + }, 32 + [MT8173_POWER_DOMAIN_MM] = { 33 + .sta_mask = PWR_STATUS_DISP, 34 + .ctl_offs = SPM_DIS_PWR_CON, 35 + .sram_pdn_bits = GENMASK(11, 8), 36 + .sram_pdn_ack_bits = GENMASK(12, 12), 37 + .bp_infracfg = { 38 + BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 | 39 + MT8173_TOP_AXI_PROT_EN_MM_M1), 40 + }, 41 + }, 42 + [MT8173_POWER_DOMAIN_VENC_LT] = { 43 + .sta_mask = PWR_STATUS_VENC_LT, 44 + .ctl_offs = SPM_VEN2_PWR_CON, 45 + .sram_pdn_bits = GENMASK(11, 8), 46 + .sram_pdn_ack_bits = GENMASK(15, 12), 47 + }, 48 + [MT8173_POWER_DOMAIN_AUDIO] = { 49 + .sta_mask = PWR_STATUS_AUDIO, 50 + .ctl_offs = SPM_AUDIO_PWR_CON, 51 + .sram_pdn_bits = GENMASK(11, 8), 52 + .sram_pdn_ack_bits = GENMASK(15, 12), 53 + }, 54 + [MT8173_POWER_DOMAIN_USB] = { 55 + .sta_mask = PWR_STATUS_USB, 56 + .ctl_offs = SPM_USB_PWR_CON, 57 + .sram_pdn_bits = GENMASK(11, 8), 58 + .sram_pdn_ack_bits = GENMASK(15, 12), 59 + .caps = MTK_SCPD_ACTIVE_WAKEUP, 60 + }, 61 + [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 62 + .sta_mask = PWR_STATUS_MFG_ASYNC, 63 + .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 64 + .sram_pdn_bits = GENMASK(11, 8), 65 + .sram_pdn_ack_bits = 0, 66 + }, 67 + [MT8173_POWER_DOMAIN_MFG_2D] = { 68 + .sta_mask = PWR_STATUS_MFG_2D, 69 + .ctl_offs = SPM_MFG_2D_PWR_CON, 70 + .sram_pdn_bits = GENMASK(11, 8), 71 + .sram_pdn_ack_bits = GENMASK(13, 12), 72 + }, 73 + [MT8173_POWER_DOMAIN_MFG] = { 74 + .sta_mask = PWR_STATUS_MFG, 75 + .ctl_offs = SPM_MFG_PWR_CON, 76 + .sram_pdn_bits = GENMASK(13, 8), 77 + .sram_pdn_ack_bits = GENMASK(21, 16), 78 + .bp_infracfg = { 79 + BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S | 80 + MT8173_TOP_AXI_PROT_EN_MFG_M0 | 81 + MT8173_TOP_AXI_PROT_EN_MFG_M1 | 82 + MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT), 83 + }, 84 + }, 85 + }; 86 + 87 + static const struct scpsys_soc_data mt8173_scpsys_data = { 88 + .domains_data = scpsys_domain_data_mt8173, 89 + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173), 90 + .pwr_sta_offs = SPM_PWR_STATUS, 91 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, 92 + }; 93 + 94 + #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
+221
drivers/soc/mediatek/mt8183-pm-domains.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __SOC_MEDIATEK_MT8183_PM_DOMAINS_H 4 + #define __SOC_MEDIATEK_MT8183_PM_DOMAINS_H 5 + 6 + #include "mtk-pm-domains.h" 7 + #include <dt-bindings/power/mt8183-power.h> 8 + 9 + /* 10 + * MT8183 power domain support 11 + */ 12 + 13 + static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { 14 + [MT8183_POWER_DOMAIN_AUDIO] = { 15 + .sta_mask = PWR_STATUS_AUDIO, 16 + .ctl_offs = 0x0314, 17 + .sram_pdn_bits = GENMASK(11, 8), 18 + .sram_pdn_ack_bits = GENMASK(15, 12), 19 + }, 20 + [MT8183_POWER_DOMAIN_CONN] = { 21 + .sta_mask = PWR_STATUS_CONN, 22 + .ctl_offs = 0x032c, 23 + .sram_pdn_bits = 0, 24 + .sram_pdn_ack_bits = 0, 25 + .bp_infracfg = { 26 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CONN, MT8183_TOP_AXI_PROT_EN_SET, 27 + MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1), 28 + }, 29 + }, 30 + [MT8183_POWER_DOMAIN_MFG_ASYNC] = { 31 + .sta_mask = PWR_STATUS_MFG_ASYNC, 32 + .ctl_offs = 0x0334, 33 + .sram_pdn_bits = 0, 34 + .sram_pdn_ack_bits = 0, 35 + }, 36 + [MT8183_POWER_DOMAIN_MFG] = { 37 + .sta_mask = PWR_STATUS_MFG, 38 + .ctl_offs = 0x0338, 39 + .sram_pdn_bits = GENMASK(8, 8), 40 + .sram_pdn_ack_bits = GENMASK(12, 12), 41 + }, 42 + [MT8183_POWER_DOMAIN_MFG_CORE0] = { 43 + .sta_mask = BIT(7), 44 + .ctl_offs = 0x034c, 45 + .sram_pdn_bits = GENMASK(8, 8), 46 + .sram_pdn_ack_bits = GENMASK(12, 12), 47 + }, 48 + [MT8183_POWER_DOMAIN_MFG_CORE1] = { 49 + .sta_mask = BIT(20), 50 + .ctl_offs = 0x0310, 51 + .sram_pdn_bits = GENMASK(8, 8), 52 + .sram_pdn_ack_bits = GENMASK(12, 12), 53 + }, 54 + [MT8183_POWER_DOMAIN_MFG_2D] = { 55 + .sta_mask = PWR_STATUS_MFG_2D, 56 + .ctl_offs = 0x0348, 57 + .sram_pdn_bits = GENMASK(8, 8), 58 + .sram_pdn_ack_bits = GENMASK(12, 12), 59 + .bp_infracfg = { 60 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_MFG, MT8183_TOP_AXI_PROT_EN_1_SET, 61 + MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1), 62 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MFG, MT8183_TOP_AXI_PROT_EN_SET, 63 + MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1), 64 + }, 65 + }, 66 + [MT8183_POWER_DOMAIN_DISP] = { 67 + .sta_mask = PWR_STATUS_DISP, 68 + .ctl_offs = 0x030c, 69 + .sram_pdn_bits = GENMASK(8, 8), 70 + .sram_pdn_ack_bits = GENMASK(12, 12), 71 + .bp_infracfg = { 72 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_DISP, MT8183_TOP_AXI_PROT_EN_1_SET, 73 + MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1), 74 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_DISP, MT8183_TOP_AXI_PROT_EN_SET, 75 + MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1), 76 + }, 77 + .bp_smi = { 78 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_DISP, 79 + MT8183_SMI_COMMON_CLAMP_EN_SET, 80 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 81 + MT8183_SMI_COMMON_CLAMP_EN), 82 + }, 83 + }, 84 + [MT8183_POWER_DOMAIN_CAM] = { 85 + .sta_mask = BIT(25), 86 + .ctl_offs = 0x0344, 87 + .sram_pdn_bits = GENMASK(9, 8), 88 + .sram_pdn_ack_bits = GENMASK(13, 12), 89 + .bp_infracfg = { 90 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_CAM, MT8183_TOP_AXI_PROT_EN_MM_SET, 91 + MT8183_TOP_AXI_PROT_EN_MM_CLR, MT8183_TOP_AXI_PROT_EN_MM_STA1), 92 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CAM, MT8183_TOP_AXI_PROT_EN_SET, 93 + MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1), 94 + BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND, 95 + MT8183_TOP_AXI_PROT_EN_MM_SET, 96 + MT8183_TOP_AXI_PROT_EN_MM_CLR, 97 + MT8183_TOP_AXI_PROT_EN_MM_STA1), 98 + }, 99 + .bp_smi = { 100 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_CAM, 101 + MT8183_SMI_COMMON_CLAMP_EN_SET, 102 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 103 + MT8183_SMI_COMMON_CLAMP_EN), 104 + }, 105 + }, 106 + [MT8183_POWER_DOMAIN_ISP] = { 107 + .sta_mask = PWR_STATUS_ISP, 108 + .ctl_offs = 0x0308, 109 + .sram_pdn_bits = GENMASK(9, 8), 110 + .sram_pdn_ack_bits = GENMASK(13, 12), 111 + .bp_infracfg = { 112 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_ISP, 113 + MT8183_TOP_AXI_PROT_EN_MM_SET, 114 + MT8183_TOP_AXI_PROT_EN_MM_CLR, 115 + MT8183_TOP_AXI_PROT_EN_MM_STA1), 116 + BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND, 117 + MT8183_TOP_AXI_PROT_EN_MM_SET, 118 + MT8183_TOP_AXI_PROT_EN_MM_CLR, 119 + MT8183_TOP_AXI_PROT_EN_MM_STA1), 120 + }, 121 + .bp_smi = { 122 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_ISP, 123 + MT8183_SMI_COMMON_CLAMP_EN_SET, 124 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 125 + MT8183_SMI_COMMON_CLAMP_EN), 126 + }, 127 + }, 128 + [MT8183_POWER_DOMAIN_VDEC] = { 129 + .sta_mask = BIT(31), 130 + .ctl_offs = 0x0300, 131 + .sram_pdn_bits = GENMASK(8, 8), 132 + .sram_pdn_ack_bits = GENMASK(12, 12), 133 + .bp_smi = { 134 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VDEC, 135 + MT8183_SMI_COMMON_CLAMP_EN_SET, 136 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 137 + MT8183_SMI_COMMON_CLAMP_EN), 138 + }, 139 + }, 140 + [MT8183_POWER_DOMAIN_VENC] = { 141 + .sta_mask = PWR_STATUS_VENC, 142 + .ctl_offs = 0x0304, 143 + .sram_pdn_bits = GENMASK(11, 8), 144 + .sram_pdn_ack_bits = GENMASK(15, 12), 145 + .bp_smi = { 146 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VENC, 147 + MT8183_SMI_COMMON_CLAMP_EN_SET, 148 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 149 + MT8183_SMI_COMMON_CLAMP_EN), 150 + }, 151 + }, 152 + [MT8183_POWER_DOMAIN_VPU_TOP] = { 153 + .sta_mask = BIT(26), 154 + .ctl_offs = 0x0324, 155 + .sram_pdn_bits = GENMASK(8, 8), 156 + .sram_pdn_ack_bits = GENMASK(12, 12), 157 + .bp_infracfg = { 158 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP, 159 + MT8183_TOP_AXI_PROT_EN_MM_SET, 160 + MT8183_TOP_AXI_PROT_EN_MM_CLR, 161 + MT8183_TOP_AXI_PROT_EN_MM_STA1), 162 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_VPU_TOP, 163 + MT8183_TOP_AXI_PROT_EN_SET, 164 + MT8183_TOP_AXI_PROT_EN_CLR, 165 + MT8183_TOP_AXI_PROT_EN_STA1), 166 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND, 167 + MT8183_TOP_AXI_PROT_EN_MM_SET, 168 + MT8183_TOP_AXI_PROT_EN_MM_CLR, 169 + MT8183_TOP_AXI_PROT_EN_MM_STA1), 170 + }, 171 + .bp_smi = { 172 + BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP, 173 + MT8183_SMI_COMMON_CLAMP_EN_SET, 174 + MT8183_SMI_COMMON_CLAMP_EN_CLR, 175 + MT8183_SMI_COMMON_CLAMP_EN), 176 + }, 177 + }, 178 + [MT8183_POWER_DOMAIN_VPU_CORE0] = { 179 + .sta_mask = BIT(27), 180 + .ctl_offs = 0x33c, 181 + .sram_pdn_bits = GENMASK(11, 8), 182 + .sram_pdn_ack_bits = GENMASK(13, 12), 183 + .bp_infracfg = { 184 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0, 185 + MT8183_TOP_AXI_PROT_EN_MCU_SET, 186 + MT8183_TOP_AXI_PROT_EN_MCU_CLR, 187 + MT8183_TOP_AXI_PROT_EN_MCU_STA1), 188 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND, 189 + MT8183_TOP_AXI_PROT_EN_MCU_SET, 190 + MT8183_TOP_AXI_PROT_EN_MCU_CLR, 191 + MT8183_TOP_AXI_PROT_EN_MCU_STA1), 192 + }, 193 + .caps = MTK_SCPD_SRAM_ISO, 194 + }, 195 + [MT8183_POWER_DOMAIN_VPU_CORE1] = { 196 + .sta_mask = BIT(28), 197 + .ctl_offs = 0x0340, 198 + .sram_pdn_bits = GENMASK(11, 8), 199 + .sram_pdn_ack_bits = GENMASK(13, 12), 200 + .bp_infracfg = { 201 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1, 202 + MT8183_TOP_AXI_PROT_EN_MCU_SET, 203 + MT8183_TOP_AXI_PROT_EN_MCU_CLR, 204 + MT8183_TOP_AXI_PROT_EN_MCU_STA1), 205 + BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND, 206 + MT8183_TOP_AXI_PROT_EN_MCU_SET, 207 + MT8183_TOP_AXI_PROT_EN_MCU_CLR, 208 + MT8183_TOP_AXI_PROT_EN_MCU_STA1), 209 + }, 210 + .caps = MTK_SCPD_SRAM_ISO, 211 + }, 212 + }; 213 + 214 + static const struct scpsys_soc_data mt8183_scpsys_data = { 215 + .domains_data = scpsys_domain_data_mt8183, 216 + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183), 217 + .pwr_sta_offs = 0x0180, 218 + .pwr_sta2nd_offs = 0x0184 219 + }; 220 + 221 + #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
+292
drivers/soc/mediatek/mt8192-pm-domains.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __SOC_MEDIATEK_MT8192_PM_DOMAINS_H 4 + #define __SOC_MEDIATEK_MT8192_PM_DOMAINS_H 5 + 6 + #include "mtk-pm-domains.h" 7 + #include <dt-bindings/power/mt8192-power.h> 8 + 9 + /* 10 + * MT8192 power domain support 11 + */ 12 + 13 + static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { 14 + [MT8192_POWER_DOMAIN_AUDIO] = { 15 + .sta_mask = BIT(21), 16 + .ctl_offs = 0x0354, 17 + .sram_pdn_bits = GENMASK(8, 8), 18 + .sram_pdn_ack_bits = GENMASK(12, 12), 19 + .bp_infracfg = { 20 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_AUDIO, 21 + MT8192_TOP_AXI_PROT_EN_2_SET, 22 + MT8192_TOP_AXI_PROT_EN_2_CLR, 23 + MT8192_TOP_AXI_PROT_EN_2_STA1), 24 + }, 25 + }, 26 + [MT8192_POWER_DOMAIN_CONN] = { 27 + .sta_mask = PWR_STATUS_CONN, 28 + .ctl_offs = 0x0304, 29 + .sram_pdn_bits = 0, 30 + .sram_pdn_ack_bits = 0, 31 + .bp_infracfg = { 32 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN, 33 + MT8192_TOP_AXI_PROT_EN_SET, 34 + MT8192_TOP_AXI_PROT_EN_CLR, 35 + MT8192_TOP_AXI_PROT_EN_STA1), 36 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN_2ND, 37 + MT8192_TOP_AXI_PROT_EN_SET, 38 + MT8192_TOP_AXI_PROT_EN_CLR, 39 + MT8192_TOP_AXI_PROT_EN_STA1), 40 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CONN, 41 + MT8192_TOP_AXI_PROT_EN_1_SET, 42 + MT8192_TOP_AXI_PROT_EN_1_CLR, 43 + MT8192_TOP_AXI_PROT_EN_1_STA1), 44 + }, 45 + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, 46 + }, 47 + [MT8192_POWER_DOMAIN_MFG0] = { 48 + .sta_mask = BIT(2), 49 + .ctl_offs = 0x0308, 50 + .sram_pdn_bits = GENMASK(8, 8), 51 + .sram_pdn_ack_bits = GENMASK(12, 12), 52 + }, 53 + [MT8192_POWER_DOMAIN_MFG1] = { 54 + .sta_mask = BIT(3), 55 + .ctl_offs = 0x030c, 56 + .sram_pdn_bits = GENMASK(8, 8), 57 + .sram_pdn_ack_bits = GENMASK(12, 12), 58 + .bp_infracfg = { 59 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_MFG1, 60 + MT8192_TOP_AXI_PROT_EN_1_SET, 61 + MT8192_TOP_AXI_PROT_EN_1_CLR, 62 + MT8192_TOP_AXI_PROT_EN_1_STA1), 63 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1, 64 + MT8192_TOP_AXI_PROT_EN_2_SET, 65 + MT8192_TOP_AXI_PROT_EN_2_CLR, 66 + MT8192_TOP_AXI_PROT_EN_2_STA1), 67 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MFG1, 68 + MT8192_TOP_AXI_PROT_EN_SET, 69 + MT8192_TOP_AXI_PROT_EN_CLR, 70 + MT8192_TOP_AXI_PROT_EN_STA1), 71 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND, 72 + MT8192_TOP_AXI_PROT_EN_2_SET, 73 + MT8192_TOP_AXI_PROT_EN_2_CLR, 74 + MT8192_TOP_AXI_PROT_EN_2_STA1), 75 + }, 76 + }, 77 + [MT8192_POWER_DOMAIN_MFG2] = { 78 + .sta_mask = BIT(4), 79 + .ctl_offs = 0x0310, 80 + .sram_pdn_bits = GENMASK(8, 8), 81 + .sram_pdn_ack_bits = GENMASK(12, 12), 82 + }, 83 + [MT8192_POWER_DOMAIN_MFG3] = { 84 + .sta_mask = BIT(5), 85 + .ctl_offs = 0x0314, 86 + .sram_pdn_bits = GENMASK(8, 8), 87 + .sram_pdn_ack_bits = GENMASK(12, 12), 88 + }, 89 + [MT8192_POWER_DOMAIN_MFG4] = { 90 + .sta_mask = BIT(6), 91 + .ctl_offs = 0x0318, 92 + .sram_pdn_bits = GENMASK(8, 8), 93 + .sram_pdn_ack_bits = GENMASK(12, 12), 94 + }, 95 + [MT8192_POWER_DOMAIN_MFG5] = { 96 + .sta_mask = BIT(7), 97 + .ctl_offs = 0x031c, 98 + .sram_pdn_bits = GENMASK(8, 8), 99 + .sram_pdn_ack_bits = GENMASK(12, 12), 100 + }, 101 + [MT8192_POWER_DOMAIN_MFG6] = { 102 + .sta_mask = BIT(8), 103 + .ctl_offs = 0x0320, 104 + .sram_pdn_bits = GENMASK(8, 8), 105 + .sram_pdn_ack_bits = GENMASK(12, 12), 106 + }, 107 + [MT8192_POWER_DOMAIN_DISP] = { 108 + .sta_mask = BIT(20), 109 + .ctl_offs = 0x0350, 110 + .sram_pdn_bits = GENMASK(8, 8), 111 + .sram_pdn_ack_bits = GENMASK(12, 12), 112 + .bp_infracfg = { 113 + BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_DISP, 114 + MT8192_TOP_AXI_PROT_EN_MM_SET, 115 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 116 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 117 + BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_2_DISP, 118 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 119 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 120 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 121 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_DISP, 122 + MT8192_TOP_AXI_PROT_EN_SET, 123 + MT8192_TOP_AXI_PROT_EN_CLR, 124 + MT8192_TOP_AXI_PROT_EN_STA1), 125 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND, 126 + MT8192_TOP_AXI_PROT_EN_MM_SET, 127 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 128 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 129 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND, 130 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 131 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 132 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 133 + }, 134 + }, 135 + [MT8192_POWER_DOMAIN_IPE] = { 136 + .sta_mask = BIT(14), 137 + .ctl_offs = 0x0338, 138 + .sram_pdn_bits = GENMASK(8, 8), 139 + .sram_pdn_ack_bits = GENMASK(12, 12), 140 + .bp_infracfg = { 141 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE, 142 + MT8192_TOP_AXI_PROT_EN_MM_SET, 143 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 144 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 145 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND, 146 + MT8192_TOP_AXI_PROT_EN_MM_SET, 147 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 148 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 149 + }, 150 + }, 151 + [MT8192_POWER_DOMAIN_ISP] = { 152 + .sta_mask = BIT(12), 153 + .ctl_offs = 0x0330, 154 + .sram_pdn_bits = GENMASK(8, 8), 155 + .sram_pdn_ack_bits = GENMASK(12, 12), 156 + .bp_infracfg = { 157 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP, 158 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 159 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 160 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 161 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND, 162 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 163 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 164 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 165 + }, 166 + }, 167 + [MT8192_POWER_DOMAIN_ISP2] = { 168 + .sta_mask = BIT(13), 169 + .ctl_offs = 0x0334, 170 + .sram_pdn_bits = GENMASK(8, 8), 171 + .sram_pdn_ack_bits = GENMASK(12, 12), 172 + .bp_infracfg = { 173 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2, 174 + MT8192_TOP_AXI_PROT_EN_MM_SET, 175 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 176 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 177 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND, 178 + MT8192_TOP_AXI_PROT_EN_MM_SET, 179 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 180 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 181 + }, 182 + }, 183 + [MT8192_POWER_DOMAIN_MDP] = { 184 + .sta_mask = BIT(19), 185 + .ctl_offs = 0x034c, 186 + .sram_pdn_bits = GENMASK(8, 8), 187 + .sram_pdn_ack_bits = GENMASK(12, 12), 188 + .bp_infracfg = { 189 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP, 190 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 191 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 192 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 193 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND, 194 + MT8192_TOP_AXI_PROT_EN_MM_2_SET, 195 + MT8192_TOP_AXI_PROT_EN_MM_2_CLR, 196 + MT8192_TOP_AXI_PROT_EN_MM_2_STA1), 197 + }, 198 + }, 199 + [MT8192_POWER_DOMAIN_VENC] = { 200 + .sta_mask = BIT(17), 201 + .ctl_offs = 0x0344, 202 + .sram_pdn_bits = GENMASK(8, 8), 203 + .sram_pdn_ack_bits = GENMASK(12, 12), 204 + .bp_infracfg = { 205 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC, 206 + MT8192_TOP_AXI_PROT_EN_MM_SET, 207 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 208 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 209 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND, 210 + MT8192_TOP_AXI_PROT_EN_MM_SET, 211 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 212 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 213 + }, 214 + }, 215 + [MT8192_POWER_DOMAIN_VDEC] = { 216 + .sta_mask = BIT(15), 217 + .ctl_offs = 0x033c, 218 + .sram_pdn_bits = GENMASK(8, 8), 219 + .sram_pdn_ack_bits = GENMASK(12, 12), 220 + .bp_infracfg = { 221 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC, 222 + MT8192_TOP_AXI_PROT_EN_MM_SET, 223 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 224 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 225 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND, 226 + MT8192_TOP_AXI_PROT_EN_MM_SET, 227 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 228 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 229 + }, 230 + }, 231 + [MT8192_POWER_DOMAIN_VDEC2] = { 232 + .sta_mask = BIT(16), 233 + .ctl_offs = 0x0340, 234 + .sram_pdn_bits = GENMASK(8, 8), 235 + .sram_pdn_ack_bits = GENMASK(12, 12), 236 + }, 237 + [MT8192_POWER_DOMAIN_CAM] = { 238 + .sta_mask = BIT(23), 239 + .ctl_offs = 0x035c, 240 + .sram_pdn_bits = GENMASK(8, 8), 241 + .sram_pdn_ack_bits = GENMASK(12, 12), 242 + .bp_infracfg = { 243 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_CAM, 244 + MT8192_TOP_AXI_PROT_EN_2_SET, 245 + MT8192_TOP_AXI_PROT_EN_2_CLR, 246 + MT8192_TOP_AXI_PROT_EN_2_STA1), 247 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM, 248 + MT8192_TOP_AXI_PROT_EN_MM_SET, 249 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 250 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 251 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CAM, 252 + MT8192_TOP_AXI_PROT_EN_1_SET, 253 + MT8192_TOP_AXI_PROT_EN_1_CLR, 254 + MT8192_TOP_AXI_PROT_EN_1_STA1), 255 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND, 256 + MT8192_TOP_AXI_PROT_EN_MM_SET, 257 + MT8192_TOP_AXI_PROT_EN_MM_CLR, 258 + MT8192_TOP_AXI_PROT_EN_MM_STA1), 259 + BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_VDNR_CAM, 260 + MT8192_TOP_AXI_PROT_EN_VDNR_SET, 261 + MT8192_TOP_AXI_PROT_EN_VDNR_CLR, 262 + MT8192_TOP_AXI_PROT_EN_VDNR_STA1), 263 + }, 264 + }, 265 + [MT8192_POWER_DOMAIN_CAM_RAWA] = { 266 + .sta_mask = BIT(24), 267 + .ctl_offs = 0x0360, 268 + .sram_pdn_bits = GENMASK(8, 8), 269 + .sram_pdn_ack_bits = GENMASK(12, 12), 270 + }, 271 + [MT8192_POWER_DOMAIN_CAM_RAWB] = { 272 + .sta_mask = BIT(25), 273 + .ctl_offs = 0x0364, 274 + .sram_pdn_bits = GENMASK(8, 8), 275 + .sram_pdn_ack_bits = GENMASK(12, 12), 276 + }, 277 + [MT8192_POWER_DOMAIN_CAM_RAWC] = { 278 + .sta_mask = BIT(26), 279 + .ctl_offs = 0x0368, 280 + .sram_pdn_bits = GENMASK(8, 8), 281 + .sram_pdn_ack_bits = GENMASK(12, 12), 282 + }, 283 + }; 284 + 285 + static const struct scpsys_soc_data mt8192_scpsys_data = { 286 + .domains_data = scpsys_domain_data_mt8192, 287 + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192), 288 + .pwr_sta_offs = 0x016c, 289 + .pwr_sta2nd_offs = 0x0170, 290 + }; 291 + 292 + #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
+1 -40
drivers/soc/mediatek/mtk-cmdq-helper.c
··· 70 70 } 71 71 EXPORT_SYMBOL(cmdq_dev_get_client_reg); 72 72 73 - static void cmdq_client_timeout(struct timer_list *t) 74 - { 75 - struct cmdq_client *client = from_timer(client, t, timer); 76 - 77 - dev_err(client->client.dev, "cmdq timeout!\n"); 78 - } 79 - 80 - struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout) 73 + struct cmdq_client *cmdq_mbox_create(struct device *dev, int index) 81 74 { 82 75 struct cmdq_client *client; 83 76 ··· 78 85 if (!client) 79 86 return (struct cmdq_client *)-ENOMEM; 80 87 81 - client->timeout_ms = timeout; 82 - if (timeout != CMDQ_NO_TIMEOUT) { 83 - spin_lock_init(&client->lock); 84 - timer_setup(&client->timer, cmdq_client_timeout, 0); 85 - } 86 - client->pkt_cnt = 0; 87 88 client->client.dev = dev; 88 89 client->client.tx_block = false; 89 90 client->client.knows_txdone = true; ··· 99 112 100 113 void cmdq_mbox_destroy(struct cmdq_client *client) 101 114 { 102 - if (client->timeout_ms != CMDQ_NO_TIMEOUT) { 103 - spin_lock(&client->lock); 104 - del_timer_sync(&client->timer); 105 - spin_unlock(&client->lock); 106 - } 107 115 mbox_free_channel(client->chan); 108 116 kfree(client); 109 117 } ··· 431 449 struct cmdq_task_cb *cb = &pkt->cb; 432 450 struct cmdq_client *client = (struct cmdq_client *)pkt->cl; 433 451 434 - if (client->timeout_ms != CMDQ_NO_TIMEOUT) { 435 - unsigned long flags = 0; 436 - 437 - spin_lock_irqsave(&client->lock, flags); 438 - if (--client->pkt_cnt == 0) 439 - del_timer(&client->timer); 440 - else 441 - mod_timer(&client->timer, jiffies + 442 - msecs_to_jiffies(client->timeout_ms)); 443 - spin_unlock_irqrestore(&client->lock, flags); 444 - } 445 - 446 452 dma_sync_single_for_cpu(client->chan->mbox->dev, pkt->pa_base, 447 453 pkt->cmd_buf_size, DMA_TO_DEVICE); 448 454 if (cb->cb) { ··· 443 473 void *data) 444 474 { 445 475 int err; 446 - unsigned long flags = 0; 447 476 struct cmdq_client *client = (struct cmdq_client *)pkt->cl; 448 477 449 478 pkt->cb.cb = cb; ··· 452 483 453 484 dma_sync_single_for_device(client->chan->mbox->dev, pkt->pa_base, 454 485 pkt->cmd_buf_size, DMA_TO_DEVICE); 455 - 456 - if (client->timeout_ms != CMDQ_NO_TIMEOUT) { 457 - spin_lock_irqsave(&client->lock, flags); 458 - if (client->pkt_cnt++ == 0) 459 - mod_timer(&client->timer, jiffies + 460 - msecs_to_jiffies(client->timeout_ms)); 461 - spin_unlock_irqrestore(&client->lock, flags); 462 - } 463 486 464 487 err = mbox_send_message(client->chan, pkt); 465 488 if (err < 0)
+308
drivers/soc/mediatek/mtk-devapc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 MediaTek Inc. 4 + */ 5 + 6 + #include <linux/clk.h> 7 + #include <linux/interrupt.h> 8 + #include <linux/iopoll.h> 9 + #include <linux/module.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/of_device.h> 12 + #include <linux/of_irq.h> 13 + #include <linux/of_address.h> 14 + 15 + #define VIO_MOD_TO_REG_IND(m) ((m) / 32) 16 + #define VIO_MOD_TO_REG_OFF(m) ((m) % 32) 17 + 18 + struct mtk_devapc_vio_dbgs { 19 + union { 20 + u32 vio_dbg0; 21 + struct { 22 + u32 mstid:16; 23 + u32 dmnid:6; 24 + u32 vio_w:1; 25 + u32 vio_r:1; 26 + u32 addr_h:4; 27 + u32 resv:4; 28 + } dbg0_bits; 29 + }; 30 + 31 + u32 vio_dbg1; 32 + }; 33 + 34 + struct mtk_devapc_data { 35 + /* numbers of violation index */ 36 + u32 vio_idx_num; 37 + 38 + /* reg offset */ 39 + u32 vio_mask_offset; 40 + u32 vio_sta_offset; 41 + u32 vio_dbg0_offset; 42 + u32 vio_dbg1_offset; 43 + u32 apc_con_offset; 44 + u32 vio_shift_sta_offset; 45 + u32 vio_shift_sel_offset; 46 + u32 vio_shift_con_offset; 47 + }; 48 + 49 + struct mtk_devapc_context { 50 + struct device *dev; 51 + void __iomem *infra_base; 52 + struct clk *infra_clk; 53 + const struct mtk_devapc_data *data; 54 + }; 55 + 56 + static void clear_vio_status(struct mtk_devapc_context *ctx) 57 + { 58 + void __iomem *reg; 59 + int i; 60 + 61 + reg = ctx->infra_base + ctx->data->vio_sta_offset; 62 + 63 + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++) 64 + writel(GENMASK(31, 0), reg + 4 * i); 65 + 66 + writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0), 67 + reg + 4 * i); 68 + } 69 + 70 + static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask) 71 + { 72 + void __iomem *reg; 73 + u32 val; 74 + int i; 75 + 76 + reg = ctx->infra_base + ctx->data->vio_mask_offset; 77 + 78 + if (mask) 79 + val = GENMASK(31, 0); 80 + else 81 + val = 0; 82 + 83 + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++) 84 + writel(val, reg + 4 * i); 85 + 86 + val = readl(reg + 4 * i); 87 + if (mask) 88 + val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 89 + 0); 90 + else 91 + val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 92 + 0); 93 + 94 + writel(val, reg + 4 * i); 95 + } 96 + 97 + #define PHY_DEVAPC_TIMEOUT 0x10000 98 + 99 + /* 100 + * devapc_sync_vio_dbg - do "shift" mechansim" to get full violation information. 101 + * shift mechanism is depends on devapc hardware design. 102 + * Mediatek devapc set multiple slaves as a group. 103 + * When violation is triggered, violation info is kept 104 + * inside devapc hardware. 105 + * Driver should do shift mechansim to sync full violation 106 + * info to VIO_DBGs registers. 107 + * 108 + */ 109 + static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx) 110 + { 111 + void __iomem *pd_vio_shift_sta_reg; 112 + void __iomem *pd_vio_shift_sel_reg; 113 + void __iomem *pd_vio_shift_con_reg; 114 + int min_shift_group; 115 + int ret; 116 + u32 val; 117 + 118 + pd_vio_shift_sta_reg = ctx->infra_base + 119 + ctx->data->vio_shift_sta_offset; 120 + pd_vio_shift_sel_reg = ctx->infra_base + 121 + ctx->data->vio_shift_sel_offset; 122 + pd_vio_shift_con_reg = ctx->infra_base + 123 + ctx->data->vio_shift_con_offset; 124 + 125 + /* Find the minimum shift group which has violation */ 126 + val = readl(pd_vio_shift_sta_reg); 127 + if (!val) 128 + return false; 129 + 130 + min_shift_group = __ffs(val); 131 + 132 + /* Assign the group to sync */ 133 + writel(0x1 << min_shift_group, pd_vio_shift_sel_reg); 134 + 135 + /* Start syncing */ 136 + writel(0x1, pd_vio_shift_con_reg); 137 + 138 + ret = readl_poll_timeout(pd_vio_shift_con_reg, val, val == 0x3, 0, 139 + PHY_DEVAPC_TIMEOUT); 140 + if (ret) { 141 + dev_err(ctx->dev, "%s: Shift violation info failed\n", __func__); 142 + return false; 143 + } 144 + 145 + /* Stop syncing */ 146 + writel(0x0, pd_vio_shift_con_reg); 147 + 148 + /* Write clear */ 149 + writel(0x1 << min_shift_group, pd_vio_shift_sta_reg); 150 + 151 + return true; 152 + } 153 + 154 + /* 155 + * devapc_extract_vio_dbg - extract full violation information after doing 156 + * shift mechanism. 157 + */ 158 + static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx) 159 + { 160 + struct mtk_devapc_vio_dbgs vio_dbgs; 161 + void __iomem *vio_dbg0_reg; 162 + void __iomem *vio_dbg1_reg; 163 + 164 + vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset; 165 + vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset; 166 + 167 + vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg); 168 + vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg); 169 + 170 + /* Print violation information */ 171 + if (vio_dbgs.dbg0_bits.vio_w) 172 + dev_info(ctx->dev, "Write Violation\n"); 173 + else if (vio_dbgs.dbg0_bits.vio_r) 174 + dev_info(ctx->dev, "Read Violation\n"); 175 + 176 + dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n", 177 + vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid, 178 + vio_dbgs.vio_dbg1); 179 + } 180 + 181 + /* 182 + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump 183 + * violation information including which master violates 184 + * access slave. 185 + */ 186 + static irqreturn_t devapc_violation_irq(int irq_number, void *data) 187 + { 188 + struct mtk_devapc_context *ctx = data; 189 + 190 + while (devapc_sync_vio_dbg(ctx)) 191 + devapc_extract_vio_dbg(ctx); 192 + 193 + clear_vio_status(ctx); 194 + 195 + return IRQ_HANDLED; 196 + } 197 + 198 + /* 199 + * start_devapc - unmask slave's irq to start receiving devapc violation. 200 + */ 201 + static void start_devapc(struct mtk_devapc_context *ctx) 202 + { 203 + writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset); 204 + 205 + mask_module_irq(ctx, false); 206 + } 207 + 208 + /* 209 + * stop_devapc - mask slave's irq to stop service. 210 + */ 211 + static void stop_devapc(struct mtk_devapc_context *ctx) 212 + { 213 + mask_module_irq(ctx, true); 214 + 215 + writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset); 216 + } 217 + 218 + static const struct mtk_devapc_data devapc_mt6779 = { 219 + .vio_idx_num = 511, 220 + .vio_mask_offset = 0x0, 221 + .vio_sta_offset = 0x400, 222 + .vio_dbg0_offset = 0x900, 223 + .vio_dbg1_offset = 0x904, 224 + .apc_con_offset = 0xF00, 225 + .vio_shift_sta_offset = 0xF10, 226 + .vio_shift_sel_offset = 0xF14, 227 + .vio_shift_con_offset = 0xF20, 228 + }; 229 + 230 + static const struct of_device_id mtk_devapc_dt_match[] = { 231 + { 232 + .compatible = "mediatek,mt6779-devapc", 233 + .data = &devapc_mt6779, 234 + }, { 235 + }, 236 + }; 237 + 238 + static int mtk_devapc_probe(struct platform_device *pdev) 239 + { 240 + struct device_node *node = pdev->dev.of_node; 241 + struct mtk_devapc_context *ctx; 242 + u32 devapc_irq; 243 + int ret; 244 + 245 + if (IS_ERR(node)) 246 + return -ENODEV; 247 + 248 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 249 + if (!ctx) 250 + return -ENOMEM; 251 + 252 + ctx->data = of_device_get_match_data(&pdev->dev); 253 + ctx->dev = &pdev->dev; 254 + 255 + ctx->infra_base = of_iomap(node, 0); 256 + if (!ctx->infra_base) 257 + return -EINVAL; 258 + 259 + devapc_irq = irq_of_parse_and_map(node, 0); 260 + if (!devapc_irq) 261 + return -EINVAL; 262 + 263 + ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); 264 + if (IS_ERR(ctx->infra_clk)) 265 + return -EINVAL; 266 + 267 + if (clk_prepare_enable(ctx->infra_clk)) 268 + return -EINVAL; 269 + 270 + ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq, 271 + IRQF_TRIGGER_NONE, "devapc", ctx); 272 + if (ret) { 273 + clk_disable_unprepare(ctx->infra_clk); 274 + return ret; 275 + } 276 + 277 + platform_set_drvdata(pdev, ctx); 278 + 279 + start_devapc(ctx); 280 + 281 + return 0; 282 + } 283 + 284 + static int mtk_devapc_remove(struct platform_device *pdev) 285 + { 286 + struct mtk_devapc_context *ctx = platform_get_drvdata(pdev); 287 + 288 + stop_devapc(ctx); 289 + 290 + clk_disable_unprepare(ctx->infra_clk); 291 + 292 + return 0; 293 + } 294 + 295 + static struct platform_driver mtk_devapc_driver = { 296 + .probe = mtk_devapc_probe, 297 + .remove = mtk_devapc_remove, 298 + .driver = { 299 + .name = "mtk-devapc", 300 + .of_match_table = mtk_devapc_dt_match, 301 + }, 302 + }; 303 + 304 + module_platform_driver(mtk_devapc_driver); 305 + 306 + MODULE_DESCRIPTION("Mediatek Device APC Driver"); 307 + MODULE_AUTHOR("Neal Liu <neal.liu@mediatek.com>"); 308 + MODULE_LICENSE("GPL");
-5
drivers/soc/mediatek/mtk-infracfg.c
··· 12 12 #define MTK_POLL_DELAY_US 10 13 13 #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) 14 14 15 - #define INFRA_TOPAXI_PROTECTEN 0x0220 16 - #define INFRA_TOPAXI_PROTECTSTA1 0x0228 17 - #define INFRA_TOPAXI_PROTECTEN_SET 0x0260 18 - #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 19 - 20 15 /** 21 16 * mtk_infracfg_set_bus_protection - enable bus protection 22 17 * @infracfg: The infracfg regmap
+3 -8
drivers/soc/mediatek/mtk-mmsys.c
··· 5 5 */ 6 6 7 7 #include <linux/device.h> 8 + #include <linux/io.h> 8 9 #include <linux/of_device.h> 9 10 #include <linux/platform_device.h> 10 11 #include <linux/soc/mediatek/mtk-mmsys.h> 11 - 12 - #include "../../gpu/drm/mediatek/mtk_drm_ddp.h" 13 - #include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h" 14 12 15 13 #define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x040 16 14 #define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN 0x044 ··· 306 308 struct platform_device *clks; 307 309 struct platform_device *drm; 308 310 void __iomem *config_regs; 309 - struct resource *mem; 310 311 int ret; 311 312 312 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 313 - config_regs = devm_ioremap_resource(dev, mem); 313 + config_regs = devm_platform_ioremap_resource(pdev, 0); 314 314 if (IS_ERR(config_regs)) { 315 315 ret = PTR_ERR(config_regs); 316 - dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n", 317 - ret); 316 + dev_err(dev, "Failed to ioremap mmsys registers: %d\n", ret); 318 317 return ret; 319 318 } 320 319
+614
drivers/soc/mediatek/mtk-pm-domains.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2020 Collabora Ltd. 4 + */ 5 + #include <linux/clk.h> 6 + #include <linux/clk-provider.h> 7 + #include <linux/init.h> 8 + #include <linux/io.h> 9 + #include <linux/iopoll.h> 10 + #include <linux/mfd/syscon.h> 11 + #include <linux/of_clk.h> 12 + #include <linux/of_device.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/pm_domain.h> 15 + #include <linux/regmap.h> 16 + #include <linux/soc/mediatek/infracfg.h> 17 + 18 + #include "mt8173-pm-domains.h" 19 + #include "mt8183-pm-domains.h" 20 + #include "mt8192-pm-domains.h" 21 + 22 + #define MTK_POLL_DELAY_US 10 23 + #define MTK_POLL_TIMEOUT USEC_PER_SEC 24 + 25 + #define PWR_RST_B_BIT BIT(0) 26 + #define PWR_ISO_BIT BIT(1) 27 + #define PWR_ON_BIT BIT(2) 28 + #define PWR_ON_2ND_BIT BIT(3) 29 + #define PWR_CLK_DIS_BIT BIT(4) 30 + #define PWR_SRAM_CLKISO_BIT BIT(5) 31 + #define PWR_SRAM_ISOINT_B_BIT BIT(6) 32 + 33 + struct scpsys_domain { 34 + struct generic_pm_domain genpd; 35 + const struct scpsys_domain_data *data; 36 + struct scpsys *scpsys; 37 + int num_clks; 38 + struct clk_bulk_data *clks; 39 + int num_subsys_clks; 40 + struct clk_bulk_data *subsys_clks; 41 + struct regmap *infracfg; 42 + struct regmap *smi; 43 + }; 44 + 45 + struct scpsys { 46 + struct device *dev; 47 + struct regmap *base; 48 + const struct scpsys_soc_data *soc_data; 49 + struct genpd_onecell_data pd_data; 50 + struct generic_pm_domain *domains[]; 51 + }; 52 + 53 + #define to_scpsys_domain(gpd) container_of(gpd, struct scpsys_domain, genpd) 54 + 55 + static bool scpsys_domain_is_on(struct scpsys_domain *pd) 56 + { 57 + struct scpsys *scpsys = pd->scpsys; 58 + u32 status, status2; 59 + 60 + regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status); 61 + status &= pd->data->sta_mask; 62 + 63 + regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2); 64 + status2 &= pd->data->sta_mask; 65 + 66 + /* A domain is on when both status bits are set. */ 67 + return status && status2; 68 + } 69 + 70 + static int scpsys_sram_enable(struct scpsys_domain *pd) 71 + { 72 + u32 pdn_ack = pd->data->sram_pdn_ack_bits; 73 + struct scpsys *scpsys = pd->scpsys; 74 + unsigned int tmp; 75 + int ret; 76 + 77 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); 78 + 79 + /* Either wait until SRAM_PDN_ACK all 1 or 0 */ 80 + ret = regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, 81 + (tmp & pdn_ack) == 0, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 82 + if (ret < 0) 83 + return ret; 84 + 85 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_ISO)) { 86 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT); 87 + udelay(1); 88 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT); 89 + } 90 + 91 + return 0; 92 + } 93 + 94 + static int scpsys_sram_disable(struct scpsys_domain *pd) 95 + { 96 + u32 pdn_ack = pd->data->sram_pdn_ack_bits; 97 + struct scpsys *scpsys = pd->scpsys; 98 + unsigned int tmp; 99 + 100 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_ISO)) { 101 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT); 102 + udelay(1); 103 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT); 104 + } 105 + 106 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); 107 + 108 + /* Either wait until SRAM_PDN_ACK all 1 or 0 */ 109 + return regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, 110 + (tmp & pdn_ack) == pdn_ack, MTK_POLL_DELAY_US, 111 + MTK_POLL_TIMEOUT); 112 + } 113 + 114 + static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, struct regmap *regmap) 115 + { 116 + int i, ret; 117 + 118 + for (i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) { 119 + u32 val, mask = bpd[i].bus_prot_mask; 120 + 121 + if (!mask) 122 + break; 123 + 124 + if (bpd[i].bus_prot_reg_update) 125 + regmap_set_bits(regmap, bpd[i].bus_prot_set, mask); 126 + else 127 + regmap_write(regmap, bpd[i].bus_prot_set, mask); 128 + 129 + ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta, 130 + val, (val & mask) == mask, 131 + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 132 + if (ret) 133 + return ret; 134 + } 135 + 136 + return 0; 137 + } 138 + 139 + static int scpsys_bus_protect_enable(struct scpsys_domain *pd) 140 + { 141 + int ret; 142 + 143 + ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg); 144 + if (ret) 145 + return ret; 146 + 147 + return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi); 148 + } 149 + 150 + static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd, 151 + struct regmap *regmap) 152 + { 153 + int i, ret; 154 + 155 + for (i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) { 156 + u32 val, mask = bpd[i].bus_prot_mask; 157 + 158 + if (!mask) 159 + continue; 160 + 161 + if (bpd[i].bus_prot_reg_update) 162 + regmap_clear_bits(regmap, bpd[i].bus_prot_clr, mask); 163 + else 164 + regmap_write(regmap, bpd[i].bus_prot_clr, mask); 165 + 166 + if (bpd[i].ignore_clr_ack) 167 + continue; 168 + 169 + ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta, 170 + val, !(val & mask), 171 + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 172 + if (ret) 173 + return ret; 174 + } 175 + 176 + return 0; 177 + } 178 + 179 + static int scpsys_bus_protect_disable(struct scpsys_domain *pd) 180 + { 181 + int ret; 182 + 183 + ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi); 184 + if (ret) 185 + return ret; 186 + 187 + return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg); 188 + } 189 + 190 + static int scpsys_power_on(struct generic_pm_domain *genpd) 191 + { 192 + struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); 193 + struct scpsys *scpsys = pd->scpsys; 194 + bool tmp; 195 + int ret; 196 + 197 + ret = clk_bulk_enable(pd->num_clks, pd->clks); 198 + if (ret) 199 + return ret; 200 + 201 + /* subsys power on */ 202 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); 203 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); 204 + 205 + /* wait until PWR_ACK = 1 */ 206 + ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US, 207 + MTK_POLL_TIMEOUT); 208 + if (ret < 0) 209 + goto err_pwr_ack; 210 + 211 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); 212 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); 213 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); 214 + 215 + ret = clk_bulk_enable(pd->num_subsys_clks, pd->subsys_clks); 216 + if (ret) 217 + goto err_pwr_ack; 218 + 219 + ret = scpsys_sram_enable(pd); 220 + if (ret < 0) 221 + goto err_disable_subsys_clks; 222 + 223 + ret = scpsys_bus_protect_disable(pd); 224 + if (ret < 0) 225 + goto err_disable_sram; 226 + 227 + return 0; 228 + 229 + err_disable_sram: 230 + scpsys_sram_disable(pd); 231 + err_disable_subsys_clks: 232 + clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks); 233 + err_pwr_ack: 234 + clk_bulk_disable(pd->num_clks, pd->clks); 235 + return ret; 236 + } 237 + 238 + static int scpsys_power_off(struct generic_pm_domain *genpd) 239 + { 240 + struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); 241 + struct scpsys *scpsys = pd->scpsys; 242 + bool tmp; 243 + int ret; 244 + 245 + ret = scpsys_bus_protect_enable(pd); 246 + if (ret < 0) 247 + return ret; 248 + 249 + ret = scpsys_sram_disable(pd); 250 + if (ret < 0) 251 + return ret; 252 + 253 + clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks); 254 + 255 + /* subsys power off */ 256 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); 257 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); 258 + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); 259 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); 260 + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); 261 + 262 + /* wait until PWR_ACK = 0 */ 263 + ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US, 264 + MTK_POLL_TIMEOUT); 265 + if (ret < 0) 266 + return ret; 267 + 268 + clk_bulk_disable(pd->num_clks, pd->clks); 269 + 270 + return 0; 271 + } 272 + 273 + static struct 274 + generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node) 275 + { 276 + const struct scpsys_domain_data *domain_data; 277 + struct scpsys_domain *pd; 278 + struct property *prop; 279 + const char *clk_name; 280 + int i, ret, num_clks; 281 + struct clk *clk; 282 + int clk_ind = 0; 283 + u32 id; 284 + 285 + ret = of_property_read_u32(node, "reg", &id); 286 + if (ret) { 287 + dev_err(scpsys->dev, "%pOF: failed to retrieve domain id from reg: %d\n", 288 + node, ret); 289 + return ERR_PTR(-EINVAL); 290 + } 291 + 292 + if (id >= scpsys->soc_data->num_domains) { 293 + dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id); 294 + return ERR_PTR(-EINVAL); 295 + } 296 + 297 + domain_data = &scpsys->soc_data->domains_data[id]; 298 + if (domain_data->sta_mask == 0) { 299 + dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id); 300 + return ERR_PTR(-EINVAL); 301 + } 302 + 303 + pd = devm_kzalloc(scpsys->dev, sizeof(*pd), GFP_KERNEL); 304 + if (!pd) 305 + return ERR_PTR(-ENOMEM); 306 + 307 + pd->data = domain_data; 308 + pd->scpsys = scpsys; 309 + 310 + pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg"); 311 + if (IS_ERR(pd->infracfg)) 312 + return ERR_CAST(pd->infracfg); 313 + 314 + pd->smi = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,smi"); 315 + if (IS_ERR(pd->smi)) 316 + return ERR_CAST(pd->smi); 317 + 318 + num_clks = of_clk_get_parent_count(node); 319 + if (num_clks > 0) { 320 + /* Calculate number of subsys_clks */ 321 + of_property_for_each_string(node, "clock-names", prop, clk_name) { 322 + char *subsys; 323 + 324 + subsys = strchr(clk_name, '-'); 325 + if (subsys) 326 + pd->num_subsys_clks++; 327 + else 328 + pd->num_clks++; 329 + } 330 + 331 + pd->clks = devm_kcalloc(scpsys->dev, pd->num_clks, sizeof(*pd->clks), GFP_KERNEL); 332 + if (!pd->clks) 333 + return ERR_PTR(-ENOMEM); 334 + 335 + pd->subsys_clks = devm_kcalloc(scpsys->dev, pd->num_subsys_clks, 336 + sizeof(*pd->subsys_clks), GFP_KERNEL); 337 + if (!pd->subsys_clks) 338 + return ERR_PTR(-ENOMEM); 339 + 340 + } 341 + 342 + for (i = 0; i < pd->num_clks; i++) { 343 + clk = of_clk_get(node, i); 344 + if (IS_ERR(clk)) { 345 + ret = PTR_ERR(clk); 346 + dev_err_probe(scpsys->dev, ret, 347 + "%pOF: failed to get clk at index %d: %d\n", node, i, ret); 348 + goto err_put_clocks; 349 + } 350 + 351 + pd->clks[clk_ind++].clk = clk; 352 + } 353 + 354 + for (i = 0; i < pd->num_subsys_clks; i++) { 355 + clk = of_clk_get(node, i + clk_ind); 356 + if (IS_ERR(clk)) { 357 + ret = PTR_ERR(clk); 358 + dev_err_probe(scpsys->dev, ret, 359 + "%pOF: failed to get clk at index %d: %d\n", node, 360 + i + clk_ind, ret); 361 + goto err_put_subsys_clocks; 362 + } 363 + 364 + pd->subsys_clks[i].clk = clk; 365 + } 366 + 367 + ret = clk_bulk_prepare(pd->num_clks, pd->clks); 368 + if (ret) 369 + goto err_put_subsys_clocks; 370 + 371 + ret = clk_bulk_prepare(pd->num_subsys_clks, pd->subsys_clks); 372 + if (ret) 373 + goto err_unprepare_clocks; 374 + 375 + /* 376 + * Initially turn on all domains to make the domains usable 377 + * with !CONFIG_PM and to get the hardware in sync with the 378 + * software. The unused domains will be switched off during 379 + * late_init time. 380 + */ 381 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF)) { 382 + if (scpsys_domain_is_on(pd)) 383 + dev_warn(scpsys->dev, 384 + "%pOF: A default off power domain has been ON\n", node); 385 + } else { 386 + ret = scpsys_power_on(&pd->genpd); 387 + if (ret < 0) { 388 + dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret); 389 + goto err_unprepare_clocks; 390 + } 391 + } 392 + 393 + if (scpsys->domains[id]) { 394 + ret = -EINVAL; 395 + dev_err(scpsys->dev, 396 + "power domain with id %d already exists, check your device-tree\n", id); 397 + goto err_unprepare_subsys_clocks; 398 + } 399 + 400 + pd->genpd.name = node->name; 401 + pd->genpd.power_off = scpsys_power_off; 402 + pd->genpd.power_on = scpsys_power_on; 403 + 404 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF)) 405 + pm_genpd_init(&pd->genpd, NULL, true); 406 + else 407 + pm_genpd_init(&pd->genpd, NULL, false); 408 + 409 + scpsys->domains[id] = &pd->genpd; 410 + 411 + return scpsys->pd_data.domains[id]; 412 + 413 + err_unprepare_subsys_clocks: 414 + clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks); 415 + err_unprepare_clocks: 416 + clk_bulk_unprepare(pd->num_clks, pd->clks); 417 + err_put_subsys_clocks: 418 + clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); 419 + err_put_clocks: 420 + clk_bulk_put(pd->num_clks, pd->clks); 421 + return ERR_PTR(ret); 422 + } 423 + 424 + static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *parent) 425 + { 426 + struct generic_pm_domain *child_pd, *parent_pd; 427 + struct device_node *child; 428 + int ret; 429 + 430 + for_each_child_of_node(parent, child) { 431 + u32 id; 432 + 433 + ret = of_property_read_u32(parent, "reg", &id); 434 + if (ret) { 435 + dev_err(scpsys->dev, "%pOF: failed to get parent domain id\n", child); 436 + goto err_put_node; 437 + } 438 + 439 + if (!scpsys->pd_data.domains[id]) { 440 + ret = -EINVAL; 441 + dev_err(scpsys->dev, "power domain with id %d does not exist\n", id); 442 + goto err_put_node; 443 + } 444 + 445 + parent_pd = scpsys->pd_data.domains[id]; 446 + 447 + child_pd = scpsys_add_one_domain(scpsys, child); 448 + if (IS_ERR(child_pd)) { 449 + ret = PTR_ERR(child_pd); 450 + dev_err(scpsys->dev, "%pOF: failed to get child domain id\n", child); 451 + goto err_put_node; 452 + } 453 + 454 + ret = pm_genpd_add_subdomain(parent_pd, child_pd); 455 + if (ret) { 456 + dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n", 457 + child_pd->name, parent_pd->name); 458 + goto err_put_node; 459 + } else { 460 + dev_dbg(scpsys->dev, "%s add subdomain: %s\n", parent_pd->name, 461 + child_pd->name); 462 + } 463 + 464 + /* recursive call to add all subdomains */ 465 + ret = scpsys_add_subdomain(scpsys, child); 466 + if (ret) 467 + goto err_put_node; 468 + } 469 + 470 + return 0; 471 + 472 + err_put_node: 473 + of_node_put(child); 474 + return ret; 475 + } 476 + 477 + static void scpsys_remove_one_domain(struct scpsys_domain *pd) 478 + { 479 + int ret; 480 + 481 + if (scpsys_domain_is_on(pd)) 482 + scpsys_power_off(&pd->genpd); 483 + 484 + /* 485 + * We're in the error cleanup already, so we only complain, 486 + * but won't emit another error on top of the original one. 487 + */ 488 + ret = pm_genpd_remove(&pd->genpd); 489 + if (ret < 0) 490 + dev_err(pd->scpsys->dev, 491 + "failed to remove domain '%s' : %d - state may be inconsistent\n", 492 + pd->genpd.name, ret); 493 + 494 + clk_bulk_unprepare(pd->num_clks, pd->clks); 495 + clk_bulk_put(pd->num_clks, pd->clks); 496 + 497 + clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks); 498 + clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); 499 + } 500 + 501 + static void scpsys_domain_cleanup(struct scpsys *scpsys) 502 + { 503 + struct generic_pm_domain *genpd; 504 + struct scpsys_domain *pd; 505 + int i; 506 + 507 + for (i = scpsys->pd_data.num_domains - 1; i >= 0; i--) { 508 + genpd = scpsys->pd_data.domains[i]; 509 + if (genpd) { 510 + pd = to_scpsys_domain(genpd); 511 + scpsys_remove_one_domain(pd); 512 + } 513 + } 514 + } 515 + 516 + static const struct of_device_id scpsys_of_match[] = { 517 + { 518 + .compatible = "mediatek,mt8173-power-controller", 519 + .data = &mt8173_scpsys_data, 520 + }, 521 + { 522 + .compatible = "mediatek,mt8183-power-controller", 523 + .data = &mt8183_scpsys_data, 524 + }, 525 + { 526 + .compatible = "mediatek,mt8192-power-controller", 527 + .data = &mt8192_scpsys_data, 528 + }, 529 + { } 530 + }; 531 + 532 + static int scpsys_probe(struct platform_device *pdev) 533 + { 534 + struct device *dev = &pdev->dev; 535 + struct device_node *np = dev->of_node; 536 + const struct scpsys_soc_data *soc; 537 + struct device_node *node; 538 + struct device *parent; 539 + struct scpsys *scpsys; 540 + int ret; 541 + 542 + soc = of_device_get_match_data(&pdev->dev); 543 + if (!soc) { 544 + dev_err(&pdev->dev, "no power controller data\n"); 545 + return -EINVAL; 546 + } 547 + 548 + scpsys = devm_kzalloc(dev, struct_size(scpsys, domains, soc->num_domains), GFP_KERNEL); 549 + if (!scpsys) 550 + return -ENOMEM; 551 + 552 + scpsys->dev = dev; 553 + scpsys->soc_data = soc; 554 + 555 + scpsys->pd_data.domains = scpsys->domains; 556 + scpsys->pd_data.num_domains = soc->num_domains; 557 + 558 + parent = dev->parent; 559 + if (!parent) { 560 + dev_err(dev, "no parent for syscon devices\n"); 561 + return -ENODEV; 562 + } 563 + 564 + scpsys->base = syscon_node_to_regmap(parent->of_node); 565 + if (IS_ERR(scpsys->base)) { 566 + dev_err(dev, "no regmap available\n"); 567 + return PTR_ERR(scpsys->base); 568 + } 569 + 570 + ret = -ENODEV; 571 + for_each_available_child_of_node(np, node) { 572 + struct generic_pm_domain *domain; 573 + 574 + domain = scpsys_add_one_domain(scpsys, node); 575 + if (IS_ERR(domain)) { 576 + ret = PTR_ERR(domain); 577 + of_node_put(node); 578 + goto err_cleanup_domains; 579 + } 580 + 581 + ret = scpsys_add_subdomain(scpsys, node); 582 + if (ret) { 583 + of_node_put(node); 584 + goto err_cleanup_domains; 585 + } 586 + } 587 + 588 + if (ret) { 589 + dev_dbg(dev, "no power domains present\n"); 590 + return ret; 591 + } 592 + 593 + ret = of_genpd_add_provider_onecell(np, &scpsys->pd_data); 594 + if (ret) { 595 + dev_err(dev, "failed to add provider: %d\n", ret); 596 + goto err_cleanup_domains; 597 + } 598 + 599 + return 0; 600 + 601 + err_cleanup_domains: 602 + scpsys_domain_cleanup(scpsys); 603 + return ret; 604 + } 605 + 606 + static struct platform_driver scpsys_pm_domain_driver = { 607 + .probe = scpsys_probe, 608 + .driver = { 609 + .name = "mtk-power-controller", 610 + .suppress_bind_attrs = true, 611 + .of_match_table = scpsys_of_match, 612 + }, 613 + }; 614 + builtin_platform_driver(scpsys_pm_domain_driver);
+102
drivers/soc/mediatek/mtk-pm-domains.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __SOC_MEDIATEK_MTK_PM_DOMAINS_H 4 + #define __SOC_MEDIATEK_MTK_PM_DOMAINS_H 5 + 6 + #define MTK_SCPD_ACTIVE_WAKEUP BIT(0) 7 + #define MTK_SCPD_FWAIT_SRAM BIT(1) 8 + #define MTK_SCPD_SRAM_ISO BIT(2) 9 + #define MTK_SCPD_KEEP_DEFAULT_OFF BIT(3) 10 + #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) 11 + 12 + #define SPM_VDE_PWR_CON 0x0210 13 + #define SPM_MFG_PWR_CON 0x0214 14 + #define SPM_VEN_PWR_CON 0x0230 15 + #define SPM_ISP_PWR_CON 0x0238 16 + #define SPM_DIS_PWR_CON 0x023c 17 + #define SPM_VEN2_PWR_CON 0x0298 18 + #define SPM_AUDIO_PWR_CON 0x029c 19 + #define SPM_MFG_2D_PWR_CON 0x02c0 20 + #define SPM_MFG_ASYNC_PWR_CON 0x02c4 21 + #define SPM_USB_PWR_CON 0x02cc 22 + 23 + #define SPM_PWR_STATUS 0x060c 24 + #define SPM_PWR_STATUS_2ND 0x0610 25 + 26 + #define PWR_STATUS_CONN BIT(1) 27 + #define PWR_STATUS_DISP BIT(3) 28 + #define PWR_STATUS_MFG BIT(4) 29 + #define PWR_STATUS_ISP BIT(5) 30 + #define PWR_STATUS_VDEC BIT(7) 31 + #define PWR_STATUS_VENC_LT BIT(20) 32 + #define PWR_STATUS_VENC BIT(21) 33 + #define PWR_STATUS_MFG_2D BIT(22) 34 + #define PWR_STATUS_MFG_ASYNC BIT(23) 35 + #define PWR_STATUS_AUDIO BIT(24) 36 + #define PWR_STATUS_USB BIT(25) 37 + 38 + #define SPM_MAX_BUS_PROT_DATA 5 39 + 40 + #define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \ 41 + .bus_prot_mask = (_mask), \ 42 + .bus_prot_set = _set, \ 43 + .bus_prot_clr = _clr, \ 44 + .bus_prot_sta = _sta, \ 45 + .bus_prot_reg_update = _update, \ 46 + .ignore_clr_ack = _ignore, \ 47 + } 48 + 49 + #define BUS_PROT_WR(_mask, _set, _clr, _sta) \ 50 + _BUS_PROT(_mask, _set, _clr, _sta, false, false) 51 + 52 + #define BUS_PROT_WR_IGN(_mask, _set, _clr, _sta) \ 53 + _BUS_PROT(_mask, _set, _clr, _sta, false, true) 54 + 55 + #define BUS_PROT_UPDATE(_mask, _set, _clr, _sta) \ 56 + _BUS_PROT(_mask, _set, _clr, _sta, true, false) 57 + 58 + #define BUS_PROT_UPDATE_TOPAXI(_mask) \ 59 + BUS_PROT_UPDATE(_mask, \ 60 + INFRA_TOPAXI_PROTECTEN, \ 61 + INFRA_TOPAXI_PROTECTEN_CLR, \ 62 + INFRA_TOPAXI_PROTECTSTA1) 63 + 64 + struct scpsys_bus_prot_data { 65 + u32 bus_prot_mask; 66 + u32 bus_prot_set; 67 + u32 bus_prot_clr; 68 + u32 bus_prot_sta; 69 + bool bus_prot_reg_update; 70 + bool ignore_clr_ack; 71 + }; 72 + 73 + #define MAX_SUBSYS_CLKS 10 74 + 75 + /** 76 + * struct scpsys_domain_data - scp domain data for power on/off flow 77 + * @sta_mask: The mask for power on/off status bit. 78 + * @ctl_offs: The offset for main power control register. 79 + * @sram_pdn_bits: The mask for sram power control bits. 80 + * @sram_pdn_ack_bits: The mask for sram power control acked bits. 81 + * @caps: The flag for active wake-up action. 82 + * @bp_infracfg: bus protection for infracfg subsystem 83 + * @bp_smi: bus protection for smi subsystem 84 + */ 85 + struct scpsys_domain_data { 86 + u32 sta_mask; 87 + int ctl_offs; 88 + u32 sram_pdn_bits; 89 + u32 sram_pdn_ack_bits; 90 + u8 caps; 91 + const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA]; 92 + const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA]; 93 + }; 94 + 95 + struct scpsys_soc_data { 96 + const struct scpsys_domain_data *domains_data; 97 + int num_domains; 98 + int pwr_sta_offs; 99 + int pwr_sta2nd_offs; 100 + }; 101 + 102 + #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
+3 -2
drivers/soc/mediatek/mtk-scpsys.c
··· 524 524 for (i = 0; i < num; i++) { 525 525 struct scp_domain *scpd = &scp->domains[i]; 526 526 struct generic_pm_domain *genpd = &scpd->genpd; 527 + bool on; 527 528 528 529 /* 529 530 * Initially turn on all domains to make the domains usable ··· 532 531 * software. The unused domains will be switched off during 533 532 * late_init time. 534 533 */ 535 - genpd->power_on(genpd); 534 + on = !WARN_ON(genpd->power_on(genpd) < 0); 536 535 537 - pm_genpd_init(genpd, NULL, false); 536 + pm_genpd_init(genpd, NULL, !on); 538 537 } 539 538 540 539 /*
+26
include/dt-bindings/power/mt8183-power.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 MediaTek Inc. 4 + * Author: Weiyi Lu <weiyi.lu@mediatek.com> 5 + */ 6 + 7 + #ifndef _DT_BINDINGS_POWER_MT8183_POWER_H 8 + #define _DT_BINDINGS_POWER_MT8183_POWER_H 9 + 10 + #define MT8183_POWER_DOMAIN_AUDIO 0 11 + #define MT8183_POWER_DOMAIN_CONN 1 12 + #define MT8183_POWER_DOMAIN_MFG_ASYNC 2 13 + #define MT8183_POWER_DOMAIN_MFG 3 14 + #define MT8183_POWER_DOMAIN_MFG_CORE0 4 15 + #define MT8183_POWER_DOMAIN_MFG_CORE1 5 16 + #define MT8183_POWER_DOMAIN_MFG_2D 6 17 + #define MT8183_POWER_DOMAIN_DISP 7 18 + #define MT8183_POWER_DOMAIN_CAM 8 19 + #define MT8183_POWER_DOMAIN_ISP 9 20 + #define MT8183_POWER_DOMAIN_VDEC 10 21 + #define MT8183_POWER_DOMAIN_VENC 11 22 + #define MT8183_POWER_DOMAIN_VPU_TOP 12 23 + #define MT8183_POWER_DOMAIN_VPU_CORE0 13 24 + #define MT8183_POWER_DOMAIN_VPU_CORE1 14 25 + 26 + #endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */
+32
include/dt-bindings/power/mt8192-power.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * Copyright (c) 2020 MediaTek Inc. 4 + * Author: Weiyi Lu <weiyi.lu@mediatek.com> 5 + */ 6 + 7 + #ifndef _DT_BINDINGS_POWER_MT8192_POWER_H 8 + #define _DT_BINDINGS_POWER_MT8192_POWER_H 9 + 10 + #define MT8192_POWER_DOMAIN_AUDIO 0 11 + #define MT8192_POWER_DOMAIN_CONN 1 12 + #define MT8192_POWER_DOMAIN_MFG0 2 13 + #define MT8192_POWER_DOMAIN_MFG1 3 14 + #define MT8192_POWER_DOMAIN_MFG2 4 15 + #define MT8192_POWER_DOMAIN_MFG3 5 16 + #define MT8192_POWER_DOMAIN_MFG4 6 17 + #define MT8192_POWER_DOMAIN_MFG5 7 18 + #define MT8192_POWER_DOMAIN_MFG6 8 19 + #define MT8192_POWER_DOMAIN_DISP 9 20 + #define MT8192_POWER_DOMAIN_IPE 10 21 + #define MT8192_POWER_DOMAIN_ISP 11 22 + #define MT8192_POWER_DOMAIN_ISP2 12 23 + #define MT8192_POWER_DOMAIN_MDP 13 24 + #define MT8192_POWER_DOMAIN_VENC 14 25 + #define MT8192_POWER_DOMAIN_VDEC 15 26 + #define MT8192_POWER_DOMAIN_VDEC2 16 27 + #define MT8192_POWER_DOMAIN_CAM 17 28 + #define MT8192_POWER_DOMAIN_CAM_RAWA 18 29 + #define MT8192_POWER_DOMAIN_CAM_RAWB 19 30 + #define MT8192_POWER_DOMAIN_CAM_RAWC 20 31 + 32 + #endif /* _DT_BINDINGS_POWER_MT8192_POWER_H */
+11
include/linux/mfd/syscon.h
··· 28 28 const char *property, 29 29 int arg_count, 30 30 unsigned int *out_args); 31 + extern struct regmap *syscon_regmap_lookup_by_phandle_optional( 32 + struct device_node *np, 33 + const char *property); 31 34 #else 32 35 static inline struct regmap *device_node_to_regmap(struct device_node *np) 33 36 { ··· 62 59 { 63 60 return ERR_PTR(-ENOTSUPP); 64 61 } 62 + 63 + static inline struct regmap *syscon_regmap_lookup_by_phandle_optional( 64 + struct device_node *np, 65 + const char *property) 66 + { 67 + return NULL; 68 + } 69 + 65 70 #endif 66 71 67 72 #endif /* __LINUX_MFD_SYSCON_H__ */
+107
include/linux/soc/mediatek/infracfg.h
··· 2 2 #ifndef __SOC_MEDIATEK_INFRACFG_H 3 3 #define __SOC_MEDIATEK_INFRACFG_H 4 4 5 + #define MT8192_TOP_AXI_PROT_EN_STA1 0x228 6 + #define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258 7 + #define MT8192_TOP_AXI_PROT_EN_SET 0x2a0 8 + #define MT8192_TOP_AXI_PROT_EN_CLR 0x2a4 9 + #define MT8192_TOP_AXI_PROT_EN_1_SET 0x2a8 10 + #define MT8192_TOP_AXI_PROT_EN_1_CLR 0x2ac 11 + #define MT8192_TOP_AXI_PROT_EN_MM_SET 0x2d4 12 + #define MT8192_TOP_AXI_PROT_EN_MM_CLR 0x2d8 13 + #define MT8192_TOP_AXI_PROT_EN_MM_STA1 0x2ec 14 + #define MT8192_TOP_AXI_PROT_EN_2_SET 0x714 15 + #define MT8192_TOP_AXI_PROT_EN_2_CLR 0x718 16 + #define MT8192_TOP_AXI_PROT_EN_2_STA1 0x724 17 + #define MT8192_TOP_AXI_PROT_EN_VDNR_SET 0xb84 18 + #define MT8192_TOP_AXI_PROT_EN_VDNR_CLR 0xb88 19 + #define MT8192_TOP_AXI_PROT_EN_VDNR_STA1 0xb90 20 + #define MT8192_TOP_AXI_PROT_EN_MM_2_SET 0xdcc 21 + #define MT8192_TOP_AXI_PROT_EN_MM_2_CLR 0xdd0 22 + #define MT8192_TOP_AXI_PROT_EN_MM_2_STA1 0xdd8 23 + 24 + #define MT8192_TOP_AXI_PROT_EN_DISP (BIT(6) | BIT(23)) 25 + #define MT8192_TOP_AXI_PROT_EN_CONN (BIT(13) | BIT(18)) 26 + #define MT8192_TOP_AXI_PROT_EN_CONN_2ND BIT(14) 27 + #define MT8192_TOP_AXI_PROT_EN_MFG1 GENMASK(22, 21) 28 + #define MT8192_TOP_AXI_PROT_EN_1_CONN BIT(10) 29 + #define MT8192_TOP_AXI_PROT_EN_1_MFG1 BIT(21) 30 + #define MT8192_TOP_AXI_PROT_EN_1_CAM BIT(22) 31 + #define MT8192_TOP_AXI_PROT_EN_2_CAM BIT(0) 32 + #define MT8192_TOP_AXI_PROT_EN_2_ADSP BIT(3) 33 + #define MT8192_TOP_AXI_PROT_EN_2_AUDIO BIT(4) 34 + #define MT8192_TOP_AXI_PROT_EN_2_MFG1 GENMASK(6, 5) 35 + #define MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND BIT(7) 36 + #define MT8192_TOP_AXI_PROT_EN_MM_CAM (BIT(0) | BIT(2)) 37 + #define MT8192_TOP_AXI_PROT_EN_MM_DISP (BIT(0) | BIT(2) | \ 38 + BIT(10) | BIT(12) | \ 39 + BIT(14) | BIT(16) | \ 40 + BIT(24) | BIT(26)) 41 + #define MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND (BIT(1) | BIT(3)) 42 + #define MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND (BIT(1) | BIT(3) | \ 43 + BIT(15) | BIT(17) | \ 44 + BIT(25) | BIT(27)) 45 + #define MT8192_TOP_AXI_PROT_EN_MM_ISP2 BIT(14) 46 + #define MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND BIT(15) 47 + #define MT8192_TOP_AXI_PROT_EN_MM_IPE BIT(16) 48 + #define MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND BIT(17) 49 + #define MT8192_TOP_AXI_PROT_EN_MM_VDEC BIT(24) 50 + #define MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND BIT(25) 51 + #define MT8192_TOP_AXI_PROT_EN_MM_VENC BIT(26) 52 + #define MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND BIT(27) 53 + #define MT8192_TOP_AXI_PROT_EN_MM_2_ISP BIT(8) 54 + #define MT8192_TOP_AXI_PROT_EN_MM_2_DISP (BIT(8) | BIT(12)) 55 + #define MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND BIT(9) 56 + #define MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND (BIT(9) | BIT(13)) 57 + #define MT8192_TOP_AXI_PROT_EN_MM_2_MDP BIT(12) 58 + #define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13) 59 + #define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21) 60 + 61 + #define MT8183_TOP_AXI_PROT_EN_STA1 0x228 62 + #define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258 63 + #define MT8183_TOP_AXI_PROT_EN_SET 0x2a0 64 + #define MT8183_TOP_AXI_PROT_EN_CLR 0x2a4 65 + #define MT8183_TOP_AXI_PROT_EN_1_SET 0x2a8 66 + #define MT8183_TOP_AXI_PROT_EN_1_CLR 0x2ac 67 + #define MT8183_TOP_AXI_PROT_EN_MCU_SET 0x2c4 68 + #define MT8183_TOP_AXI_PROT_EN_MCU_CLR 0x2c8 69 + #define MT8183_TOP_AXI_PROT_EN_MCU_STA1 0x2e4 70 + #define MT8183_TOP_AXI_PROT_EN_MM_SET 0x2d4 71 + #define MT8183_TOP_AXI_PROT_EN_MM_CLR 0x2d8 72 + #define MT8183_TOP_AXI_PROT_EN_MM_STA1 0x2ec 73 + 74 + #define MT8183_TOP_AXI_PROT_EN_DISP (BIT(10) | BIT(11)) 75 + #define MT8183_TOP_AXI_PROT_EN_CONN (BIT(13) | BIT(14)) 76 + #define MT8183_TOP_AXI_PROT_EN_MFG (BIT(21) | BIT(22)) 77 + #define MT8183_TOP_AXI_PROT_EN_CAM BIT(28) 78 + #define MT8183_TOP_AXI_PROT_EN_VPU_TOP BIT(27) 79 + #define MT8183_TOP_AXI_PROT_EN_1_DISP (BIT(16) | BIT(17)) 80 + #define MT8183_TOP_AXI_PROT_EN_1_MFG GENMASK(21, 19) 81 + #define MT8183_TOP_AXI_PROT_EN_MM_ISP (BIT(3) | BIT(8)) 82 + #define MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND BIT(10) 83 + #define MT8183_TOP_AXI_PROT_EN_MM_CAM (BIT(4) | BIT(5) | \ 84 + BIT(9) | BIT(13)) 85 + #define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP (GENMASK(9, 6) | \ 86 + BIT(12)) 87 + #define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND (BIT(10) | BIT(11)) 88 + #define MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND BIT(11) 89 + #define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND (BIT(0) | BIT(2) | \ 90 + BIT(4)) 91 + #define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND (BIT(1) | BIT(3) | \ 92 + BIT(5)) 93 + #define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0 BIT(6) 94 + #define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1 BIT(7) 95 + 96 + #define MT8183_SMI_COMMON_CLAMP_EN 0x3c0 97 + #define MT8183_SMI_COMMON_CLAMP_EN_SET 0x3c4 98 + #define MT8183_SMI_COMMON_CLAMP_EN_CLR 0x3c8 99 + 100 + #define MT8183_SMI_COMMON_SMI_CLAMP_DISP GENMASK(7, 0) 101 + #define MT8183_SMI_COMMON_SMI_CLAMP_VENC BIT(1) 102 + #define MT8183_SMI_COMMON_SMI_CLAMP_ISP BIT(2) 103 + #define MT8183_SMI_COMMON_SMI_CLAMP_CAM (BIT(3) | BIT(4)) 104 + #define MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP (BIT(5) | BIT(6)) 105 + #define MT8183_SMI_COMMON_SMI_CLAMP_VDEC BIT(7) 106 + 5 107 #define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0) 6 108 #define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1) 7 109 #define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2) ··· 133 31 BIT(28)) 134 32 #define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \ 135 33 BIT(7) | BIT(8)) 34 + 35 + #define INFRA_TOPAXI_PROTECTEN 0x0220 36 + #define INFRA_TOPAXI_PROTECTSTA1 0x0228 37 + #define INFRA_TOPAXI_PROTECTEN_SET 0x0260 38 + #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 136 39 137 40 #define REG_INFRA_MISC 0xf00 138 41 #define F_DDR_4GB_SUPPORT_EN BIT(13)
+1 -9
include/linux/soc/mediatek/mtk-cmdq.h
··· 11 11 #include <linux/mailbox/mtk-cmdq-mailbox.h> 12 12 #include <linux/timer.h> 13 13 14 - #define CMDQ_NO_TIMEOUT 0xffffffffu 15 14 #define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0))) 16 15 #define CMDQ_ADDR_LOW(addr) ((u16)(addr) | BIT(1)) 17 16 ··· 23 24 }; 24 25 25 26 struct cmdq_client { 26 - spinlock_t lock; 27 - u32 pkt_cnt; 28 27 struct mbox_client client; 29 28 struct mbox_chan *chan; 30 - struct timer_list timer; 31 - u32 timeout_ms; /* in unit of microsecond */ 32 29 }; 33 30 34 31 /** ··· 46 51 * cmdq_mbox_create() - create CMDQ mailbox client and channel 47 52 * @dev: device of CMDQ mailbox client 48 53 * @index: index of CMDQ mailbox channel 49 - * @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set 50 - * CMDQ_NO_TIMEOUT if a timer is not used. 51 54 * 52 55 * Return: CMDQ mailbox client pointer 53 56 */ 54 - struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, 55 - u32 timeout); 57 + struct cmdq_client *cmdq_mbox_create(struct device *dev, int index); 56 58 57 59 /** 58 60 * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
+33
include/linux/soc/mediatek/mtk-mmsys.h
··· 9 9 enum mtk_ddp_comp_id; 10 10 struct device; 11 11 12 + enum mtk_ddp_comp_id { 13 + DDP_COMPONENT_AAL0, 14 + DDP_COMPONENT_AAL1, 15 + DDP_COMPONENT_BLS, 16 + DDP_COMPONENT_CCORR, 17 + DDP_COMPONENT_COLOR0, 18 + DDP_COMPONENT_COLOR1, 19 + DDP_COMPONENT_DITHER, 20 + DDP_COMPONENT_DPI0, 21 + DDP_COMPONENT_DPI1, 22 + DDP_COMPONENT_DSI0, 23 + DDP_COMPONENT_DSI1, 24 + DDP_COMPONENT_DSI2, 25 + DDP_COMPONENT_DSI3, 26 + DDP_COMPONENT_GAMMA, 27 + DDP_COMPONENT_OD0, 28 + DDP_COMPONENT_OD1, 29 + DDP_COMPONENT_OVL0, 30 + DDP_COMPONENT_OVL_2L0, 31 + DDP_COMPONENT_OVL_2L1, 32 + DDP_COMPONENT_OVL1, 33 + DDP_COMPONENT_PWM0, 34 + DDP_COMPONENT_PWM1, 35 + DDP_COMPONENT_PWM2, 36 + DDP_COMPONENT_RDMA0, 37 + DDP_COMPONENT_RDMA1, 38 + DDP_COMPONENT_RDMA2, 39 + DDP_COMPONENT_UFOE, 40 + DDP_COMPONENT_WDMA0, 41 + DDP_COMPONENT_WDMA1, 42 + DDP_COMPONENT_ID_MAX, 43 + }; 44 + 12 45 void mtk_mmsys_ddp_connect(struct device *dev, 13 46 enum mtk_ddp_comp_id cur, 14 47 enum mtk_ddp_comp_id next);