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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-msm-next-2022-03-01' of https://gitlab.freedesktop.org/drm/msm into drm-next

We're experimenting a bit with the process this time, with Dmitry
collecting display patches and merging them into msm-next with me
handling the gpu/etc side of things. Summary of interesting new bits
and pieces

* dpu + dp support for sc8180x
* dp support for sm8350
* dpu + dsi support for qcm2290
* 10nm dsi phy tuning support
* bridge support for dp encoder
* gpu support for additional 7c3 SKUs
* assorted cleanups and fixes

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGu=Jdrw6DqYOYPTMks7=zatrsvdR=o6DpjqZ=TQQhFZuw@mail.gmail.com

+2049 -994
+1
Documentation/devicetree/bindings/display/msm/dp-controller.yaml
··· 21 21 - qcom,sc7280-edp 22 22 - qcom,sc8180x-dp 23 23 - qcom,sc8180x-edp 24 + - qcom,sm8350-dp 24 25 25 26 reg: 26 27 items:
+219
Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/msm/dpu-msm8998.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Display DPU dt properties for MSM8998 target 8 + 9 + maintainers: 10 + - AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> 11 + 12 + description: | 13 + Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates 14 + sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree 15 + bindings of MDSS and DPU are mentioned for MSM8998 target. 16 + 17 + properties: 18 + compatible: 19 + items: 20 + - const: qcom,msm8998-mdss 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + reg-names: 26 + const: mdss 27 + 28 + power-domains: 29 + maxItems: 1 30 + 31 + clocks: 32 + items: 33 + - description: Display AHB clock 34 + - description: Display AXI clock 35 + - description: Display core clock 36 + 37 + clock-names: 38 + items: 39 + - const: iface 40 + - const: bus 41 + - const: core 42 + 43 + interrupts: 44 + maxItems: 1 45 + 46 + interrupt-controller: true 47 + 48 + "#address-cells": true 49 + 50 + "#size-cells": true 51 + 52 + "#interrupt-cells": 53 + const: 1 54 + 55 + iommus: 56 + items: 57 + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0 58 + 59 + ranges: true 60 + 61 + patternProperties: 62 + "^display-controller@[0-9a-f]+$": 63 + type: object 64 + description: Node containing the properties of DPU. 65 + 66 + properties: 67 + compatible: 68 + items: 69 + - const: qcom,msm8998-dpu 70 + 71 + reg: 72 + items: 73 + - description: Address offset and size for mdp register set 74 + - description: Address offset and size for regdma register set 75 + - description: Address offset and size for vbif register set 76 + - description: Address offset and size for non-realtime vbif register set 77 + 78 + reg-names: 79 + items: 80 + - const: mdp 81 + - const: regdma 82 + - const: vbif 83 + - const: vbif_nrt 84 + 85 + clocks: 86 + items: 87 + - description: Display ahb clock 88 + - description: Display axi clock 89 + - description: Display mem-noc clock 90 + - description: Display core clock 91 + - description: Display vsync clock 92 + 93 + clock-names: 94 + items: 95 + - const: iface 96 + - const: bus 97 + - const: mnoc 98 + - const: core 99 + - const: vsync 100 + 101 + interrupts: 102 + maxItems: 1 103 + 104 + power-domains: 105 + maxItems: 1 106 + 107 + operating-points-v2: true 108 + ports: 109 + $ref: /schemas/graph.yaml#/properties/ports 110 + description: | 111 + Contains the list of output ports from DPU device. These ports 112 + connect to interfaces that are external to the DPU hardware, 113 + such as DSI, DP etc. Each output port contains an endpoint that 114 + describes how it is connected to an external interface. 115 + 116 + properties: 117 + port@0: 118 + $ref: /schemas/graph.yaml#/properties/port 119 + description: DPU_INTF1 (DSI1) 120 + 121 + port@1: 122 + $ref: /schemas/graph.yaml#/properties/port 123 + description: DPU_INTF2 (DSI2) 124 + 125 + required: 126 + - port@0 127 + - port@1 128 + 129 + required: 130 + - compatible 131 + - reg 132 + - reg-names 133 + - clocks 134 + - interrupts 135 + - power-domains 136 + - operating-points-v2 137 + - ports 138 + 139 + required: 140 + - compatible 141 + - reg 142 + - reg-names 143 + - power-domains 144 + - clocks 145 + - interrupts 146 + - interrupt-controller 147 + - iommus 148 + - ranges 149 + 150 + additionalProperties: false 151 + 152 + examples: 153 + - | 154 + #include <dt-bindings/clock/qcom,mmcc-msm8998.h> 155 + #include <dt-bindings/interrupt-controller/arm-gic.h> 156 + #include <dt-bindings/power/qcom-rpmpd.h> 157 + 158 + display-subsystem@c900000 { 159 + compatible = "qcom,msm8998-mdss"; 160 + reg = <0x0c900000 0x1000>; 161 + reg-names = "mdss"; 162 + 163 + clocks = <&mmcc MDSS_AHB_CLK>, 164 + <&mmcc MDSS_AXI_CLK>, 165 + <&mmcc MDSS_MDP_CLK>; 166 + clock-names = "iface", "bus", "core"; 167 + 168 + #address-cells = <1>; 169 + #interrupt-cells = <1>; 170 + #size-cells = <1>; 171 + 172 + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; 173 + interrupt-controller; 174 + iommus = <&mmss_smmu 0>; 175 + 176 + power-domains = <&mmcc MDSS_GDSC>; 177 + ranges; 178 + 179 + display-controller@c901000 { 180 + compatible = "qcom,msm8998-dpu"; 181 + reg = <0x0c901000 0x8f000>, 182 + <0x0c9a8e00 0xf0>, 183 + <0x0c9b0000 0x2008>, 184 + <0x0c9b8000 0x1040>; 185 + reg-names = "mdp", "regdma", "vbif", "vbif_nrt"; 186 + 187 + clocks = <&mmcc MDSS_AHB_CLK>, 188 + <&mmcc MDSS_AXI_CLK>, 189 + <&mmcc MNOC_AHB_CLK>, 190 + <&mmcc MDSS_MDP_CLK>, 191 + <&mmcc MDSS_VSYNC_CLK>; 192 + clock-names = "iface", "bus", "mnoc", "core", "vsync"; 193 + 194 + interrupt-parent = <&mdss>; 195 + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; 196 + operating-points-v2 = <&mdp_opp_table>; 197 + power-domains = <&rpmpd MSM8998_VDDMX>; 198 + 199 + ports { 200 + #address-cells = <1>; 201 + #size-cells = <0>; 202 + 203 + port@0 { 204 + reg = <0>; 205 + dpu_intf1_out: endpoint { 206 + remote-endpoint = <&dsi0_in>; 207 + }; 208 + }; 209 + 210 + port@1 { 211 + reg = <1>; 212 + dpu_intf2_out: endpoint { 213 + remote-endpoint = <&dsi1_in>; 214 + }; 215 + }; 216 + }; 217 + }; 218 + }; 219 + ...
+214
Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/msm/dpu-qcm2290.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Display DPU dt properties for QCM2290 target 8 + 9 + maintainers: 10 + - Loic Poulain <loic.poulain@linaro.org> 11 + 12 + description: | 13 + Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates 14 + sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS 15 + and DPU are mentioned for QCM2290 target. 16 + 17 + properties: 18 + compatible: 19 + items: 20 + - const: qcom,qcm2290-mdss 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + reg-names: 26 + const: mdss 27 + 28 + power-domains: 29 + maxItems: 1 30 + 31 + clocks: 32 + items: 33 + - description: Display AHB clock from gcc 34 + - description: Display AXI clock 35 + - description: Display core clock 36 + 37 + clock-names: 38 + items: 39 + - const: iface 40 + - const: bus 41 + - const: core 42 + 43 + interrupts: 44 + maxItems: 1 45 + 46 + interrupt-controller: true 47 + 48 + "#address-cells": true 49 + 50 + "#size-cells": true 51 + 52 + "#interrupt-cells": 53 + const: 1 54 + 55 + iommus: 56 + items: 57 + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0 58 + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port1 59 + 60 + ranges: true 61 + 62 + interconnects: 63 + items: 64 + - description: Interconnect path specifying the port ids for data bus 65 + 66 + interconnect-names: 67 + const: mdp0-mem 68 + 69 + patternProperties: 70 + "^display-controller@[0-9a-f]+$": 71 + type: object 72 + description: Node containing the properties of DPU. 73 + 74 + properties: 75 + compatible: 76 + items: 77 + - const: qcom,qcm2290-dpu 78 + 79 + reg: 80 + items: 81 + - description: Address offset and size for mdp register set 82 + - description: Address offset and size for vbif register set 83 + 84 + reg-names: 85 + items: 86 + - const: mdp 87 + - const: vbif 88 + 89 + clocks: 90 + items: 91 + - description: Display AXI clock from gcc 92 + - description: Display AHB clock from dispcc 93 + - description: Display core clock from dispcc 94 + - description: Display lut clock from dispcc 95 + - description: Display vsync clock from dispcc 96 + 97 + clock-names: 98 + items: 99 + - const: bus 100 + - const: iface 101 + - const: core 102 + - const: lut 103 + - const: vsync 104 + 105 + interrupts: 106 + maxItems: 1 107 + 108 + power-domains: 109 + maxItems: 1 110 + 111 + operating-points-v2: true 112 + 113 + ports: 114 + $ref: /schemas/graph.yaml#/properties/ports 115 + description: | 116 + Contains the list of output ports from DPU device. These ports 117 + connect to interfaces that are external to the DPU hardware, 118 + such as DSI. Each output port contains an endpoint that 119 + describes how it is connected to an external interface. 120 + 121 + properties: 122 + port@0: 123 + $ref: /schemas/graph.yaml#/properties/port 124 + description: DPU_INTF1 (DSI1) 125 + 126 + required: 127 + - port@0 128 + 129 + required: 130 + - compatible 131 + - reg 132 + - reg-names 133 + - clocks 134 + - interrupts 135 + - power-domains 136 + - operating-points-v2 137 + - ports 138 + 139 + required: 140 + - compatible 141 + - reg 142 + - reg-names 143 + - power-domains 144 + - clocks 145 + - interrupts 146 + - interrupt-controller 147 + - iommus 148 + - ranges 149 + 150 + additionalProperties: false 151 + 152 + examples: 153 + - | 154 + #include <dt-bindings/clock/qcom,dispcc-qcm2290.h> 155 + #include <dt-bindings/clock/qcom,gcc-qcm2290.h> 156 + #include <dt-bindings/interrupt-controller/arm-gic.h> 157 + #include <dt-bindings/interconnect/qcom,qcm2290.h> 158 + #include <dt-bindings/power/qcom-rpmpd.h> 159 + 160 + mdss: mdss@5e00000 { 161 + #address-cells = <1>; 162 + #size-cells = <1>; 163 + compatible = "qcom,qcm2290-mdss", "qcom,mdss"; 164 + reg = <0x05e00000 0x1000>; 165 + reg-names = "mdss"; 166 + power-domains = <&dispcc MDSS_GDSC>; 167 + clocks = <&gcc GCC_DISP_AHB_CLK>, 168 + <&gcc GCC_DISP_HF_AXI_CLK>, 169 + <&dispcc DISP_CC_MDSS_MDP_CLK>; 170 + clock-names = "iface", "bus", "core"; 171 + 172 + interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; 173 + interrupt-controller; 174 + #interrupt-cells = <1>; 175 + 176 + interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>; 177 + interconnect-names = "mdp0-mem"; 178 + 179 + iommus = <&apps_smmu 0x420 0x2>, 180 + <&apps_smmu 0x421 0x0>; 181 + ranges; 182 + 183 + mdss_mdp: mdp@5e01000 { 184 + compatible = "qcom,qcm2290-dpu"; 185 + reg = <0x05e01000 0x8f000>, 186 + <0x05eb0000 0x2008>; 187 + reg-names = "mdp", "vbif"; 188 + 189 + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, 190 + <&dispcc DISP_CC_MDSS_AHB_CLK>, 191 + <&dispcc DISP_CC_MDSS_MDP_CLK>, 192 + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, 193 + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; 194 + clock-names = "bus", "iface", "core", "lut", "vsync"; 195 + 196 + operating-points-v2 = <&mdp_opp_table>; 197 + power-domains = <&rpmpd QCM2290_VDDCX>; 198 + 199 + interrupt-parent = <&mdss>; 200 + interrupts = <0 IRQ_TYPE_NONE>; 201 + 202 + ports { 203 + #address-cells = <1>; 204 + #size-cells = <0>; 205 + 206 + port@0 { 207 + reg = <0>; 208 + dpu_intf1_out: endpoint { 209 + remote-endpoint = <&dsi0_in>; 210 + }; 211 + }; 212 + }; 213 + }; 214 + ...
+3 -2
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
··· 14 14 15 15 properties: 16 16 compatible: 17 - items: 18 - - const: qcom,mdss-dsi-ctrl 17 + enum: 18 + - qcom,mdss-dsi-ctrl 19 + - qcom,dsi-ctrl-6g-qcm2290 19 20 20 21 reg: 21 22 maxItems: 1
+36
Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
··· 35 35 Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and 36 36 connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target 37 37 38 + qcom,phy-rescode-offset-top: 39 + $ref: /schemas/types.yaml#/definitions/int8-array 40 + minItems: 5 41 + maxItems: 5 42 + description: 43 + Integer array of offset for pull-up legs rescode for all five lanes. 44 + To offset the drive strength from the calibrated value in an increasing 45 + manner, -32 is the weakest and +31 is the strongest. 46 + items: 47 + minimum: -32 48 + maximum: 31 49 + 50 + qcom,phy-rescode-offset-bot: 51 + $ref: /schemas/types.yaml#/definitions/int8-array 52 + minItems: 5 53 + maxItems: 5 54 + description: 55 + Integer array of offset for pull-down legs rescode for all five lanes. 56 + To offset the drive strength from the calibrated value in a decreasing 57 + manner, -32 is the weakest and +31 is the strongest. 58 + items: 59 + minimum: -32 60 + maximum: 31 61 + 62 + qcom,phy-drive-ldo-level: 63 + $ref: "/schemas/types.yaml#/definitions/uint32" 64 + description: 65 + The PHY LDO has an amplitude tuning feature to adjust the LDO output 66 + for the HSTX drive. Use supported levels (mV) to offset the drive level 67 + from the default value. 68 + enum: [ 375, 400, 425, 450, 475, 500 ] 69 + 38 70 required: 39 71 - compatible 40 72 - reg ··· 96 64 clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, 97 65 <&rpmhcc RPMH_CXO_CLK>; 98 66 clock-names = "iface", "ref"; 67 + 68 + qcom,phy-rescode-offset-top = /bits/ 8 <0 0 0 0 0>; 69 + qcom,phy-rescode-offset-bot = /bits/ 8 <0 0 0 0 0>; 70 + qcom,phy-drive-ldo-level = <400>; 99 71 }; 100 72 ...
-9
drivers/gpu/drm/msm/Kconfig
··· 34 34 depends on DRM_MSM && (DEBUG_FS || DEV_COREDUMP) 35 35 default y 36 36 37 - config DRM_MSM_REGISTER_LOGGING 38 - bool "MSM DRM register logging" 39 - depends on DRM_MSM 40 - default n 41 - help 42 - Compile in support for logging register reads/writes in a format 43 - that can be parsed by envytools demsm tool. If enabled, register 44 - logging can be switched on via msm.reglog=y module param. 45 - 46 37 config DRM_MSM_GPU_SUDO 47 38 bool "Enable SUDO flag on submits" 48 39 depends on DRM_MSM && EXPERT
+2 -1
drivers/gpu/drm/msm/Makefile
··· 66 66 disp/dpu1/dpu_hw_top.o \ 67 67 disp/dpu1/dpu_hw_util.o \ 68 68 disp/dpu1/dpu_hw_vbif.o \ 69 - disp/dpu1/dpu_io_util.o \ 70 69 disp/dpu1/dpu_kms.o \ 71 70 disp/dpu1/dpu_mdss.o \ 72 71 disp/dpu1/dpu_plane.o \ ··· 86 87 msm_gem_vma.o \ 87 88 msm_gpu.o \ 88 89 msm_gpu_devfreq.o \ 90 + msm_io_utils.o \ 89 91 msm_iommu.o \ 90 92 msm_perf.o \ 91 93 msm_rd.o \ ··· 102 102 103 103 msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ 104 104 dp/dp_catalog.o \ 105 + dp/dp_clk_util.o \ 105 106 dp/dp_ctrl.o \ 106 107 dp/dp_display.o \ 107 108 dp/dp_drm.o \
+17 -3
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
··· 10 10 11 11 #include <linux/bitfield.h> 12 12 #include <linux/devfreq.h> 13 - #include <linux/nvmem-consumer.h> 14 13 #include <linux/soc/qcom/llcc-qcom.h> 15 14 16 15 #define GPU_PAS_ID 13 ··· 1505 1506 if (a6xx_gpu->have_mmu500) 1506 1507 a6xx_gpu->llc_mmio = NULL; 1507 1508 else 1508 - a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem", "gpu_cx"); 1509 + a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem"); 1509 1510 1510 1511 a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU); 1511 1512 a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW); ··· 1735 1736 return UINT_MAX; 1736 1737 } 1737 1738 1739 + static u32 adreno_7c3_get_speed_bin(u32 fuse) 1740 + { 1741 + if (fuse == 0) 1742 + return 0; 1743 + else if (fuse == 117) 1744 + return 0; 1745 + else if (fuse == 190) 1746 + return 1; 1747 + 1748 + return UINT_MAX; 1749 + } 1750 + 1738 1751 static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) 1739 1752 { 1740 1753 u32 val = UINT_MAX; 1741 1754 1742 1755 if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) 1743 1756 val = a618_get_speed_bin(fuse); 1757 + 1758 + if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) 1759 + val = adreno_7c3_get_speed_bin(fuse); 1744 1760 1745 1761 if (val == UINT_MAX) { 1746 1762 DRM_DEV_ERROR(dev, ··· 1773 1759 u32 speedbin; 1774 1760 int ret; 1775 1761 1776 - ret = nvmem_cell_read_variable_le_u32(dev, "speed_bin", &speedbin); 1762 + ret = adreno_read_speedbin(dev, &speedbin); 1777 1763 /* 1778 1764 * -ENOENT means that the platform doesn't support speedbin which is 1779 1765 * fine
-1
drivers/gpu/drm/msm/adreno/adreno_device.c
··· 318 318 .hwcg = a660_hwcg, 319 319 }, { 320 320 .rev = ADRENO_REV(6, 3, 5, ANY_ID), 321 - .name = "Adreno 7c Gen 3", 322 321 .fw = { 323 322 [ADRENO_FW_SQE] = "a660_sqe.fw", 324 323 [ADRENO_FW_GMU] = "a660_gmu.bin",
+33 -8
drivers/gpu/drm/msm/adreno/adreno_gpu.c
··· 14 14 #include <linux/pm_opp.h> 15 15 #include <linux/slab.h> 16 16 #include <linux/soc/qcom/mdt_loader.h> 17 + #include <linux/nvmem-consumer.h> 17 18 #include <soc/qcom/ocmem.h> 18 19 #include "adreno_gpu.h" 19 20 #include "a6xx_gpu.h" ··· 228 227 return aspace; 229 228 } 230 229 231 - int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) 230 + int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, 231 + uint32_t param, uint64_t *value) 232 232 { 233 233 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 234 234 ··· 244 242 *value = !adreno_is_a650_family(adreno_gpu) ? 0x100000 : 0; 245 243 return 0; 246 244 case MSM_PARAM_CHIP_ID: 247 - *value = adreno_gpu->rev.patchid | 248 - (adreno_gpu->rev.minor << 8) | 249 - (adreno_gpu->rev.major << 16) | 250 - (adreno_gpu->rev.core << 24); 245 + *value = (uint64_t) adreno_gpu->rev.patchid | 246 + (uint64_t) (adreno_gpu->rev.minor << 8) | 247 + (uint64_t) (adreno_gpu->rev.major << 16) | 248 + (uint64_t) (adreno_gpu->rev.core << 24); 249 + if (!adreno_gpu->info->revn) 250 + *value |= ((uint64_t) adreno_gpu->speedbin) << 32; 251 251 return 0; 252 252 case MSM_PARAM_MAX_FREQ: 253 253 *value = adreno_gpu->base.fast_rate; ··· 272 268 *value = 0; 273 269 return 0; 274 270 case MSM_PARAM_FAULTS: 275 - *value = gpu->global_faults; 271 + *value = gpu->global_faults + ctx->aspace->faults; 276 272 return 0; 277 273 case MSM_PARAM_SUSPENDS: 278 274 *value = gpu->suspend_count; ··· 925 921 adreno_ocmem->hdl); 926 922 } 927 923 924 + int adreno_read_speedbin(struct device *dev, u32 *speedbin) 925 + { 926 + return nvmem_cell_read_variable_le_u32(dev, "speed_bin", speedbin); 927 + } 928 + 928 929 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, 929 930 struct adreno_gpu *adreno_gpu, 930 931 const struct adreno_gpu_funcs *funcs, int nr_rings) ··· 938 929 struct adreno_platform_config *config = dev->platform_data; 939 930 struct msm_gpu_config adreno_gpu_config = { 0 }; 940 931 struct msm_gpu *gpu = &adreno_gpu->base; 932 + struct adreno_rev *rev = &config->rev; 933 + const char *gpu_name; 934 + u32 speedbin; 941 935 942 936 adreno_gpu->funcs = funcs; 943 937 adreno_gpu->info = adreno_info(config->rev); 944 938 adreno_gpu->gmem = adreno_gpu->info->gmem; 945 939 adreno_gpu->revn = adreno_gpu->info->revn; 946 - adreno_gpu->rev = config->rev; 940 + adreno_gpu->rev = *rev; 941 + 942 + if (adreno_read_speedbin(dev, &speedbin) || !speedbin) 943 + speedbin = 0xffff; 944 + adreno_gpu->speedbin = (uint16_t) (0xffff & speedbin); 945 + 946 + gpu_name = adreno_gpu->info->name; 947 + if (!gpu_name) { 948 + gpu_name = devm_kasprintf(dev, GFP_KERNEL, "%d.%d.%d.%d", 949 + rev->core, rev->major, rev->minor, 950 + rev->patchid); 951 + if (!gpu_name) 952 + return -ENOMEM; 953 + } 947 954 948 955 adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; 949 956 ··· 973 948 pm_runtime_enable(dev); 974 949 975 950 return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, 976 - adreno_gpu->info->name, &adreno_gpu_config); 951 + gpu_name, &adreno_gpu_config); 977 952 } 978 953 979 954 void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
+5 -1
drivers/gpu/drm/msm/adreno/adreno_gpu.h
··· 80 80 const struct adreno_info *info; 81 81 uint32_t gmem; /* actual gmem size */ 82 82 uint32_t revn; /* numeric revision name */ 83 + uint16_t speedbin; 83 84 const struct adreno_gpu_funcs *funcs; 84 85 85 86 /* interesting register offsets to dump: */ ··· 280 279 adreno_is_a660_family(gpu); 281 280 } 282 281 283 - int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); 282 + int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, 283 + uint32_t param, uint64_t *value); 284 284 const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, 285 285 const char *fwname); 286 286 struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu, ··· 325 323 struct platform_device *pdev); 326 324 327 325 void adreno_set_llc_attributes(struct iommu_domain *iommu); 326 + 327 + int adreno_read_speedbin(struct device *dev, u32 *speedbin); 328 328 329 329 /* 330 330 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
+6 -17
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
··· 284 284 } 285 285 } 286 286 287 - static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate) 288 - { 289 - struct dss_clk *core_clk = kms->perf.core_clk; 290 - 291 - if (core_clk->max_rate && (rate > core_clk->max_rate)) 292 - rate = core_clk->max_rate; 293 - 294 - core_clk->rate = rate; 295 - return dev_pm_opp_set_rate(&kms->pdev->dev, core_clk->rate); 296 - } 297 - 298 287 static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) 299 288 { 300 289 u64 clk_rate = kms->perf.perf_tune.min_core_clk; ··· 295 306 dpu_cstate = to_dpu_crtc_state(crtc->state); 296 307 clk_rate = max(dpu_cstate->new_perf.core_clk_rate, 297 308 clk_rate); 298 - clk_rate = clk_round_rate(kms->perf.core_clk->clk, 309 + clk_rate = clk_round_rate(kms->perf.core_clk, 299 310 clk_rate); 300 311 } 301 312 } ··· 394 405 395 406 trace_dpu_core_perf_update_clk(kms->dev, stop_req, clk_rate); 396 407 397 - ret = _dpu_core_perf_set_core_clk_rate(kms, clk_rate); 408 + clk_rate = min(clk_rate, kms->perf.max_core_clk_rate); 409 + ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate); 398 410 if (ret) { 399 - DPU_ERROR("failed to set %s clock rate %llu\n", 400 - kms->perf.core_clk->clk_name, clk_rate); 411 + DPU_ERROR("failed to set core clock rate %llu\n", clk_rate); 401 412 return ret; 402 413 } 403 414 ··· 518 529 int dpu_core_perf_init(struct dpu_core_perf *perf, 519 530 struct drm_device *dev, 520 531 struct dpu_mdss_cfg *catalog, 521 - struct dss_clk *core_clk) 532 + struct clk *core_clk) 522 533 { 523 534 perf->dev = dev; 524 535 perf->catalog = catalog; 525 536 perf->core_clk = core_clk; 526 537 527 - perf->max_core_clk_rate = core_clk->max_rate; 538 + perf->max_core_clk_rate = clk_get_rate(core_clk); 528 539 if (!perf->max_core_clk_rate) { 529 540 DPU_DEBUG("optional max core clk rate, use default\n"); 530 541 perf->max_core_clk_rate = DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE;
+3 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
··· 56 56 * @dev: Pointer to drm device 57 57 * @debugfs_root: top level debug folder 58 58 * @catalog: Pointer to catalog configuration 59 - * @core_clk: Pointer to core clock structure 59 + * @core_clk: Pointer to the core clock 60 60 * @core_clk_rate: current core clock rate 61 61 * @max_core_clk_rate: maximum allowable core clock rate 62 62 * @perf_tune: debug control for performance tuning ··· 69 69 struct drm_device *dev; 70 70 struct dentry *debugfs_root; 71 71 struct dpu_mdss_cfg *catalog; 72 - struct dss_clk *core_clk; 72 + struct clk *core_clk; 73 73 u64 core_clk_rate; 74 74 u64 max_core_clk_rate; 75 75 struct dpu_core_perf_tune perf_tune; ··· 120 120 int dpu_core_perf_init(struct dpu_core_perf *perf, 121 121 struct drm_device *dev, 122 122 struct dpu_mdss_cfg *catalog, 123 - struct dss_clk *core_clk); 123 + struct clk *core_clk); 124 124 125 125 struct dpu_kms; 126 126
+20 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 408 408 if (ctl->ops.set_active_pipes) 409 409 ctl->ops.set_active_pipes(ctl, fetch_active); 410 410 411 - _dpu_crtc_program_lm_output_roi(crtc); 411 + _dpu_crtc_program_lm_output_roi(crtc); 412 412 } 413 413 414 414 /** ··· 1046 1046 u32 pipe_id; 1047 1047 }; 1048 1048 1049 + static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate) 1050 + { 1051 + struct drm_crtc *crtc = cstate->crtc; 1052 + struct drm_encoder *encoder; 1053 + 1054 + drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) { 1055 + if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) { 1056 + return true; 1057 + } 1058 + } 1059 + 1060 + return false; 1061 + } 1062 + 1049 1063 static int dpu_crtc_atomic_check(struct drm_crtc *crtc, 1050 1064 struct drm_atomic_state *state) 1051 1065 { ··· 1080 1066 const struct drm_plane_state *pipe_staged[SSPP_MAX]; 1081 1067 int left_zpos_cnt = 0, right_zpos_cnt = 0; 1082 1068 struct drm_rect crtc_rect = { 0 }; 1069 + bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); 1083 1070 1084 1071 pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL); 1085 1072 ··· 1112 1097 1113 1098 /* get plane state for all drm planes associated with crtc state */ 1114 1099 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { 1100 + struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate); 1115 1101 struct drm_rect dst, clip = crtc_rect; 1116 1102 1117 1103 if (IS_ERR_OR_NULL(pstate)) { ··· 1124 1108 if (cnt >= DPU_STAGE_MAX * 4) 1125 1109 continue; 1126 1110 1127 - pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); 1111 + pstates[cnt].dpu_pstate = dpu_pstate; 1128 1112 pstates[cnt].drm_pstate = pstate; 1129 1113 pstates[cnt].stage = pstate->normalized_zpos; 1130 1114 pstates[cnt].pipe_id = dpu_plane_pipe(plane); 1115 + 1116 + dpu_pstate->needs_dirtyfb = needs_dirtyfb; 1131 1117 1132 1118 if (pipe_staged[pstates[cnt].pipe_id]) { 1133 1119 multirect_plane[multirect_count].r0 =
+18 -82
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
··· 127 127 * Virtual encoder registers itself with the DRM Framework as the encoder. 128 128 * @base: drm_encoder base class for registration with DRM 129 129 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes 130 - * @bus_scaling_client: Client handle to the bus scaling interface 131 130 * @enabled: True if the encoder is active, protected by enc_lock 132 131 * @num_phys_encs: Actual number of physical encoders contained. 133 132 * @phys_encs: Container of physical encoders managed. ··· 143 144 * link between encoder/crtc. However in this case we need 144 145 * to track crtc in the disable() hook which is called 145 146 * _after_ encoder_mask is cleared. 147 + * @connector: If a mode is set, cached pointer to the active connector 146 148 * @crtc_kickoff_cb: Callback into CRTC that will flush & start 147 149 * all CTL paths 148 150 * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb ··· 168 168 * @vsync_event_work: worker to handle vsync event for autorefresh 169 169 * @topology: topology of the display 170 170 * @idle_timeout: idle timeout duration in milliseconds 171 - * @dp: msm_dp pointer, for DP encoders 172 171 */ 173 172 struct dpu_encoder_virt { 174 173 struct drm_encoder base; 175 174 spinlock_t enc_spinlock; 176 - uint32_t bus_scaling_client; 177 175 178 176 bool enabled; 179 177 ··· 184 186 bool intfs_swapped; 185 187 186 188 struct drm_crtc *crtc; 189 + struct drm_connector *connector; 187 190 188 191 struct dentry *debugfs_root; 189 192 struct mutex enc_lock; ··· 206 207 struct msm_display_topology topology; 207 208 208 209 u32 idle_timeout; 209 - 210 - struct msm_dp *dp; 211 210 }; 212 211 213 212 #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) ··· 417 420 return linecount; 418 421 } 419 422 420 - void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc, 421 - struct dpu_encoder_hw_resources *hw_res) 422 - { 423 - struct dpu_encoder_virt *dpu_enc = NULL; 424 - int i = 0; 425 - 426 - dpu_enc = to_dpu_encoder_virt(drm_enc); 427 - DPU_DEBUG_ENC(dpu_enc, "\n"); 428 - 429 - /* Query resources used by phys encs, expected to be without overlap */ 430 - memset(hw_res, 0, sizeof(*hw_res)); 431 - 432 - for (i = 0; i < dpu_enc->num_phys_encs; i++) { 433 - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 434 - 435 - if (phys->ops.get_hw_resources) 436 - phys->ops.get_hw_resources(phys, hw_res); 437 - } 438 - } 439 - 440 423 static void dpu_encoder_destroy(struct drm_encoder *drm_enc) 441 424 { 442 425 struct dpu_encoder_virt *dpu_enc = NULL; ··· 584 607 if (phys->ops.atomic_check) 585 608 ret = phys->ops.atomic_check(phys, crtc_state, 586 609 conn_state); 587 - else if (phys->ops.mode_fixup) 588 - if (!phys->ops.mode_fixup(phys, mode, adj_mode)) 589 - ret = -EINVAL; 590 - 591 610 if (ret) { 592 611 DPU_ERROR_ENC(dpu_enc, 593 612 "mode unsupported, phys idx %d\n", i); ··· 929 956 return 0; 930 957 } 931 958 932 - static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, 933 - struct drm_display_mode *mode, 934 - struct drm_display_mode *adj_mode) 959 + static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, 960 + struct drm_crtc_state *crtc_state, 961 + struct drm_connector_state *conn_state) 935 962 { 936 963 struct dpu_encoder_virt *dpu_enc; 937 964 struct msm_drm_private *priv; 938 965 struct dpu_kms *dpu_kms; 939 - struct list_head *connector_list; 940 - struct drm_connector *conn = NULL, *conn_iter; 941 - struct drm_crtc *drm_crtc; 942 966 struct dpu_crtc_state *cstate; 943 967 struct dpu_global_state *global_state; 944 968 struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; ··· 943 973 struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; 944 974 struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; 945 975 int num_lm, num_ctl, num_pp; 946 - int i, j; 976 + int i; 947 977 948 978 if (!drm_enc) { 949 979 DPU_ERROR("invalid encoder\n"); ··· 955 985 956 986 priv = drm_enc->dev->dev_private; 957 987 dpu_kms = to_dpu_kms(priv->kms); 958 - connector_list = &dpu_kms->dev->mode_config.connector_list; 959 988 960 989 global_state = dpu_kms_get_existing_global_state(dpu_kms); 961 990 if (IS_ERR_OR_NULL(global_state)) { ··· 963 994 } 964 995 965 996 trace_dpu_enc_mode_set(DRMID(drm_enc)); 966 - 967 - list_for_each_entry(conn_iter, connector_list, head) 968 - if (conn_iter->encoder == drm_enc) 969 - conn = conn_iter; 970 - 971 - if (!conn) { 972 - DPU_ERROR_ENC(dpu_enc, "failed to find attached connector\n"); 973 - return; 974 - } else if (!conn->state) { 975 - DPU_ERROR_ENC(dpu_enc, "invalid connector state\n"); 976 - return; 977 - } 978 - 979 - drm_for_each_crtc(drm_crtc, drm_enc->dev) 980 - if (drm_crtc->state->encoder_mask & drm_encoder_mask(drm_enc)) 981 - break; 982 997 983 998 /* Query resource that have been reserved in atomic check step. */ 984 999 num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, ··· 980 1027 dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) 981 1028 : NULL; 982 1029 983 - cstate = to_dpu_crtc_state(drm_crtc->state); 1030 + cstate = to_dpu_crtc_state(crtc_state); 984 1031 985 1032 for (i = 0; i < num_lm; i++) { 986 1033 int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); ··· 992 1039 993 1040 cstate->num_mixers = num_lm; 994 1041 1042 + dpu_enc->connector = conn_state->connector; 1043 + 995 1044 for (i = 0; i < dpu_enc->num_phys_encs; i++) { 996 - int num_blk; 997 - struct dpu_hw_blk *hw_blk[MAX_CHANNELS_PER_ENC]; 998 1045 struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 999 1046 1000 1047 if (!dpu_enc->hw_pp[i]) { ··· 1012 1059 phys->hw_pp = dpu_enc->hw_pp[i]; 1013 1060 phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); 1014 1061 1015 - num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm, 1016 - global_state, drm_enc->base.id, DPU_HW_BLK_INTF, 1017 - hw_blk, ARRAY_SIZE(hw_blk)); 1018 - for (j = 0; j < num_blk; j++) { 1019 - struct dpu_hw_intf *hw_intf; 1020 - 1021 - hw_intf = to_dpu_hw_intf(hw_blk[i]); 1022 - if (hw_intf->idx == phys->intf_idx) 1023 - phys->hw_intf = hw_intf; 1024 - } 1062 + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) 1063 + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); 1025 1064 1026 1065 if (!phys->hw_intf) { 1027 1066 DPU_ERROR_ENC(dpu_enc, ··· 1021 1076 return; 1022 1077 } 1023 1078 1024 - phys->connector = conn->state->connector; 1025 - if (phys->ops.mode_set) 1026 - phys->ops.mode_set(phys, mode, adj_mode); 1079 + phys->cached_mode = crtc_state->adjusted_mode; 1080 + if (phys->ops.atomic_mode_set) 1081 + phys->ops.atomic_mode_set(phys, crtc_state, conn_state); 1027 1082 } 1028 1083 } 1029 1084 ··· 1044 1099 } 1045 1100 1046 1101 1047 - if (dpu_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DisplayPort && 1102 + if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_TMDS && 1048 1103 dpu_enc->cur_master->hw_mdptop && 1049 1104 dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select) 1050 1105 dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select( ··· 1054 1109 1055 1110 if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && 1056 1111 !WARN_ON(dpu_enc->num_phys_encs == 0)) { 1057 - unsigned bpc = dpu_enc->phys_encs[0]->connector->display_info.bpc; 1112 + unsigned bpc = dpu_enc->connector->display_info.bpc; 1058 1113 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { 1059 1114 if (!dpu_enc->hw_pp[i]) 1060 1115 continue; ··· 1087 1142 { 1088 1143 struct dpu_encoder_virt *dpu_enc = NULL; 1089 1144 int ret = 0; 1090 - struct msm_drm_private *priv; 1091 1145 struct drm_display_mode *cur_mode = NULL; 1092 1146 1093 1147 dpu_enc = to_dpu_encoder_virt(drm_enc); 1094 1148 1095 1149 mutex_lock(&dpu_enc->enc_lock); 1096 1150 cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; 1097 - priv = drm_enc->dev->dev_private; 1098 1151 1099 1152 trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay, 1100 1153 cur_mode->vdisplay); ··· 1122 1179 static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) 1123 1180 { 1124 1181 struct dpu_encoder_virt *dpu_enc = NULL; 1125 - struct msm_drm_private *priv; 1126 1182 int i = 0; 1127 1183 1128 1184 dpu_enc = to_dpu_encoder_virt(drm_enc); ··· 1129 1187 1130 1188 mutex_lock(&dpu_enc->enc_lock); 1131 1189 dpu_enc->enabled = false; 1132 - 1133 - priv = drm_enc->dev->dev_private; 1134 1190 1135 1191 trace_dpu_enc_disable(DRMID(drm_enc)); 1136 1192 ··· 1153 1213 1154 1214 dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_STOP); 1155 1215 1156 - for (i = 0; i < dpu_enc->num_phys_encs; i++) { 1157 - dpu_enc->phys_encs[i]->connector = NULL; 1158 - } 1216 + dpu_enc->connector = NULL; 1159 1217 1160 1218 DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); 1161 1219 ··· 2031 2093 } 2032 2094 2033 2095 static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { 2034 - .mode_set = dpu_encoder_virt_mode_set, 2096 + .atomic_mode_set = dpu_encoder_virt_atomic_mode_set, 2035 2097 .disable = dpu_encoder_virt_disable, 2036 2098 .enable = dpu_encoder_virt_enable, 2037 2099 .atomic_check = dpu_encoder_virt_atomic_check, ··· 2066 2128 timer_setup(&dpu_enc->vsync_event_timer, 2067 2129 dpu_encoder_vsync_event_handler, 2068 2130 0); 2069 - else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) 2070 - dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]]; 2071 2131 2072 2132 INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, 2073 2133 dpu_encoder_off_work);
+14 -12
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
··· 19 19 #define IDLE_TIMEOUT (66 - 16/2) 20 20 21 21 /** 22 - * Encoder functions and data types 23 - * @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused 22 + * struct msm_display_info - defines display properties 23 + * @intf_type: DRM_MODE_ENCODER_ type 24 + * @capabilities: Bitmask of display flags 25 + * @num_of_h_tiles: Number of horizontal tiles in case of split interface 26 + * @h_tile_instance: Controller instance used per tile. Number of elements is 27 + * based on num_of_h_tiles 28 + * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is 29 + * used instead of panel TE in cmd mode panels 24 30 */ 25 - struct dpu_encoder_hw_resources { 26 - enum dpu_intf_mode intfs[INTF_MAX]; 31 + struct msm_display_info { 32 + int intf_type; 33 + uint32_t capabilities; 34 + uint32_t num_of_h_tiles; 35 + uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; 36 + bool is_te_using_watchdog_timer; 27 37 }; 28 - 29 - /** 30 - * dpu_encoder_get_hw_resources - Populate table of required hardware resources 31 - * @encoder: encoder pointer 32 - * @hw_res: resource table to populate with encoder required resources 33 - */ 34 - void dpu_encoder_get_hw_resources(struct drm_encoder *encoder, 35 - struct dpu_encoder_hw_resources *hw_res); 36 38 37 39 /** 38 40 * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to
+4 -15
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
··· 84 84 * @is_master: Whether this phys_enc is the current master 85 85 * encoder. Can be switched at enable time. Based 86 86 * on split_role and current mode (CMD/VID). 87 - * @mode_fixup: DRM Call. Fixup a DRM mode. 88 - * @mode_set: DRM Call. Set a DRM mode. 87 + * @atomic_mode_set: DRM Call. Set a DRM mode. 89 88 * This likely caches the mode, for use at enable. 90 89 * @enable: DRM Call. Enable a DRM mode. 91 90 * @disable: DRM Call. Disable mode. 92 91 * @atomic_check: DRM Call. Atomic check new DRM state. 93 92 * @destroy: DRM Call. Destroy and release resources. 94 - * @get_hw_resources: Populate the structure with the hardware 95 - * resources that this phys_enc is using. 96 - * Expect no overlap between phys_encs. 97 93 * @control_vblank_irq Register/Deregister for VBLANK IRQ 98 94 * @wait_for_commit_done: Wait for hardware to have flushed the 99 95 * current pending frames to hardware ··· 113 117 struct dentry *debugfs_root); 114 118 void (*prepare_commit)(struct dpu_encoder_phys *encoder); 115 119 bool (*is_master)(struct dpu_encoder_phys *encoder); 116 - bool (*mode_fixup)(struct dpu_encoder_phys *encoder, 117 - const struct drm_display_mode *mode, 118 - struct drm_display_mode *adjusted_mode); 119 - void (*mode_set)(struct dpu_encoder_phys *encoder, 120 - struct drm_display_mode *mode, 121 - struct drm_display_mode *adjusted_mode); 120 + void (*atomic_mode_set)(struct dpu_encoder_phys *encoder, 121 + struct drm_crtc_state *crtc_state, 122 + struct drm_connector_state *conn_state); 122 123 void (*enable)(struct dpu_encoder_phys *encoder); 123 124 void (*disable)(struct dpu_encoder_phys *encoder); 124 125 int (*atomic_check)(struct dpu_encoder_phys *encoder, 125 126 struct drm_crtc_state *crtc_state, 126 127 struct drm_connector_state *conn_state); 127 128 void (*destroy)(struct dpu_encoder_phys *encoder); 128 - void (*get_hw_resources)(struct dpu_encoder_phys *encoder, 129 - struct dpu_encoder_hw_resources *hw_res); 130 129 int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); 131 130 int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); 132 131 int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); ··· 173 182 * tied to a specific panel / sub-panel. Abstract type, sub-classed by 174 183 * phys_vid or phys_cmd for video mode or command mode encs respectively. 175 184 * @parent: Pointer to the containing virtual encoder 176 - * @connector: If a mode is set, cached pointer to the active connector 177 185 * @ops: Operations exposed to the virtual encoder 178 186 * @parent_ops: Callbacks exposed by the parent to the phys_enc 179 187 * @hw_mdptop: Hardware interface to the top registers ··· 201 211 */ 202 212 struct dpu_encoder_phys { 203 213 struct drm_encoder *parent; 204 - struct drm_connector *connector; 205 214 struct dpu_encoder_phys_ops ops; 206 215 const struct dpu_encoder_virt_ops *parent_ops; 207 216 struct dpu_hw_mdp *hw_mdptop;
+7 -32
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
··· 45 45 return (phys_enc->split_role != ENC_ROLE_SLAVE); 46 46 } 47 47 48 - static bool dpu_encoder_phys_cmd_mode_fixup( 49 - struct dpu_encoder_phys *phys_enc, 50 - const struct drm_display_mode *mode, 51 - struct drm_display_mode *adj_mode) 52 - { 53 - DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc), "\n"); 54 - return true; 55 - } 56 - 57 48 static void _dpu_encoder_phys_cmd_update_intf_cfg( 58 49 struct dpu_encoder_phys *phys_enc) 59 50 { ··· 135 144 phys_enc); 136 145 } 137 146 138 - static void dpu_encoder_phys_cmd_mode_set( 147 + static void dpu_encoder_phys_cmd_atomic_mode_set( 139 148 struct dpu_encoder_phys *phys_enc, 140 - struct drm_display_mode *mode, 141 - struct drm_display_mode *adj_mode) 149 + struct drm_crtc_state *crtc_state, 150 + struct drm_connector_state *conn_state) 142 151 { 143 - struct dpu_encoder_phys_cmd *cmd_enc = 144 - to_dpu_encoder_phys_cmd(phys_enc); 145 152 struct dpu_encoder_irq *irq; 146 - 147 - if (!mode || !adj_mode) { 148 - DPU_ERROR("invalid args\n"); 149 - return; 150 - } 151 - phys_enc->cached_mode = *adj_mode; 152 - DPU_DEBUG_CMDENC(cmd_enc, "caching mode:\n"); 153 - drm_mode_debug_printmodeline(adj_mode); 154 153 155 154 irq = &phys_enc->irq[INTR_IDX_CTL_START]; 156 155 irq->irq_idx = phys_enc->hw_ctl->caps->intr_start; ··· 515 534 kfree(cmd_enc); 516 535 } 517 536 518 - static void dpu_encoder_phys_cmd_get_hw_resources( 519 - struct dpu_encoder_phys *phys_enc, 520 - struct dpu_encoder_hw_resources *hw_res) 521 - { 522 - hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD; 523 - } 524 - 525 537 static void dpu_encoder_phys_cmd_prepare_for_kickoff( 526 538 struct dpu_encoder_phys *phys_enc) 527 539 { ··· 656 682 if (!dpu_encoder_phys_cmd_is_master(phys_enc)) 657 683 return 0; 658 684 685 + if (phys_enc->hw_ctl->ops.is_started(phys_enc->hw_ctl)) 686 + return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc); 687 + 659 688 return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); 660 689 } 661 690 ··· 708 731 { 709 732 ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit; 710 733 ops->is_master = dpu_encoder_phys_cmd_is_master; 711 - ops->mode_set = dpu_encoder_phys_cmd_mode_set; 712 - ops->mode_fixup = dpu_encoder_phys_cmd_mode_fixup; 734 + ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; 713 735 ops->enable = dpu_encoder_phys_cmd_enable; 714 736 ops->disable = dpu_encoder_phys_cmd_disable; 715 737 ops->destroy = dpu_encoder_phys_cmd_destroy; 716 - ops->get_hw_resources = dpu_encoder_phys_cmd_get_hw_resources; 717 738 ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq; 718 739 ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done; 719 740 ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
+4 -32
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
··· 225 225 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 226 226 } 227 227 228 - static bool dpu_encoder_phys_vid_mode_fixup( 229 - struct dpu_encoder_phys *phys_enc, 230 - const struct drm_display_mode *mode, 231 - struct drm_display_mode *adj_mode) 232 - { 233 - DPU_DEBUG_VIDENC(phys_enc, "\n"); 234 - 235 - /* 236 - * Modifying mode has consequences when the mode comes back to us 237 - */ 238 - return true; 239 - } 240 - 241 228 static void dpu_encoder_phys_vid_setup_timing_engine( 242 229 struct dpu_encoder_phys *phys_enc) 243 230 { ··· 348 361 return phys_enc->split_role != ENC_ROLE_SOLO; 349 362 } 350 363 351 - static void dpu_encoder_phys_vid_mode_set( 364 + static void dpu_encoder_phys_vid_atomic_mode_set( 352 365 struct dpu_encoder_phys *phys_enc, 353 - struct drm_display_mode *mode, 354 - struct drm_display_mode *adj_mode) 366 + struct drm_crtc_state *crtc_state, 367 + struct drm_connector_state *conn_state) 355 368 { 356 369 struct dpu_encoder_irq *irq; 357 - 358 - if (adj_mode) { 359 - phys_enc->cached_mode = *adj_mode; 360 - drm_mode_debug_printmodeline(adj_mode); 361 - DPU_DEBUG_VIDENC(phys_enc, "caching mode:\n"); 362 - } 363 370 364 371 irq = &phys_enc->irq[INTR_IDX_VSYNC]; 365 372 irq->irq_idx = phys_enc->hw_intf->cap->intr_vsync; ··· 444 463 { 445 464 DPU_DEBUG_VIDENC(phys_enc, "\n"); 446 465 kfree(phys_enc); 447 - } 448 - 449 - static void dpu_encoder_phys_vid_get_hw_resources( 450 - struct dpu_encoder_phys *phys_enc, 451 - struct dpu_encoder_hw_resources *hw_res) 452 - { 453 - hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO; 454 466 } 455 467 456 468 static int dpu_encoder_phys_vid_wait_for_vblank( ··· 649 675 static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) 650 676 { 651 677 ops->is_master = dpu_encoder_phys_vid_is_master; 652 - ops->mode_set = dpu_encoder_phys_vid_mode_set; 653 - ops->mode_fixup = dpu_encoder_phys_vid_mode_fixup; 678 + ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; 654 679 ops->enable = dpu_encoder_phys_vid_enable; 655 680 ops->disable = dpu_encoder_phys_vid_disable; 656 681 ops->destroy = dpu_encoder_phys_vid_destroy; 657 - ops->get_hw_resources = dpu_encoder_phys_vid_get_hw_resources; 658 682 ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; 659 683 ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done; 660 684 ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
+598 -12
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
··· 16 16 BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\ 17 17 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT)) 18 18 19 + #define VIG_MSM8998_MASK \ 20 + (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) 21 + 19 22 #define VIG_SDM845_MASK \ 20 23 (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3)) 21 24 ··· 28 25 #define VIG_SM8250_MASK \ 29 26 (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE)) 30 27 28 + #define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL)) 29 + 30 + #define DMA_MSM8998_MASK \ 31 + (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ 32 + BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ 33 + BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) 34 + 31 35 #define DMA_SDM845_MASK \ 32 36 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ 33 37 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ ··· 42 32 43 33 #define DMA_CURSOR_SDM845_MASK \ 44 34 (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR)) 35 + 36 + #define DMA_CURSOR_MSM8998_MASK \ 37 + (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR)) 45 38 46 39 #define MIXER_SDM845_MASK \ 47 40 (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER)) ··· 61 48 (BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG)) 62 49 63 50 #define MERGE_3D_SM8150_MASK (0) 51 + 52 + #define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC) 64 53 65 54 #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC) 66 55 ··· 105 90 BIT(MDP_INTF3_INTR) | \ 106 91 BIT(MDP_INTF4_INTR)) 107 92 93 + #define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \ 94 + BIT(MDP_SSPP_TOP0_INTR2) | \ 95 + BIT(MDP_SSPP_TOP0_HIST_INTR) | \ 96 + BIT(MDP_INTF0_INTR) | \ 97 + BIT(MDP_INTF1_INTR) | \ 98 + BIT(MDP_INTF2_INTR) | \ 99 + BIT(MDP_INTF3_INTR) | \ 100 + BIT(MDP_INTF4_INTR) | \ 101 + BIT(MDP_INTF5_INTR) | \ 102 + BIT(MDP_AD4_0_INTR) | \ 103 + BIT(MDP_AD4_1_INTR)) 108 104 109 105 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) 110 106 #define DEFAULT_DPU_LINE_WIDTH 2048 ··· 207 181 * DPU sub blocks config 208 182 *************************************************************/ 209 183 /* DPU top level caps */ 184 + static const struct dpu_caps msm8998_dpu_caps = { 185 + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 186 + .max_mixer_blendstages = 0x7, 187 + .qseed_type = DPU_SSPP_SCALER_QSEED3, 188 + .smart_dma_rev = DPU_SSPP_SMART_DMA_V1, 189 + .ubwc_version = DPU_HW_UBWC_VER_10, 190 + .has_src_split = true, 191 + .has_dim_layer = true, 192 + .has_idle_pc = true, 193 + .has_3d_merge = true, 194 + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 195 + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, 196 + .max_hdeci_exp = MAX_HORZ_DECIMATION, 197 + .max_vdeci_exp = MAX_VERT_DECIMATION, 198 + }; 199 + 210 200 static const struct dpu_caps sdm845_dpu_caps = { 211 201 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 212 202 .max_mixer_blendstages = 0xb, ··· 267 225 .max_vdeci_exp = MAX_VERT_DECIMATION, 268 226 }; 269 227 228 + static const struct dpu_caps sc8180x_dpu_caps = { 229 + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 230 + .max_mixer_blendstages = 0xb, 231 + .qseed_type = DPU_SSPP_SCALER_QSEED3, 232 + .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */ 233 + .ubwc_version = DPU_HW_UBWC_VER_30, 234 + .has_src_split = true, 235 + .has_dim_layer = true, 236 + .has_idle_pc = true, 237 + .has_3d_merge = true, 238 + .max_linewidth = 4096, 239 + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, 240 + .max_hdeci_exp = MAX_HORZ_DECIMATION, 241 + .max_vdeci_exp = MAX_VERT_DECIMATION, 242 + }; 243 + 270 244 static const struct dpu_caps sm8250_dpu_caps = { 271 245 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 272 246 .max_mixer_blendstages = 0xb, ··· 309 251 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, 310 252 }; 311 253 254 + static const struct dpu_mdp_cfg msm8998_mdp[] = { 255 + { 256 + .name = "top_0", .id = MDP_TOP, 257 + .base = 0x0, .len = 0x458, 258 + .features = 0, 259 + .highest_bank_bit = 0x2, 260 + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { 261 + .reg_off = 0x2AC, .bit_off = 0}, 262 + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { 263 + .reg_off = 0x2B4, .bit_off = 0}, 264 + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { 265 + .reg_off = 0x2BC, .bit_off = 0}, 266 + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { 267 + .reg_off = 0x2C4, .bit_off = 0}, 268 + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { 269 + .reg_off = 0x2AC, .bit_off = 8}, 270 + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { 271 + .reg_off = 0x2B4, .bit_off = 8}, 272 + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { 273 + .reg_off = 0x2C4, .bit_off = 8}, 274 + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { 275 + .reg_off = 0x2C4, .bit_off = 12}, 276 + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { 277 + .reg_off = 0x3A8, .bit_off = 15}, 278 + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { 279 + .reg_off = 0x3B0, .bit_off = 15}, 280 + }, 281 + }; 282 + 283 + static const struct dpu_caps qcm2290_dpu_caps = { 284 + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 285 + .max_mixer_blendstages = 0x4, 286 + .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, 287 + .ubwc_version = DPU_HW_UBWC_VER_20, 288 + .has_dim_layer = true, 289 + .has_idle_pc = true, 290 + .max_linewidth = 2160, 291 + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, 292 + }; 293 + 312 294 static const struct dpu_mdp_cfg sdm845_mdp[] = { 313 295 { 314 296 .name = "top_0", .id = MDP_TOP, 315 297 .base = 0x0, .len = 0x45C, 316 - .features = 0, 298 + .features = BIT(DPU_MDP_AUDIO_SELECT), 317 299 .highest_bank_bit = 0x2, 318 300 .clk_ctrls[DPU_CLK_CTRL_VIG0] = { 319 301 .reg_off = 0x2AC, .bit_off = 0}, ··· 388 290 .reg_off = 0x2B4, .bit_off = 8}, 389 291 .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { 390 292 .reg_off = 0x2C4, .bit_off = 8}, 293 + }, 294 + }; 295 + 296 + static const struct dpu_mdp_cfg sc8180x_mdp[] = { 297 + { 298 + .name = "top_0", .id = MDP_TOP, 299 + .base = 0x0, .len = 0x45C, 300 + .features = 0, 301 + .highest_bank_bit = 0x3, 302 + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { 303 + .reg_off = 0x2AC, .bit_off = 0}, 304 + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { 305 + .reg_off = 0x2B4, .bit_off = 0}, 306 + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { 307 + .reg_off = 0x2BC, .bit_off = 0}, 308 + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { 309 + .reg_off = 0x2C4, .bit_off = 0}, 310 + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { 311 + .reg_off = 0x2AC, .bit_off = 8}, 312 + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { 313 + .reg_off = 0x2B4, .bit_off = 8}, 314 + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { 315 + .reg_off = 0x2BC, .bit_off = 8}, 316 + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { 317 + .reg_off = 0x2C4, .bit_off = 8}, 391 318 }, 392 319 }; 393 320 ··· 459 336 }, 460 337 }; 461 338 339 + static const struct dpu_mdp_cfg qcm2290_mdp[] = { 340 + { 341 + .name = "top_0", .id = MDP_TOP, 342 + .base = 0x0, .len = 0x494, 343 + .features = 0, 344 + .highest_bank_bit = 0x2, 345 + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { 346 + .reg_off = 0x2AC, .bit_off = 0}, 347 + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { 348 + .reg_off = 0x2AC, .bit_off = 8}, 349 + }, 350 + }; 351 + 462 352 /************************************************************* 463 353 * CTL sub blocks config 464 354 *************************************************************/ 355 + static const struct dpu_ctl_cfg msm8998_ctl[] = { 356 + { 357 + .name = "ctl_0", .id = CTL_0, 358 + .base = 0x1000, .len = 0x94, 359 + .features = BIT(DPU_CTL_SPLIT_DISPLAY), 360 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), 361 + }, 362 + { 363 + .name = "ctl_1", .id = CTL_1, 364 + .base = 0x1200, .len = 0x94, 365 + .features = 0, 366 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), 367 + }, 368 + { 369 + .name = "ctl_2", .id = CTL_2, 370 + .base = 0x1400, .len = 0x94, 371 + .features = BIT(DPU_CTL_SPLIT_DISPLAY), 372 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), 373 + }, 374 + { 375 + .name = "ctl_3", .id = CTL_3, 376 + .base = 0x1600, .len = 0x94, 377 + .features = 0, 378 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), 379 + }, 380 + { 381 + .name = "ctl_4", .id = CTL_4, 382 + .base = 0x1800, .len = 0x94, 383 + .features = 0, 384 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), 385 + }, 386 + }; 387 + 465 388 static const struct dpu_ctl_cfg sdm845_ctl[] = { 466 389 { 467 390 .name = "ctl_0", .id = CTL_0, ··· 628 459 }, 629 460 }; 630 461 462 + static const struct dpu_ctl_cfg qcm2290_ctl[] = { 463 + { 464 + .name = "ctl_0", .id = CTL_0, 465 + .base = 0x1000, .len = 0x1dc, 466 + .features = BIT(DPU_CTL_ACTIVE_CFG), 467 + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), 468 + }, 469 + }; 470 + 631 471 /************************************************************* 632 472 * SSPP sub blocks config 633 473 *************************************************************/ ··· 675 497 .virt_num_formats = ARRAY_SIZE(plane_formats), \ 676 498 } 677 499 500 + static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = 501 + _VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3); 502 + static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = 503 + _VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3); 504 + static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = 505 + _VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3); 506 + static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = 507 + _VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3); 508 + 678 509 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = 679 510 _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3); 680 511 static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = ··· 709 522 .type = _type, \ 710 523 .clk_ctrl = _clkctrl \ 711 524 } 525 + 526 + static const struct dpu_sspp_cfg msm8998_sspp[] = { 527 + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_MSM8998_MASK, 528 + msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), 529 + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_MSM8998_MASK, 530 + msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), 531 + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_MSM8998_MASK, 532 + msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), 533 + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_MSM8998_MASK, 534 + msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), 535 + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_MSM8998_MASK, 536 + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), 537 + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_MSM8998_MASK, 538 + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), 539 + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_MSM8998_MASK, 540 + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0), 541 + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_MSM8998_MASK, 542 + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), 543 + }; 712 544 713 545 static const struct dpu_sspp_cfg sdm845_sspp[] = { 714 546 SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK, ··· 801 595 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), 802 596 }; 803 597 598 + 599 + #define _VIG_SBLK_NOSCALE(num, sdma_pri) \ 600 + { \ 601 + .maxdwnscale = SSPP_UNITY_SCALE, \ 602 + .maxupscale = SSPP_UNITY_SCALE, \ 603 + .smart_dma_priority = sdma_pri, \ 604 + .src_blk = {.name = STRCAT("sspp_src_", num), \ 605 + .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ 606 + .format_list = plane_formats_yuv, \ 607 + .num_formats = ARRAY_SIZE(plane_formats_yuv), \ 608 + .virt_format_list = plane_formats, \ 609 + .virt_num_formats = ARRAY_SIZE(plane_formats), \ 610 + } 611 + 612 + static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE("0", 2); 613 + static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK("8", 1); 614 + 615 + static const struct dpu_sspp_cfg qcm2290_sspp[] = { 616 + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_QCM2290_MASK, 617 + qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), 618 + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK, 619 + qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), 620 + }; 621 + 804 622 /************************************************************* 805 623 * MIXER sub blocks config 806 624 *************************************************************/ 807 - 808 - /* SDM845 */ 809 - 810 - static const struct dpu_lm_sub_blks sdm845_lm_sblk = { 811 - .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 812 - .maxblendstages = 11, /* excluding base layer */ 813 - .blendstage_base = { /* offsets relative to mixer base */ 814 - 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, 815 - 0xb0, 0xc8, 0xe0, 0xf8, 0x110 816 - }, 817 - }; 818 625 819 626 #define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \ 820 627 { \ ··· 839 620 .lm_pair_mask = (1 << _lmpair), \ 840 621 .dspp = _dspp \ 841 622 } 623 + 624 + /* MSM8998 */ 625 + 626 + static const struct dpu_lm_sub_blks msm8998_lm_sblk = { 627 + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 628 + .maxblendstages = 7, /* excluding base layer */ 629 + .blendstage_base = { /* offsets relative to mixer base */ 630 + 0x20, 0x50, 0x80, 0xb0, 0x230, 631 + 0x260, 0x290 632 + }, 633 + }; 634 + 635 + static const struct dpu_lm_cfg msm8998_lm[] = { 636 + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, 637 + &msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0), 638 + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, 639 + &msm8998_lm_sblk, PINGPONG_1, LM_5, DSPP_1), 640 + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, 641 + &msm8998_lm_sblk, PINGPONG_2, LM_0, 0), 642 + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, 643 + &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), 644 + LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, 645 + &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), 646 + LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, 647 + &msm8998_lm_sblk, PINGPONG_3, LM_1, 0), 648 + }; 649 + 650 + /* SDM845 */ 651 + 652 + static const struct dpu_lm_sub_blks sdm845_lm_sblk = { 653 + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 654 + .maxblendstages = 11, /* excluding base layer */ 655 + .blendstage_base = { /* offsets relative to mixer base */ 656 + 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, 657 + 0xb0, 0xc8, 0xe0, 0xf8, 0x110 658 + }, 659 + }; 842 660 843 661 static const struct dpu_lm_cfg sdm845_lm[] = { 844 662 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, ··· 935 679 &sc7180_lm_sblk, PINGPONG_3, LM_2, 0), 936 680 }; 937 681 682 + /* QCM2290 */ 683 + 684 + static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { 685 + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 686 + .maxblendstages = 4, /* excluding base layer */ 687 + .blendstage_base = { /* offsets relative to mixer base */ 688 + 0x20, 0x38, 0x50, 0x68 689 + }, 690 + }; 691 + 692 + static const struct dpu_lm_cfg qcm2290_lm[] = { 693 + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK, 694 + &qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0), 695 + }; 696 + 938 697 /************************************************************* 939 698 * DSPP sub blocks config 940 699 *************************************************************/ 700 + static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { 701 + .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, 702 + .len = 0x90, .version = 0x10007}, 703 + .gc = { .id = DPU_DSPP_GC, .base = 0x17c0, 704 + .len = 0x90, .version = 0x10007}, 705 + }; 706 + 941 707 static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = { 942 708 .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, 943 709 .len = 0x90, .version = 0x10000}, ··· 978 700 .sblk = _sblk \ 979 701 } 980 702 703 + static const struct dpu_dspp_cfg msm8998_dspp[] = { 704 + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, 705 + &msm8998_dspp_sblk), 706 + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_MSM8998_MASK, 707 + &msm8998_dspp_sblk), 708 + }; 709 + 981 710 static const struct dpu_dspp_cfg sc7180_dspp[] = { 982 711 DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, 983 712 &sc7180_dspp_sblk), ··· 998 713 DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, 999 714 &sm8150_dspp_sblk), 1000 715 DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, 716 + &sm8150_dspp_sblk), 717 + }; 718 + 719 + static const struct dpu_dspp_cfg qcm2290_dspp[] = { 720 + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, 1001 721 &sm8150_dspp_sblk), 1002 722 }; 1003 723 ··· 1088 798 -1), 1089 799 }; 1090 800 801 + static struct dpu_pingpong_cfg qcm2290_pp[] = { 802 + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, 803 + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), 804 + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), 805 + }; 806 + 1091 807 /************************************************************* 1092 808 * MERGE_3D sub blocks config 1093 809 *************************************************************/ ··· 1132 836 .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \ 1133 837 } 1134 838 839 + static const struct dpu_intf_cfg msm8998_intf[] = { 840 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), 841 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), 842 + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), 843 + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), 844 + }; 845 + 1135 846 static const struct dpu_intf_cfg sdm845_intf[] = { 1136 847 INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), 1137 848 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), ··· 1164 861 INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23), 1165 862 }; 1166 863 864 + static const struct dpu_intf_cfg sc8180x_intf[] = { 865 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), 866 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), 867 + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), 868 + /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */ 869 + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), 870 + INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21), 871 + INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23), 872 + }; 873 + 874 + static const struct dpu_intf_cfg qcm2290_intf[] = { 875 + INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0), 876 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), 877 + }; 878 + 1167 879 /************************************************************* 1168 880 * VBIF sub blocks config 1169 881 *************************************************************/ 1170 882 /* VBIF QOS remap */ 883 + static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2}; 884 + static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1}; 1171 885 static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6}; 1172 886 static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3}; 887 + 888 + static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { 889 + { 890 + .pps = 1088 * 1920 * 30, 891 + .ot_limit = 2, 892 + }, 893 + { 894 + .pps = 1088 * 1920 * 60, 895 + .ot_limit = 6, 896 + }, 897 + { 898 + .pps = 3840 * 2160 * 30, 899 + .ot_limit = 16, 900 + }, 901 + }; 902 + 903 + static const struct dpu_vbif_cfg msm8998_vbif[] = { 904 + { 905 + .name = "vbif_0", .id = VBIF_0, 906 + .base = 0, .len = 0x1040, 907 + .default_ot_rd_limit = 32, 908 + .default_ot_wr_limit = 32, 909 + .features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM), 910 + .xin_halt_timeout = 0x4000, 911 + .dynamic_ot_rd_tbl = { 912 + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), 913 + .cfg = msm8998_ot_rdwr_cfg, 914 + }, 915 + .dynamic_ot_wr_tbl = { 916 + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), 917 + .cfg = msm8998_ot_rdwr_cfg, 918 + }, 919 + .qos_rt_tbl = { 920 + .npriority_lvl = ARRAY_SIZE(msm8998_rt_pri_lvl), 921 + .priority_lvl = msm8998_rt_pri_lvl, 922 + }, 923 + .qos_nrt_tbl = { 924 + .npriority_lvl = ARRAY_SIZE(msm8998_nrt_pri_lvl), 925 + .priority_lvl = msm8998_nrt_pri_lvl, 926 + }, 927 + .memtype_count = 14, 928 + .memtype = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, 929 + }, 930 + }; 1173 931 1174 932 static const struct dpu_vbif_cfg sdm845_vbif[] = { 1175 933 { ··· 1272 908 *************************************************************/ 1273 909 1274 910 /* SSPP QOS LUTs */ 911 + static const struct dpu_qos_lut_entry msm8998_qos_linear[] = { 912 + {.fl = 4, .lut = 0x1b}, 913 + {.fl = 5, .lut = 0x5b}, 914 + {.fl = 6, .lut = 0x15b}, 915 + {.fl = 7, .lut = 0x55b}, 916 + {.fl = 8, .lut = 0x155b}, 917 + {.fl = 9, .lut = 0x555b}, 918 + {.fl = 10, .lut = 0x1555b}, 919 + {.fl = 11, .lut = 0x5555b}, 920 + {.fl = 12, .lut = 0x15555b}, 921 + {.fl = 13, .lut = 0x55555b}, 922 + {.fl = 14, .lut = 0}, 923 + {.fl = 1, .lut = 0x1b}, 924 + {.fl = 0, .lut = 0} 925 + }; 926 + 1275 927 static const struct dpu_qos_lut_entry sdm845_qos_linear[] = { 1276 928 {.fl = 4, .lut = 0x357}, 1277 929 {.fl = 5, .lut = 0x3357}, ··· 1303 923 {.fl = 0, .lut = 0x11222222223357} 1304 924 }; 1305 925 926 + static const struct dpu_qos_lut_entry msm8998_qos_macrotile[] = { 927 + {.fl = 10, .lut = 0x1aaff}, 928 + {.fl = 11, .lut = 0x5aaff}, 929 + {.fl = 12, .lut = 0x15aaff}, 930 + {.fl = 13, .lut = 0x55aaff}, 931 + {.fl = 1, .lut = 0x1aaff}, 932 + {.fl = 0, .lut = 0}, 933 + }; 934 + 1306 935 static const struct dpu_qos_lut_entry sc7180_qos_linear[] = { 1307 936 {.fl = 0, .lut = 0x0011222222335777}, 1308 937 }; 1309 938 1310 939 static const struct dpu_qos_lut_entry sm8150_qos_linear[] = { 1311 940 {.fl = 0, .lut = 0x0011222222223357 }, 941 + }; 942 + 943 + static const struct dpu_qos_lut_entry sc8180x_qos_linear[] = { 944 + {.fl = 4, .lut = 0x0000000000000357 }, 945 + }; 946 + 947 + static const struct dpu_qos_lut_entry qcm2290_qos_linear[] = { 948 + {.fl = 0, .lut = 0x0011222222335777}, 1312 949 }; 1313 950 1314 951 static const struct dpu_qos_lut_entry sdm845_qos_macrotile[] = { ··· 1341 944 {.fl = 0, .lut = 0x0011223344556677}, 1342 945 }; 1343 946 947 + static const struct dpu_qos_lut_entry sc8180x_qos_macrotile[] = { 948 + {.fl = 10, .lut = 0x0000000344556677}, 949 + }; 950 + 951 + static const struct dpu_qos_lut_entry msm8998_qos_nrt[] = { 952 + {.fl = 0, .lut = 0x0}, 953 + }; 954 + 1344 955 static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = { 1345 956 {.fl = 0, .lut = 0x0}, 1346 957 }; 1347 958 1348 959 static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { 1349 960 {.fl = 0, .lut = 0x0}, 961 + }; 962 + 963 + static const struct dpu_perf_cfg msm8998_perf_data = { 964 + .max_bw_low = 6700000, 965 + .max_bw_high = 6700000, 966 + .min_core_ib = 2400000, 967 + .min_llcc_ib = 800000, 968 + .min_dram_ib = 800000, 969 + .undersized_prefill_lines = 2, 970 + .xtra_prefill_lines = 2, 971 + .dest_scale_prefill_lines = 3, 972 + .macrotile_prefill_lines = 4, 973 + .yuv_nv12_prefill_lines = 8, 974 + .linear_prefill_lines = 1, 975 + .downscaling_prefill_lines = 1, 976 + .amortizable_threshold = 25, 977 + .min_prefill_lines = 25, 978 + .danger_lut_tbl = {0xf, 0xffff, 0x0}, 979 + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, 980 + .qos_lut_tbl = { 981 + {.nentry = ARRAY_SIZE(msm8998_qos_linear), 982 + .entries = msm8998_qos_linear 983 + }, 984 + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), 985 + .entries = msm8998_qos_macrotile 986 + }, 987 + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), 988 + .entries = msm8998_qos_nrt 989 + }, 990 + }, 991 + .cdp_cfg = { 992 + {.rd_enable = 1, .wr_enable = 1}, 993 + {.rd_enable = 1, .wr_enable = 0} 994 + }, 995 + .clk_inefficiency_factor = 200, 996 + .bw_inefficiency_factor = 120, 1350 997 }; 1351 998 1352 999 static const struct dpu_perf_cfg sdm845_perf_data = { ··· 1486 1045 .bw_inefficiency_factor = 120, 1487 1046 }; 1488 1047 1048 + static const struct dpu_perf_cfg sc8180x_perf_data = { 1049 + .max_bw_low = 9600000, 1050 + .max_bw_high = 9600000, 1051 + .min_core_ib = 2400000, 1052 + .min_llcc_ib = 800000, 1053 + .min_dram_ib = 800000, 1054 + .danger_lut_tbl = {0xf, 0xffff, 0x0}, 1055 + .qos_lut_tbl = { 1056 + {.nentry = ARRAY_SIZE(sc8180x_qos_linear), 1057 + .entries = sc8180x_qos_linear 1058 + }, 1059 + {.nentry = ARRAY_SIZE(sc8180x_qos_macrotile), 1060 + .entries = sc8180x_qos_macrotile 1061 + }, 1062 + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), 1063 + .entries = sc7180_qos_nrt 1064 + }, 1065 + /* TODO: macrotile-qseed is different from macrotile */ 1066 + }, 1067 + .cdp_cfg = { 1068 + {.rd_enable = 1, .wr_enable = 1}, 1069 + {.rd_enable = 1, .wr_enable = 0} 1070 + }, 1071 + .clk_inefficiency_factor = 105, 1072 + .bw_inefficiency_factor = 120, 1073 + }; 1074 + 1489 1075 static const struct dpu_perf_cfg sm8250_perf_data = { 1490 1076 .max_bw_low = 13700000, 1491 1077 .max_bw_high = 16600000, ··· 1570 1102 .bw_inefficiency_factor = 120, 1571 1103 }; 1572 1104 1105 + static const struct dpu_perf_cfg qcm2290_perf_data = { 1106 + .max_bw_low = 2700000, 1107 + .max_bw_high = 2700000, 1108 + .min_core_ib = 1300000, 1109 + .min_llcc_ib = 0, 1110 + .min_dram_ib = 1600000, 1111 + .min_prefill_lines = 24, 1112 + .danger_lut_tbl = {0xff, 0x0, 0x0}, 1113 + .safe_lut_tbl = {0xfff0, 0x0, 0x0}, 1114 + .qos_lut_tbl = { 1115 + {.nentry = ARRAY_SIZE(qcm2290_qos_linear), 1116 + .entries = qcm2290_qos_linear 1117 + }, 1118 + }, 1119 + .cdp_cfg = { 1120 + {.rd_enable = 1, .wr_enable = 1}, 1121 + {.rd_enable = 1, .wr_enable = 0} 1122 + }, 1123 + .clk_inefficiency_factor = 105, 1124 + .bw_inefficiency_factor = 120, 1125 + }; 1573 1126 /************************************************************* 1574 1127 * Hardware catalog init 1575 1128 *************************************************************/ 1129 + 1130 + /* 1131 + * msm8998_cfg_init(): populate sdm845 dpu sub-blocks reg offsets 1132 + * and instance counts. 1133 + */ 1134 + static void msm8998_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1135 + { 1136 + *dpu_cfg = (struct dpu_mdss_cfg){ 1137 + .caps = &msm8998_dpu_caps, 1138 + .mdp_count = ARRAY_SIZE(msm8998_mdp), 1139 + .mdp = msm8998_mdp, 1140 + .ctl_count = ARRAY_SIZE(msm8998_ctl), 1141 + .ctl = msm8998_ctl, 1142 + .sspp_count = ARRAY_SIZE(msm8998_sspp), 1143 + .sspp = msm8998_sspp, 1144 + .mixer_count = ARRAY_SIZE(msm8998_lm), 1145 + .mixer = msm8998_lm, 1146 + .dspp_count = ARRAY_SIZE(msm8998_dspp), 1147 + .dspp = msm8998_dspp, 1148 + .pingpong_count = ARRAY_SIZE(sdm845_pp), 1149 + .pingpong = sdm845_pp, 1150 + .intf_count = ARRAY_SIZE(msm8998_intf), 1151 + .intf = msm8998_intf, 1152 + .vbif_count = ARRAY_SIZE(msm8998_vbif), 1153 + .vbif = msm8998_vbif, 1154 + .reg_dma_count = 0, 1155 + .perf = msm8998_perf_data, 1156 + .mdss_irqs = IRQ_SM8250_MASK, 1157 + }; 1158 + } 1576 1159 1577 1160 /* 1578 1161 * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets ··· 1719 1200 } 1720 1201 1721 1202 /* 1203 + * sc8180x_cfg_init(): populate sc8180 dpu sub-blocks reg offsets 1204 + * and instance counts. 1205 + */ 1206 + static void sc8180x_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1207 + { 1208 + *dpu_cfg = (struct dpu_mdss_cfg){ 1209 + .caps = &sc8180x_dpu_caps, 1210 + .mdp_count = ARRAY_SIZE(sc8180x_mdp), 1211 + .mdp = sc8180x_mdp, 1212 + .ctl_count = ARRAY_SIZE(sm8150_ctl), 1213 + .ctl = sm8150_ctl, 1214 + .sspp_count = ARRAY_SIZE(sdm845_sspp), 1215 + .sspp = sdm845_sspp, 1216 + .mixer_count = ARRAY_SIZE(sm8150_lm), 1217 + .mixer = sm8150_lm, 1218 + .pingpong_count = ARRAY_SIZE(sm8150_pp), 1219 + .pingpong = sm8150_pp, 1220 + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1221 + .merge_3d = sm8150_merge_3d, 1222 + .intf_count = ARRAY_SIZE(sc8180x_intf), 1223 + .intf = sc8180x_intf, 1224 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1225 + .vbif = sdm845_vbif, 1226 + .reg_dma_count = 1, 1227 + .dma_cfg = sm8150_regdma, 1228 + .perf = sc8180x_perf_data, 1229 + .mdss_irqs = IRQ_SC8180X_MASK, 1230 + }; 1231 + } 1232 + 1233 + /* 1722 1234 * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets 1723 1235 * and instance counts. 1724 1236 */ ··· 1805 1255 }; 1806 1256 } 1807 1257 1258 + 1259 + /* 1260 + * qcm2290_cfg_init(): populate qcm2290 dpu sub-blocks reg offsets 1261 + * and instance counts. 1262 + */ 1263 + static void qcm2290_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1264 + { 1265 + *dpu_cfg = (struct dpu_mdss_cfg){ 1266 + .caps = &qcm2290_dpu_caps, 1267 + .mdp_count = ARRAY_SIZE(qcm2290_mdp), 1268 + .mdp = qcm2290_mdp, 1269 + .ctl_count = ARRAY_SIZE(qcm2290_ctl), 1270 + .ctl = qcm2290_ctl, 1271 + .sspp_count = ARRAY_SIZE(qcm2290_sspp), 1272 + .sspp = qcm2290_sspp, 1273 + .mixer_count = ARRAY_SIZE(qcm2290_lm), 1274 + .mixer = qcm2290_lm, 1275 + .dspp_count = ARRAY_SIZE(qcm2290_dspp), 1276 + .dspp = qcm2290_dspp, 1277 + .pingpong_count = ARRAY_SIZE(qcm2290_pp), 1278 + .pingpong = qcm2290_pp, 1279 + .intf_count = ARRAY_SIZE(qcm2290_intf), 1280 + .intf = qcm2290_intf, 1281 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1282 + .vbif = sdm845_vbif, 1283 + .reg_dma_count = 1, 1284 + .dma_cfg = sdm845_regdma, 1285 + .perf = qcm2290_perf_data, 1286 + .mdss_irqs = IRQ_SC7180_MASK, 1287 + }; 1288 + } 1289 + 1808 1290 static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = { 1291 + { .hw_rev = DPU_HW_VER_300, .cfg_init = msm8998_cfg_init}, 1292 + { .hw_rev = DPU_HW_VER_301, .cfg_init = msm8998_cfg_init}, 1809 1293 { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init}, 1810 1294 { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init}, 1811 1295 { .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init}, 1812 1296 { .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init}, 1297 + { .hw_rev = DPU_HW_VER_510, .cfg_init = sc8180x_cfg_init}, 1813 1298 { .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init}, 1814 1299 { .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init}, 1300 + { .hw_rev = DPU_HW_VER_650, .cfg_init = qcm2290_cfg_init}, 1815 1301 { .hw_rev = DPU_HW_VER_720, .cfg_init = sc7280_cfg_init}, 1816 1302 }; 1817 1303
+5 -16
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
··· 39 39 #define DPU_HW_VER_410 DPU_HW_VER(4, 1, 0) /* sdm670 v1.0 */ 40 40 #define DPU_HW_VER_500 DPU_HW_VER(5, 0, 0) /* sm8150 v1.0 */ 41 41 #define DPU_HW_VER_501 DPU_HW_VER(5, 0, 1) /* sm8150 v2.0 */ 42 + #define DPU_HW_VER_510 DPU_HW_VER(5, 1, 1) /* sc8180 */ 42 43 #define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250 */ 43 44 #define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */ 45 + #define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */ 44 46 #define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */ 45 47 46 48 #define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170) ··· 89 87 DPU_MDP_BWC, 90 88 DPU_MDP_UBWC_1_0, 91 89 DPU_MDP_UBWC_1_5, 90 + DPU_MDP_AUDIO_SELECT, 92 91 DPU_MDP_MAX 93 92 }; 94 93 ··· 438 435 DPU_CLK_CTRL_RGB3, 439 436 DPU_CLK_CTRL_DMA0, 440 437 DPU_CLK_CTRL_DMA1, 438 + DPU_CLK_CTRL_DMA2, 439 + DPU_CLK_CTRL_DMA3, 441 440 DPU_CLK_CTRL_CURSOR0, 442 441 DPU_CLK_CTRL_CURSOR1, 443 442 DPU_CLK_CTRL_INLINE_ROT0_SSPP, ··· 785 780 u32 hw_rev; 786 781 void (*cfg_init)(struct dpu_mdss_cfg *dpu_cfg); 787 782 }; 788 - 789 - /* 790 - * Access Macros 791 - */ 792 - #define BLK_MDP(s) ((s)->mdp) 793 - #define BLK_CTL(s) ((s)->ctl) 794 - #define BLK_VIG(s) ((s)->vig) 795 - #define BLK_RGB(s) ((s)->rgb) 796 - #define BLK_DMA(s) ((s)->dma) 797 - #define BLK_CURSOR(s) ((s)->cursor) 798 - #define BLK_MIXER(s) ((s)->mixer) 799 - #define BLK_PINGPONG(s) ((s)->pingpong) 800 - #define BLK_INTF(s) ((s)->intf) 801 - #define BLK_AD(s) ((s)->ad) 802 - #define BLK_DSPP(s) ((s)->dspp) 803 - #define BLK_MERGE3d(s) ((s)->merge_3d) 804 783 805 784 /** 806 785 * dpu_hw_catalog_init - dpu hardware catalog init API retrieves
+6
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
··· 92 92 DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1); 93 93 } 94 94 95 + static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx) 96 + { 97 + return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)); 98 + } 99 + 95 100 static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx) 96 101 { 97 102 trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask, ··· 592 587 ops->get_pending_flush = dpu_hw_ctl_get_pending_flush; 593 588 ops->get_flush_register = dpu_hw_ctl_get_flush_register; 594 589 ops->trigger_start = dpu_hw_ctl_trigger_start; 590 + ops->is_started = dpu_hw_ctl_is_started; 595 591 ops->trigger_pending = dpu_hw_ctl_trigger_pending; 596 592 ops->reset = dpu_hw_ctl_reset_control; 597 593 ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
+7
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
··· 62 62 void (*trigger_start)(struct dpu_hw_ctl *ctx); 63 63 64 64 /** 65 + * check if the ctl is started 66 + * @ctx : ctl path ctx pointer 67 + * @Return: true if started, false if stopped 68 + */ 69 + bool (*is_started)(struct dpu_hw_ctl *ctx); 70 + 71 + /** 65 72 * kickoff prepare is in progress hw operation for sw 66 73 * controlled interfaces: DSI cmd mode and WB interface 67 74 * are SW controlled
+8 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
··· 13 13 #include "dpu_hw_mdss.h" 14 14 #include "dpu_trace.h" 15 15 16 - /** 16 + /* 17 17 * Register offsets in MDSS register file for the interrupt registers 18 18 * w.r.t. to the MDP base 19 19 */ ··· 23 23 #define MDP_INTF_2_OFF 0x6B000 24 24 #define MDP_INTF_3_OFF 0x6B800 25 25 #define MDP_INTF_4_OFF 0x6C000 26 + #define MDP_INTF_5_OFF 0x6C800 26 27 #define MDP_AD4_0_OFF 0x7C000 27 28 #define MDP_AD4_1_OFF 0x7D000 28 29 #define MDP_AD4_INTR_EN_OFF 0x41c ··· 95 94 MDP_INTF_4_OFF+INTF_INTR_STATUS 96 95 }, 97 96 { 97 + MDP_INTF_5_OFF+INTF_INTR_CLEAR, 98 + MDP_INTF_5_OFF+INTF_INTR_EN, 99 + MDP_INTF_5_OFF+INTF_INTR_STATUS 100 + }, 101 + { 98 102 MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF, 99 103 MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF, 100 104 MDP_AD4_0_OFF + MDP_AD4_INTR_STATUS_OFF, ··· 146 140 147 141 /** 148 142 * dpu_core_irq_callback_handler - dispatch core interrupts 149 - * @arg: private data of callback handler 143 + * @dpu_kms: Pointer to DPU's KMS structure 150 144 * @irq_idx: interrupt index 151 145 */ 152 146 static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx)
+1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
··· 22 22 MDP_INTF2_INTR, 23 23 MDP_INTF3_INTR, 24 24 MDP_INTF4_INTR, 25 + MDP_INTF5_INTR, 25 26 MDP_AD4_0_INTR, 26 27 MDP_AD4_1_INTR, 27 28 MDP_INTF0_7xxx_INTR,
-11
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
··· 78 78 }; 79 79 80 80 struct dpu_hw_intf { 81 - struct dpu_hw_blk base; 82 81 struct dpu_hw_blk_reg_map hw; 83 82 84 83 /* intf */ ··· 88 89 /* ops */ 89 90 struct dpu_hw_intf_ops ops; 90 91 }; 91 - 92 - /** 93 - * to_dpu_hw_intf - convert base object dpu_hw_base to container 94 - * @hw: Pointer to base hardware block 95 - * return: Pointer to hardware block container 96 - */ 97 - static inline struct dpu_hw_intf *to_dpu_hw_intf(struct dpu_hw_blk *hw) 98 - { 99 - return container_of(hw, struct dpu_hw_intf, base); 100 - } 101 92 102 93 /** 103 94 * dpu_hw_intf_init(): Initializes the intf driver for the passed
+3 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
··· 268 268 ops->get_danger_status = dpu_hw_get_danger_status; 269 269 ops->setup_vsync_source = dpu_hw_setup_vsync_source; 270 270 ops->get_safe_status = dpu_hw_get_safe_status; 271 - ops->intf_audio_select = dpu_hw_intf_audio_select; 271 + 272 + if (cap & BIT(DPU_MDP_AUDIO_SELECT)) 273 + ops->intf_audio_select = dpu_hw_intf_audio_select; 272 274 } 273 275 274 276 static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp,
+1 -68
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c drivers/gpu/drm/msm/dp/dp_clk_util.c
··· 11 11 12 12 #include <drm/drm_print.h> 13 13 14 - #include "dpu_io_util.h" 14 + #include "dp_clk_util.h" 15 15 16 16 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk) 17 17 { ··· 116 116 } 117 117 } 118 118 119 - return rc; 120 - } 121 - 122 - int msm_dss_parse_clock(struct platform_device *pdev, 123 - struct dss_module_power *mp) 124 - { 125 - u32 i, rc = 0; 126 - const char *clock_name; 127 - int num_clk = 0; 128 - 129 - if (!pdev || !mp) 130 - return -EINVAL; 131 - 132 - mp->num_clk = 0; 133 - num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names"); 134 - if (num_clk <= 0) { 135 - pr_debug("clocks are not defined\n"); 136 - return 0; 137 - } 138 - 139 - mp->clk_config = devm_kcalloc(&pdev->dev, 140 - num_clk, sizeof(struct dss_clk), 141 - GFP_KERNEL); 142 - if (!mp->clk_config) 143 - return -ENOMEM; 144 - 145 - for (i = 0; i < num_clk; i++) { 146 - rc = of_property_read_string_index(pdev->dev.of_node, 147 - "clock-names", i, 148 - &clock_name); 149 - if (rc) { 150 - DRM_DEV_ERROR(&pdev->dev, "Failed to get clock name for %d\n", 151 - i); 152 - break; 153 - } 154 - strlcpy(mp->clk_config[i].clk_name, clock_name, 155 - sizeof(mp->clk_config[i].clk_name)); 156 - 157 - mp->clk_config[i].type = DSS_CLK_AHB; 158 - } 159 - 160 - rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, num_clk); 161 - if (rc) { 162 - DRM_DEV_ERROR(&pdev->dev, "Failed to get clock refs %d\n", rc); 163 - goto err; 164 - } 165 - 166 - rc = of_clk_set_defaults(pdev->dev.of_node, false); 167 - if (rc) { 168 - DRM_DEV_ERROR(&pdev->dev, "Failed to set clock defaults %d\n", rc); 169 - goto err; 170 - } 171 - 172 - for (i = 0; i < num_clk; i++) { 173 - u32 rate = clk_get_rate(mp->clk_config[i].clk); 174 - if (!rate) 175 - continue; 176 - mp->clk_config[i].rate = rate; 177 - mp->clk_config[i].type = DSS_CLK_PCLK; 178 - mp->clk_config[i].max_rate = rate; 179 - } 180 - 181 - mp->num_clk = num_clk; 182 - return 0; 183 - 184 - err: 185 - msm_dss_put_clk(mp->clk_config, num_clk); 186 119 return rc; 187 120 }
+3 -5
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h drivers/gpu/drm/msm/dp/dp_clk_util.h
··· 2 2 /* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved. 3 3 */ 4 4 5 - #ifndef __DPU_IO_UTIL_H__ 6 - #define __DPU_IO_UTIL_H__ 5 + #ifndef __DP_CLK_UTIL_H__ 6 + #define __DP_CLK_UTIL_H__ 7 7 8 8 #include <linux/platform_device.h> 9 9 #include <linux/types.h> ··· 35 35 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk); 36 36 int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk); 37 37 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable); 38 - int msm_dss_parse_clock(struct platform_device *pdev, 39 - struct dss_module_power *mp); 40 - #endif /* __DPU_IO_UTIL_H__ */ 38 + #endif /* __DP_CLK_UTIL_H__ */
+22 -46
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
··· 271 271 if (!p) 272 272 return -EINVAL; 273 273 274 + /* Only create a set of debugfs for the primary node, ignore render nodes */ 275 + if (minor->type != DRM_MINOR_PRIMARY) 276 + return 0; 277 + 274 278 dev = dpu_kms->dev; 275 279 priv = dev->dev_private; 276 280 ··· 778 774 return ret; 779 775 } 780 776 781 - static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate, 782 - struct drm_encoder *encoder) 783 - { 784 - return rate; 785 - } 786 - 787 777 static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) 788 778 { 789 779 int i; ··· 946 948 .disable_vblank = dpu_kms_disable_vblank, 947 949 .check_modified_format = dpu_format_check_modified_format, 948 950 .get_format = dpu_get_msm_format, 949 - .round_pixclk = dpu_kms_round_pixclk, 950 951 .destroy = dpu_kms_destroy, 951 952 .snapshot = dpu_kms_mdp_snapshot, 952 953 #ifdef CONFIG_DEBUG_FS ··· 995 998 return 0; 996 999 } 997 1000 998 - static struct dss_clk *_dpu_kms_get_clk(struct dpu_kms *dpu_kms, 999 - char *clock_name) 1000 - { 1001 - struct dss_module_power *mp = &dpu_kms->mp; 1002 - int i; 1003 - 1004 - for (i = 0; i < mp->num_clk; i++) { 1005 - if (!strcmp(mp->clk_config[i].clk_name, clock_name)) 1006 - return &mp->clk_config[i]; 1007 - } 1008 - 1009 - return NULL; 1010 - } 1011 - 1012 1001 u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) 1013 1002 { 1014 - struct dss_clk *clk; 1003 + struct clk *clk; 1015 1004 1016 - clk = _dpu_kms_get_clk(dpu_kms, clock_name); 1005 + clk = msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, clock_name); 1017 1006 if (!clk) 1018 1007 return -EINVAL; 1019 1008 1020 - return clk_get_rate(clk->clk); 1009 + return clk_get_rate(clk); 1021 1010 } 1022 1011 1023 1012 static int dpu_kms_hw_init(struct msm_kms *kms) ··· 1026 1043 1027 1044 atomic_set(&dpu_kms->bandwidth_ref, 0); 1028 1045 1029 - dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp", "mdp"); 1046 + dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp"); 1030 1047 if (IS_ERR(dpu_kms->mmio)) { 1031 1048 rc = PTR_ERR(dpu_kms->mmio); 1032 1049 DPU_ERROR("mdp register memory map failed: %d\n", rc); ··· 1035 1052 } 1036 1053 DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio); 1037 1054 1038 - dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif", "vbif"); 1055 + dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif"); 1039 1056 if (IS_ERR(dpu_kms->vbif[VBIF_RT])) { 1040 1057 rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]); 1041 1058 DPU_ERROR("vbif register memory map failed: %d\n", rc); 1042 1059 dpu_kms->vbif[VBIF_RT] = NULL; 1043 1060 goto error; 1044 1061 } 1045 - dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt", "vbif_nrt"); 1062 + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt"); 1046 1063 if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) { 1047 1064 dpu_kms->vbif[VBIF_NRT] = NULL; 1048 1065 DPU_DEBUG("VBIF NRT is not defined"); 1049 1066 } 1050 1067 1051 - dpu_kms->reg_dma = msm_ioremap_quiet(dpu_kms->pdev, "regdma", "regdma"); 1068 + dpu_kms->reg_dma = msm_ioremap_quiet(dpu_kms->pdev, "regdma"); 1052 1069 if (IS_ERR(dpu_kms->reg_dma)) { 1053 1070 dpu_kms->reg_dma = NULL; 1054 1071 DPU_DEBUG("REG_DMA is not defined"); ··· 1115 1132 } 1116 1133 1117 1134 rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog, 1118 - _dpu_kms_get_clk(dpu_kms, "core")); 1135 + msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, "core")); 1119 1136 if (rc) { 1120 1137 DPU_ERROR("failed to init perf %d\n", rc); 1121 1138 goto perf_err; ··· 1202 1219 struct platform_device *pdev = to_platform_device(dev); 1203 1220 struct drm_device *ddev = priv->dev; 1204 1221 struct dpu_kms *dpu_kms; 1205 - struct dss_module_power *mp; 1206 1222 int ret = 0; 1207 1223 1208 1224 dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL); ··· 1218 1236 return ret; 1219 1237 } 1220 1238 1221 - mp = &dpu_kms->mp; 1222 - ret = msm_dss_parse_clock(pdev, mp); 1223 - if (ret) { 1239 + ret = devm_clk_bulk_get_all(&pdev->dev, &dpu_kms->clocks); 1240 + if (ret < 0) { 1224 1241 DPU_ERROR("failed to parse clocks, ret=%d\n", ret); 1225 1242 return ret; 1226 1243 } 1244 + dpu_kms->num_clocks = ret; 1227 1245 1228 1246 platform_set_drvdata(pdev, dpu_kms); 1229 1247 ··· 1247 1265 { 1248 1266 struct platform_device *pdev = to_platform_device(dev); 1249 1267 struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); 1250 - struct dss_module_power *mp = &dpu_kms->mp; 1251 - 1252 - msm_dss_put_clk(mp->clk_config, mp->num_clk); 1253 - devm_kfree(&pdev->dev, mp->clk_config); 1254 - mp->num_clk = 0; 1255 1268 1256 1269 if (dpu_kms->rpm_enabled) 1257 1270 pm_runtime_disable(&pdev->dev); ··· 1270 1293 1271 1294 static int __maybe_unused dpu_runtime_suspend(struct device *dev) 1272 1295 { 1273 - int i, rc = -1; 1296 + int i; 1274 1297 struct platform_device *pdev = to_platform_device(dev); 1275 1298 struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); 1276 - struct dss_module_power *mp = &dpu_kms->mp; 1277 1299 1278 1300 /* Drop the performance state vote */ 1279 1301 dev_pm_opp_set_rate(dev, 0); 1280 - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); 1281 - if (rc) 1282 - DPU_ERROR("clock disable failed rc:%d\n", rc); 1302 + clk_bulk_disable_unprepare(dpu_kms->num_clocks, dpu_kms->clocks); 1283 1303 1284 1304 for (i = 0; i < dpu_kms->num_paths; i++) 1285 1305 icc_set_bw(dpu_kms->path[i], 0, 0); 1286 1306 1287 - return rc; 1307 + return 0; 1288 1308 } 1289 1309 1290 1310 static int __maybe_unused dpu_runtime_resume(struct device *dev) ··· 1291 1317 struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); 1292 1318 struct drm_encoder *encoder; 1293 1319 struct drm_device *ddev; 1294 - struct dss_module_power *mp = &dpu_kms->mp; 1295 1320 int i; 1296 1321 1297 1322 ddev = dpu_kms->dev; ··· 1300 1327 for (i = 0; i < dpu_kms->num_paths; i++) 1301 1328 icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); 1302 1329 1303 - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); 1330 + rc = clk_bulk_prepare_enable(dpu_kms->num_clocks, dpu_kms->clocks); 1304 1331 if (rc) { 1305 1332 DPU_ERROR("clock enable failed rc:%d\n", rc); 1306 1333 return rc; ··· 1321 1348 }; 1322 1349 1323 1350 const struct of_device_id dpu_dt_match[] = { 1351 + { .compatible = "qcom,msm8998-dpu", }, 1352 + { .compatible = "qcom,qcm2290-dpu", }, 1324 1353 { .compatible = "qcom,sdm845-dpu", }, 1325 1354 { .compatible = "qcom,sc7180-dpu", }, 1326 1355 { .compatible = "qcom,sc7280-dpu", }, 1356 + { .compatible = "qcom,sc8180x-dpu", }, 1327 1357 { .compatible = "qcom,sm8150-dpu", }, 1328 1358 { .compatible = "qcom,sm8250-dpu", }, 1329 1359 {}
+2 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
··· 21 21 #include "dpu_hw_lm.h" 22 22 #include "dpu_hw_interrupts.h" 23 23 #include "dpu_hw_top.h" 24 - #include "dpu_io_util.h" 25 24 #include "dpu_rm.h" 26 25 #include "dpu_core_perf.h" 27 26 ··· 112 113 struct platform_device *pdev; 113 114 bool rpm_enabled; 114 115 115 - struct dss_module_power mp; 116 + struct clk_bulk_data *clocks; 117 + size_t num_clocks; 116 118 117 119 /* reference count bandwidth requests, so we know when we can 118 120 * release bandwidth. Each atomic update increments, and frame- ··· 144 144 uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; 145 145 uint32_t mixer_to_enc_id[LM_MAX - LM_0]; 146 146 uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; 147 - uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; 148 147 uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; 149 148 }; 150 149
+9 -19
drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
··· 29 29 struct dpu_mdss { 30 30 struct msm_mdss base; 31 31 void __iomem *mmio; 32 - struct dss_module_power mp; 32 + struct clk_bulk_data *clocks; 33 + size_t num_clocks; 33 34 struct dpu_irq_controller irq_controller; 34 35 }; 35 36 ··· 137 136 static int dpu_mdss_enable(struct msm_mdss *mdss) 138 137 { 139 138 struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); 140 - struct dss_module_power *mp = &dpu_mdss->mp; 141 139 int ret; 142 140 143 - ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); 141 + ret = clk_bulk_prepare_enable(dpu_mdss->num_clocks, dpu_mdss->clocks); 144 142 if (ret) { 145 143 DPU_ERROR("clock enable failed, ret:%d\n", ret); 146 144 return ret; ··· 174 174 static int dpu_mdss_disable(struct msm_mdss *mdss) 175 175 { 176 176 struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); 177 - struct dss_module_power *mp = &dpu_mdss->mp; 178 - int ret; 179 177 180 - ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); 181 - if (ret) 182 - DPU_ERROR("clock disable failed, ret:%d\n", ret); 178 + clk_bulk_disable_unprepare(dpu_mdss->num_clocks, dpu_mdss->clocks); 183 179 184 - return ret; 180 + return 0; 185 181 } 186 182 187 183 static void dpu_mdss_destroy(struct msm_mdss *mdss) 188 184 { 189 185 struct platform_device *pdev = to_platform_device(mdss->dev); 190 186 struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); 191 - struct dss_module_power *mp = &dpu_mdss->mp; 192 187 int irq; 193 188 194 189 pm_runtime_suspend(mdss->dev); ··· 191 196 _dpu_mdss_irq_domain_fini(dpu_mdss); 192 197 irq = platform_get_irq(pdev, 0); 193 198 irq_set_chained_handler_and_data(irq, NULL, NULL); 194 - msm_dss_put_clk(mp->clk_config, mp->num_clk); 195 - devm_kfree(&pdev->dev, mp->clk_config); 196 199 197 200 if (dpu_mdss->mmio) 198 201 devm_iounmap(&pdev->dev, dpu_mdss->mmio); ··· 207 214 { 208 215 struct msm_drm_private *priv = platform_get_drvdata(pdev); 209 216 struct dpu_mdss *dpu_mdss; 210 - struct dss_module_power *mp; 211 217 int ret; 212 218 int irq; 213 219 ··· 214 222 if (!dpu_mdss) 215 223 return -ENOMEM; 216 224 217 - dpu_mdss->mmio = msm_ioremap(pdev, "mdss", "mdss"); 225 + dpu_mdss->mmio = msm_ioremap(pdev, "mdss"); 218 226 if (IS_ERR(dpu_mdss->mmio)) 219 227 return PTR_ERR(dpu_mdss->mmio); 220 228 221 229 DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio); 222 230 223 - mp = &dpu_mdss->mp; 224 - ret = msm_dss_parse_clock(pdev, mp); 225 - if (ret) { 231 + ret = devm_clk_bulk_get_all(&pdev->dev, &dpu_mdss->clocks); 232 + if (ret < 0) { 226 233 DPU_ERROR("failed to parse clocks, ret=%d\n", ret); 227 234 goto clk_parse_err; 228 235 } 236 + dpu_mdss->num_clocks = ret; 229 237 230 238 dpu_mdss->base.dev = &pdev->dev; 231 239 dpu_mdss->base.funcs = &mdss_funcs; ··· 252 260 irq_error: 253 261 _dpu_mdss_irq_domain_fini(dpu_mdss); 254 262 irq_domain_error: 255 - msm_dss_put_clk(mp->clk_config, mp->num_clk); 256 263 clk_parse_err: 257 - devm_kfree(&pdev->dev, mp->clk_config); 258 264 if (dpu_mdss->mmio) 259 265 devm_iounmap(&pdev->dev, dpu_mdss->mmio); 260 266 dpu_mdss->mmio = NULL;
+3 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
··· 902 902 903 903 if (pstate->aspace) { 904 904 ret = msm_framebuffer_prepare(new_state->fb, 905 - pstate->aspace); 905 + pstate->aspace, pstate->needs_dirtyfb); 906 906 if (ret) { 907 907 DPU_ERROR("failed to prepare framebuffer\n"); 908 908 return ret; ··· 933 933 934 934 DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", old_state->fb->base.id); 935 935 936 - msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace); 936 + msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace, 937 + old_pstate->needs_dirtyfb); 937 938 } 938 939 939 940 static bool dpu_plane_validate_src(struct drm_rect *src,
+3
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
··· 25 25 * @pending: whether the current update is still pending 26 26 * @plane_fetch_bw: calculated BW per plane 27 27 * @plane_clk: calculated clk per plane 28 + * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed 28 29 */ 29 30 struct dpu_plane_state { 30 31 struct drm_plane_state base; ··· 38 37 39 38 u64 plane_fetch_bw; 40 39 u64 plane_clk; 40 + 41 + bool needs_dirtyfb; 41 42 }; 42 43 43 44 /**
+17 -90
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
··· 28 28 */ 29 29 struct dpu_rm_requirements { 30 30 struct msm_display_topology topology; 31 - struct dpu_encoder_hw_resources hw_res; 32 31 }; 33 32 34 33 int dpu_rm_destroy(struct dpu_rm *rm) 35 34 { 36 35 int i; 37 36 37 + for (i = 0; i < ARRAY_SIZE(rm->dspp_blks); i++) { 38 + struct dpu_hw_dspp *hw; 39 + 40 + if (rm->dspp_blks[i]) { 41 + hw = to_dpu_hw_dspp(rm->dspp_blks[i]); 42 + dpu_hw_dspp_destroy(hw); 43 + } 44 + } 38 45 for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) { 39 46 struct dpu_hw_pingpong *hw; 40 47 ··· 74 67 dpu_hw_ctl_destroy(hw); 75 68 } 76 69 } 77 - for (i = 0; i < ARRAY_SIZE(rm->intf_blks); i++) { 78 - struct dpu_hw_intf *hw; 79 - 80 - if (rm->intf_blks[i]) { 81 - hw = to_dpu_hw_intf(rm->intf_blks[i]); 82 - dpu_hw_intf_destroy(hw); 83 - } 84 - } 70 + for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++) 71 + dpu_hw_intf_destroy(rm->hw_intf[i]); 85 72 86 73 return 0; 87 74 } ··· 109 108 continue; 110 109 } 111 110 hw = dpu_hw_lm_init(lm->id, mmio, cat); 112 - if (IS_ERR_OR_NULL(hw)) { 111 + if (IS_ERR(hw)) { 113 112 rc = PTR_ERR(hw); 114 113 DPU_ERROR("failed lm object creation: err %d\n", rc); 115 114 goto fail; 116 115 } 117 116 rm->mixer_blks[lm->id - LM_0] = &hw->base; 118 - 119 - if (!rm->lm_max_width) { 120 - rm->lm_max_width = lm->sblk->maxwidth; 121 - } else if (rm->lm_max_width != lm->sblk->maxwidth) { 122 - /* 123 - * Don't expect to have hw where lm max widths differ. 124 - * If found, take the min. 125 - */ 126 - DPU_ERROR("unsupported: lm maxwidth differs\n"); 127 - if (rm->lm_max_width > lm->sblk->maxwidth) 128 - rm->lm_max_width = lm->sblk->maxwidth; 129 - } 130 117 } 131 118 132 119 for (i = 0; i < cat->merge_3d_count; i++) { ··· 126 137 continue; 127 138 } 128 139 hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat); 129 - if (IS_ERR_OR_NULL(hw)) { 140 + if (IS_ERR(hw)) { 130 141 rc = PTR_ERR(hw); 131 142 DPU_ERROR("failed merge_3d object creation: err %d\n", 132 143 rc); ··· 144 155 continue; 145 156 } 146 157 hw = dpu_hw_pingpong_init(pp->id, mmio, cat); 147 - if (IS_ERR_OR_NULL(hw)) { 158 + if (IS_ERR(hw)) { 148 159 rc = PTR_ERR(hw); 149 160 DPU_ERROR("failed pingpong object creation: err %d\n", 150 161 rc); ··· 168 179 continue; 169 180 } 170 181 hw = dpu_hw_intf_init(intf->id, mmio, cat); 171 - if (IS_ERR_OR_NULL(hw)) { 182 + if (IS_ERR(hw)) { 172 183 rc = PTR_ERR(hw); 173 184 DPU_ERROR("failed intf object creation: err %d\n", rc); 174 185 goto fail; 175 186 } 176 - rm->intf_blks[intf->id - INTF_0] = &hw->base; 187 + rm->hw_intf[intf->id - INTF_0] = hw; 177 188 } 178 189 179 190 for (i = 0; i < cat->ctl_count; i++) { ··· 185 196 continue; 186 197 } 187 198 hw = dpu_hw_ctl_init(ctl->id, mmio, cat); 188 - if (IS_ERR_OR_NULL(hw)) { 199 + if (IS_ERR(hw)) { 189 200 rc = PTR_ERR(hw); 190 201 DPU_ERROR("failed ctl object creation: err %d\n", rc); 191 202 goto fail; ··· 202 213 continue; 203 214 } 204 215 hw = dpu_hw_dspp_init(dspp->id, mmio, cat); 205 - if (IS_ERR_OR_NULL(hw)) { 216 + if (IS_ERR(hw)) { 206 217 rc = PTR_ERR(hw); 207 218 DPU_ERROR("failed dspp object creation: err %d\n", rc); 208 219 goto fail; ··· 441 452 return 0; 442 453 } 443 454 444 - static int _dpu_rm_reserve_intf( 445 - struct dpu_rm *rm, 446 - struct dpu_global_state *global_state, 447 - uint32_t enc_id, 448 - uint32_t id) 449 - { 450 - int idx = id - INTF_0; 451 - 452 - if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) { 453 - DPU_ERROR("invalid intf id: %d", id); 454 - return -EINVAL; 455 - } 456 - 457 - if (!rm->intf_blks[idx]) { 458 - DPU_ERROR("couldn't find intf id %d\n", id); 459 - return -EINVAL; 460 - } 461 - 462 - if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) { 463 - DPU_ERROR("intf id %d already reserved\n", id); 464 - return -ENAVAIL; 465 - } 466 - 467 - global_state->intf_to_enc_id[idx] = enc_id; 468 - return 0; 469 - } 470 - 471 - static int _dpu_rm_reserve_intf_related_hw( 472 - struct dpu_rm *rm, 473 - struct dpu_global_state *global_state, 474 - uint32_t enc_id, 475 - struct dpu_encoder_hw_resources *hw_res) 476 - { 477 - int i, ret = 0; 478 - u32 id; 479 - 480 - for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) { 481 - if (hw_res->intfs[i] == INTF_MODE_NONE) 482 - continue; 483 - id = i + INTF_0; 484 - ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id); 485 - if (ret) 486 - return ret; 487 - } 488 - 489 - return ret; 490 - } 491 - 492 455 static int _dpu_rm_make_reservation( 493 456 struct dpu_rm *rm, 494 457 struct dpu_global_state *global_state, ··· 462 521 return ret; 463 522 } 464 523 465 - ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, enc->base.id, 466 - &reqs->hw_res); 467 - if (ret) 468 - return ret; 469 - 470 524 return ret; 471 525 } 472 526 ··· 470 534 struct dpu_rm_requirements *reqs, 471 535 struct msm_display_topology req_topology) 472 536 { 473 - dpu_encoder_get_hw_resources(enc, &reqs->hw_res); 474 - 475 537 reqs->topology = req_topology; 476 538 477 539 DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n", ··· 499 565 ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id); 500 566 _dpu_rm_clear_mapping(global_state->ctl_to_enc_id, 501 567 ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); 502 - _dpu_rm_clear_mapping(global_state->intf_to_enc_id, 503 - ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id); 504 568 } 505 569 506 570 int dpu_rm_reserve( ··· 561 629 hw_blks = rm->ctl_blks; 562 630 hw_to_enc_id = global_state->ctl_to_enc_id; 563 631 max_blks = ARRAY_SIZE(rm->ctl_blks); 564 - break; 565 - case DPU_HW_BLK_INTF: 566 - hw_blks = rm->intf_blks; 567 - hw_to_enc_id = global_state->intf_to_enc_id; 568 - max_blks = ARRAY_SIZE(rm->intf_blks); 569 632 break; 570 633 case DPU_HW_BLK_DSPP: 571 634 hw_blks = rm->dspp_blks;
+13 -6
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
··· 18 18 * @pingpong_blks: array of pingpong hardware resources 19 19 * @mixer_blks: array of layer mixer hardware resources 20 20 * @ctl_blks: array of ctl hardware resources 21 - * @intf_blks: array of intf hardware resources 21 + * @hw_intf: array of intf hardware resources 22 22 * @dspp_blks: array of dspp hardware resources 23 - * @lm_max_width: cached layer mixer maximum width 24 - * @rm_lock: resource manager mutex 25 23 */ 26 24 struct dpu_rm { 27 25 struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; 28 26 struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0]; 29 27 struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; 30 - struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0]; 28 + struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0]; 31 29 struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0]; 32 30 struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; 33 - 34 - uint32_t lm_max_width; 35 31 }; 36 32 37 33 /** ··· 84 88 int dpu_rm_get_assigned_resources(struct dpu_rm *rm, 85 89 struct dpu_global_state *global_state, uint32_t enc_id, 86 90 enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); 91 + 92 + /** 93 + * dpu_rm_get_intf - Return a struct dpu_hw_intf instance given it's index. 94 + * @rm: DPU Resource Manager handle 95 + * @intf_idx: INTF's index 96 + */ 97 + static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx) 98 + { 99 + return rm->hw_intf[intf_idx - INTF_0]; 100 + } 101 + 87 102 #endif /* __DPU_RM_H__ */ 88 103
+1 -1
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
··· 418 418 419 419 mdp4_kms->dev = dev; 420 420 421 - mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4"); 421 + mdp4_kms->mmio = msm_ioremap(pdev, NULL); 422 422 if (IS_ERR(mdp4_kms->mmio)) { 423 423 ret = PTR_ERR(mdp4_kms->mmio); 424 424 goto fail;
+17 -2
drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
··· 7 7 #include <drm/drm_atomic.h> 8 8 #include <drm/drm_damage_helper.h> 9 9 #include <drm/drm_fourcc.h> 10 + #include <drm/drm_gem_atomic_helper.h> 10 11 11 12 #include "mdp4_kms.h" 12 13 ··· 91 90 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 92 91 }; 93 92 93 + static int mdp4_plane_prepare_fb(struct drm_plane *plane, 94 + struct drm_plane_state *new_state) 95 + { 96 + struct msm_drm_private *priv = plane->dev->dev_private; 97 + struct msm_kms *kms = priv->kms; 98 + 99 + if (!new_state->fb) 100 + return 0; 101 + 102 + drm_gem_plane_helper_prepare_fb(plane, new_state); 103 + 104 + return msm_framebuffer_prepare(new_state->fb, kms->aspace, false); 105 + } 106 + 94 107 static void mdp4_plane_cleanup_fb(struct drm_plane *plane, 95 108 struct drm_plane_state *old_state) 96 109 { ··· 117 102 return; 118 103 119 104 DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); 120 - msm_framebuffer_cleanup(fb, kms->aspace); 105 + msm_framebuffer_cleanup(fb, kms->aspace, false); 121 106 } 122 107 123 108 ··· 145 130 } 146 131 147 132 static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = { 148 - .prepare_fb = msm_atomic_prepare_fb, 133 + .prepare_fb = mdp4_plane_prepare_fb, 149 134 .cleanup_fb = mdp4_plane_cleanup_fb, 150 135 .atomic_check = mdp4_plane_atomic_check, 151 136 .atomic_update = mdp4_plane_atomic_update,
+8
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
··· 690 690 { 691 691 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, 692 692 crtc); 693 + struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state); 694 + struct mdp5_interface *intf = mdp5_cstate->pipeline.intf; 693 695 struct mdp5_kms *mdp5_kms = get_kms(crtc); 694 696 struct drm_plane *plane; 695 697 struct drm_device *dev = crtc->dev; ··· 708 706 DBG("%s: check", crtc->name); 709 707 710 708 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { 709 + struct mdp5_plane_state *mdp5_pstate = 710 + to_mdp5_plane_state(pstate); 711 + 711 712 if (!pstate->visible) 712 713 continue; 713 714 714 715 pstates[cnt].plane = plane; 715 716 pstates[cnt].state = to_mdp5_plane_state(pstate); 717 + 718 + mdp5_pstate->needs_dirtyfb = 719 + intf->mode == MDP5_INTF_DSI_MODE_COMMAND; 716 720 717 721 /* 718 722 * if any plane on this crtc uses 2 hwpipes, then we need
+1 -8
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
··· 190 190 mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp); 191 191 } 192 192 193 - static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate, 194 - struct drm_encoder *encoder) 195 - { 196 - return rate; 197 - } 198 - 199 193 static int mdp5_set_split_display(struct msm_kms *kms, 200 194 struct drm_encoder *encoder, 201 195 struct drm_encoder *slave_encoder, ··· 272 278 .wait_flush = mdp5_wait_flush, 273 279 .complete_commit = mdp5_complete_commit, 274 280 .get_format = mdp_get_format, 275 - .round_pixclk = mdp5_round_pixclk, 276 281 .set_split_display = mdp5_set_split_display, 277 282 .destroy = mdp5_kms_destroy, 278 283 #ifdef CONFIG_DEBUG_FS ··· 820 827 if (ret) 821 828 goto fail; 822 829 823 - mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5"); 830 + mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys"); 824 831 if (IS_ERR(mdp5_kms->mmio)) { 825 832 ret = PTR_ERR(mdp5_kms->mmio); 826 833 goto fail;
+5
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
··· 100 100 101 101 /* assigned by crtc blender */ 102 102 enum mdp_mixer_stage_id stage; 103 + 104 + /* whether attached CRTC needs pixel data explicitly flushed to 105 + * display (ex. DSI command mode display) 106 + */ 107 + bool needs_dirtyfb; 103 108 }; 104 109 #define to_mdp5_plane_state(x) \ 105 110 container_of(x, struct mdp5_plane_state, base)
+2 -2
drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
··· 210 210 211 211 mdp5_mdss->base.dev = &pdev->dev; 212 212 213 - mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS"); 213 + mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys"); 214 214 if (IS_ERR(mdp5_mdss->mmio)) { 215 215 ret = PTR_ERR(mdp5_mdss->mmio); 216 216 goto fail; 217 217 } 218 218 219 - mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF"); 219 + mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys"); 220 220 if (IS_ERR(mdp5_mdss->vbif)) { 221 221 ret = PTR_ERR(mdp5_mdss->vbif); 222 222 goto fail;
+19 -2
drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
··· 8 8 #include <drm/drm_atomic.h> 9 9 #include <drm/drm_damage_helper.h> 10 10 #include <drm/drm_fourcc.h> 11 + #include <drm/drm_gem_atomic_helper.h> 11 12 #include <drm/drm_print.h> 12 13 13 14 #include "mdp5_kms.h" ··· 141 140 .atomic_print_state = mdp5_plane_atomic_print_state, 142 141 }; 143 142 143 + static int mdp5_plane_prepare_fb(struct drm_plane *plane, 144 + struct drm_plane_state *new_state) 145 + { 146 + struct msm_drm_private *priv = plane->dev->dev_private; 147 + struct msm_kms *kms = priv->kms; 148 + bool needs_dirtyfb = to_mdp5_plane_state(new_state)->needs_dirtyfb; 149 + 150 + if (!new_state->fb) 151 + return 0; 152 + 153 + drm_gem_plane_helper_prepare_fb(plane, new_state); 154 + 155 + return msm_framebuffer_prepare(new_state->fb, kms->aspace, needs_dirtyfb); 156 + } 157 + 144 158 static void mdp5_plane_cleanup_fb(struct drm_plane *plane, 145 159 struct drm_plane_state *old_state) 146 160 { 147 161 struct mdp5_kms *mdp5_kms = get_kms(plane); 148 162 struct msm_kms *kms = &mdp5_kms->base.base; 149 163 struct drm_framebuffer *fb = old_state->fb; 164 + bool needed_dirtyfb = to_mdp5_plane_state(old_state)->needs_dirtyfb; 150 165 151 166 if (!fb) 152 167 return; 153 168 154 169 DBG("%s: cleanup: FB[%u]", plane->name, fb->base.id); 155 - msm_framebuffer_cleanup(fb, kms->aspace); 170 + msm_framebuffer_cleanup(fb, kms->aspace, needed_dirtyfb); 156 171 } 157 172 158 173 static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, ··· 454 437 } 455 438 456 439 static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { 457 - .prepare_fb = msm_atomic_prepare_fb, 440 + .prepare_fb = mdp5_plane_prepare_fb, 458 441 .cleanup_fb = mdp5_plane_cleanup_fb, 459 442 .atomic_check = mdp5_plane_atomic_check, 460 443 .atomic_update = mdp5_plane_atomic_update,
+1 -1
drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
··· 68 68 uint8_t reserved; 69 69 70 70 /* we shouldn't be requesting blocks for an in-use client: */ 71 - WARN_ON(bitmap_weight(cs, cnt) > 0); 71 + WARN_ON(!bitmap_empty(cs, cnt)); 72 72 73 73 reserved = smp->reserved[cid]; 74 74
+6 -6
drivers/gpu/drm/msm/dp/dp_catalog.c
··· 456 456 dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0); 457 457 } 458 458 459 - int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, 460 - u32 pattern) 459 + int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, 460 + u32 state_bit) 461 461 { 462 462 int bit, ret; 463 463 u32 data; 464 464 struct dp_catalog_private *catalog = container_of(dp_catalog, 465 465 struct dp_catalog_private, dp_catalog); 466 466 467 - bit = BIT(pattern - 1); 468 - DRM_DEBUG_DP("hw: bit=%d train=%d\n", bit, pattern); 467 + bit = BIT(state_bit - 1); 468 + DRM_DEBUG_DP("hw: bit=%d train=%d\n", bit, state_bit); 469 469 dp_catalog_ctrl_state_ctrl(dp_catalog, bit); 470 470 471 - bit = BIT(pattern - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; 471 + bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; 472 472 473 473 /* Poll for mainlink ready status */ 474 474 ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base + ··· 476 476 data, data & bit, 477 477 POLLING_SLEEP_US, POLLING_TIMEOUT_US); 478 478 if (ret < 0) { 479 - DRM_ERROR("set pattern for link_train=%d failed\n", pattern); 479 + DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit); 480 480 return ret; 481 481 } 482 482 return 0;
+1 -1
drivers/gpu/drm/msm/dp/dp_catalog.h
··· 94 94 void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb); 95 95 void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate, 96 96 u32 stream_rate_khz, bool fixed_nvid); 97 - int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, u32 pattern); 97 + int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern); 98 98 void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog); 99 99 bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); 100 100 void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
+51 -61
drivers/gpu/drm/msm/dp/dp_ctrl.c
··· 1083 1083 1084 1084 *training_step = DP_TRAINING_1; 1085 1085 1086 - ret = dp_catalog_ctrl_set_pattern(ctrl->catalog, DP_TRAINING_PATTERN_1); 1086 + ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1); 1087 1087 if (ret) 1088 1088 return ret; 1089 1089 dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 | ··· 1181 1181 int *training_step) 1182 1182 { 1183 1183 int tries = 0, ret = 0; 1184 - char pattern; 1184 + u8 pattern; 1185 + u32 state_ctrl_bit; 1185 1186 int const maximum_retries = 5; 1186 1187 u8 link_status[DP_LINK_STATUS_SIZE]; 1187 1188 ··· 1190 1189 1191 1190 *training_step = DP_TRAINING_2; 1192 1191 1193 - if (drm_dp_tps3_supported(ctrl->panel->dpcd)) 1192 + if (drm_dp_tps4_supported(ctrl->panel->dpcd)) { 1193 + pattern = DP_TRAINING_PATTERN_4; 1194 + state_ctrl_bit = 4; 1195 + } else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) { 1194 1196 pattern = DP_TRAINING_PATTERN_3; 1195 - else 1197 + state_ctrl_bit = 3; 1198 + } else { 1196 1199 pattern = DP_TRAINING_PATTERN_2; 1200 + state_ctrl_bit = 2; 1201 + } 1197 1202 1198 - ret = dp_catalog_ctrl_set_pattern(ctrl->catalog, pattern); 1203 + ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit); 1199 1204 if (ret) 1200 1205 return ret; 1201 1206 ··· 1372 1365 return ret; 1373 1366 } 1374 1367 1375 - int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset) 1368 + void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable) 1376 1369 { 1377 1370 struct dp_ctrl_private *ctrl; 1378 - struct dp_io *dp_io; 1379 - struct phy *phy; 1380 - 1381 - if (!dp_ctrl) { 1382 - DRM_ERROR("Invalid input data\n"); 1383 - return -EINVAL; 1384 - } 1385 1371 1386 1372 ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); 1387 - dp_io = &ctrl->parser->io; 1388 - phy = dp_io->phy; 1389 1373 1390 - ctrl->dp_ctrl.orientation = flip; 1374 + dp_catalog_ctrl_reset(ctrl->catalog); 1391 1375 1392 - if (reset) 1393 - dp_catalog_ctrl_reset(ctrl->catalog); 1394 - 1395 - DRM_DEBUG_DP("flip=%d\n", flip); 1396 - dp_catalog_ctrl_phy_reset(ctrl->catalog); 1397 - phy_init(phy); 1398 - dp_catalog_ctrl_enable_irq(ctrl->catalog, true); 1399 - 1400 - return 0; 1376 + if (enable) 1377 + dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); 1401 1378 } 1402 1379 1403 - /** 1404 - * dp_ctrl_host_deinit() - Uninitialize DP controller 1405 - * @dp_ctrl: Display Port Driver data 1406 - * 1407 - * Perform required steps to uninitialize DP controller 1408 - * and its resources. 1409 - */ 1410 - void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl) 1380 + void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl) 1411 1381 { 1412 1382 struct dp_ctrl_private *ctrl; 1413 1383 struct dp_io *dp_io; 1414 1384 struct phy *phy; 1415 1385 1416 - if (!dp_ctrl) { 1417 - DRM_ERROR("Invalid input data\n"); 1418 - return; 1419 - } 1386 + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); 1387 + dp_io = &ctrl->parser->io; 1388 + phy = dp_io->phy; 1389 + 1390 + dp_catalog_ctrl_phy_reset(ctrl->catalog); 1391 + phy_init(phy); 1392 + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", 1393 + phy, phy->init_count, phy->power_count); 1394 + } 1395 + 1396 + void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl) 1397 + { 1398 + struct dp_ctrl_private *ctrl; 1399 + struct dp_io *dp_io; 1400 + struct phy *phy; 1420 1401 1421 1402 ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); 1422 1403 dp_io = &ctrl->parser->io; 1423 1404 phy = dp_io->phy; 1424 1405 1425 - dp_catalog_ctrl_enable_irq(ctrl->catalog, false); 1406 + dp_catalog_ctrl_phy_reset(ctrl->catalog); 1426 1407 phy_exit(phy); 1427 - 1428 - DRM_DEBUG_DP("Host deinitialized successfully\n"); 1408 + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", 1409 + phy, phy->init_count, phy->power_count); 1429 1410 } 1430 1411 1431 1412 static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl) ··· 1483 1488 } 1484 1489 1485 1490 phy_power_off(phy); 1486 - phy_exit(phy); 1487 1491 1492 + /* aux channel down, reinit phy */ 1493 + phy_exit(phy); 1494 + phy_init(phy); 1495 + 1496 + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", 1497 + phy, phy->init_count, phy->power_count); 1488 1498 return 0; 1489 1499 } 1490 1500 ··· 1761 1761 /* end with failure */ 1762 1762 break; /* lane == 1 already */ 1763 1763 } 1764 + 1765 + /* stop link training before start re training */ 1766 + dp_ctrl_clear_training_pattern(ctrl); 1764 1767 } 1765 1768 } 1766 1769 ··· 1896 1893 return ret; 1897 1894 } 1898 1895 1896 + DRM_DEBUG_DP("Before, phy=%x init_count=%d power_on=%d\n", 1897 + (u32)(uintptr_t)phy, phy->init_count, phy->power_count); 1898 + 1899 1899 phy_power_off(phy); 1900 1900 1901 1901 /* aux channel down, reinit phy */ 1902 1902 phy_exit(phy); 1903 1903 phy_init(phy); 1904 1904 1905 - DRM_DEBUG_DP("DP off link/stream done\n"); 1905 + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", 1906 + phy, phy->init_count, phy->power_count); 1906 1907 return ret; 1907 - } 1908 - 1909 - void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl) 1910 - { 1911 - struct dp_ctrl_private *ctrl; 1912 - struct dp_io *dp_io; 1913 - struct phy *phy; 1914 - 1915 - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); 1916 - dp_io = &ctrl->parser->io; 1917 - phy = dp_io->phy; 1918 - 1919 - dp_catalog_ctrl_reset(ctrl->catalog); 1920 - 1921 - phy_exit(phy); 1922 - 1923 - DRM_DEBUG_DP("DP off phy done\n"); 1924 1908 } 1925 1909 1926 1910 int dp_ctrl_off(struct dp_ctrl *dp_ctrl) ··· 1938 1948 } 1939 1949 1940 1950 phy_power_off(phy); 1941 - phy_exit(phy); 1951 + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", 1952 + phy, phy->init_count, phy->power_count); 1942 1953 1943 - DRM_DEBUG_DP("DP off done\n"); 1944 1954 return ret; 1945 1955 } 1946 1956
+5 -3
drivers/gpu/drm/msm/dp/dp_ctrl.h
··· 19 19 u32 pixel_rate; 20 20 }; 21 21 22 - int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset); 23 - void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl); 24 22 int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); 25 23 int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl); 26 24 int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); 27 - void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl); 28 25 int dp_ctrl_off(struct dp_ctrl *dp_ctrl); 29 26 void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl); 30 27 void dp_ctrl_isr(struct dp_ctrl *dp_ctrl); ··· 30 33 struct dp_panel *panel, struct drm_dp_aux *aux, 31 34 struct dp_power *power, struct dp_catalog *catalog, 32 35 struct dp_parser *parser); 36 + 37 + void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable); 38 + void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl); 39 + void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl); 40 + void dp_ctrl_irq_phy_exit(struct dp_ctrl *dp_ctrl); 33 41 34 42 #endif /* _DP_CTRL_H_ */
+12 -16
drivers/gpu/drm/msm/dp/dp_debug.c
··· 207 207 .write = dp_test_active_write 208 208 }; 209 209 210 - static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) 210 + static void dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) 211 211 { 212 - int rc = 0; 212 + char path[64]; 213 213 struct dp_debug_private *debug = container_of(dp_debug, 214 214 struct dp_debug_private, dp_debug); 215 215 216 - debugfs_create_file("dp_debug", 0444, minor->debugfs_root, 216 + snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name); 217 + 218 + debug->root = debugfs_create_dir(path, minor->debugfs_root); 219 + 220 + debugfs_create_file("dp_debug", 0444, debug->root, 217 221 debug, &dp_debug_fops); 218 222 219 223 debugfs_create_file("msm_dp_test_active", 0444, 220 - minor->debugfs_root, 224 + debug->root, 221 225 debug, &test_active_fops); 222 226 223 227 debugfs_create_file("msm_dp_test_data", 0444, 224 - minor->debugfs_root, 228 + debug->root, 225 229 debug, &dp_test_data_fops); 226 230 227 231 debugfs_create_file("msm_dp_test_type", 0444, 228 - minor->debugfs_root, 232 + debug->root, 229 233 debug, &dp_test_type_fops); 230 - 231 - debug->root = minor->debugfs_root; 232 - 233 - return rc; 234 234 } 235 235 236 236 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 237 237 struct dp_usbpd *usbpd, struct dp_link *link, 238 238 struct drm_connector *connector, struct drm_minor *minor) 239 239 { 240 - int rc = 0; 241 240 struct dp_debug_private *debug; 242 241 struct dp_debug *dp_debug; 242 + int rc; 243 243 244 244 if (!dev || !panel || !usbpd || !link) { 245 245 DRM_ERROR("invalid input\n"); ··· 266 266 dp_debug->hdisplay = 0; 267 267 dp_debug->vrefresh = 0; 268 268 269 - rc = dp_debug_init(dp_debug, minor); 270 - if (rc) { 271 - devm_kfree(dev, debug); 272 - goto error; 273 - } 269 + dp_debug_init(dp_debug, minor); 274 270 275 271 return dp_debug; 276 272 error:
+126 -70
drivers/gpu/drm/msm/dp/dp_display.c
··· 83 83 84 84 /* state variables */ 85 85 bool core_initialized; 86 + bool phy_initialized; 86 87 bool hpd_irq_on; 87 88 bool audio_supported; 88 89 ··· 144 143 .num_descs = 2, 145 144 }; 146 145 146 + static const struct msm_dp_config sc8180x_dp_cfg = { 147 + .descs = (const struct msm_dp_desc[]) { 148 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 149 + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 150 + [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, 151 + }, 152 + .num_descs = 3, 153 + }; 154 + 155 + static const struct msm_dp_config sm8350_dp_cfg = { 156 + .descs = (const struct msm_dp_desc[]) { 157 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 158 + }, 159 + .num_descs = 1, 160 + }; 161 + 147 162 static const struct of_device_id dp_dt_match[] = { 148 163 { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg }, 149 164 { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_cfg }, 150 165 { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg }, 166 + { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg }, 167 + { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg }, 168 + { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_cfg }, 151 169 {} 152 170 }; 153 171 ··· 266 246 goto end; 267 247 } 268 248 269 - dp->dp_display.panel_bridge = dp->parser->panel_bridge; 249 + dp->dp_display.next_bridge = dp->parser->next_bridge; 270 250 271 251 dp->aux->drm_dev = drm; 272 252 rc = dp_aux_register(dp->aux); ··· 392 372 return rc; 393 373 } 394 374 395 - static void dp_display_host_init(struct dp_display_private *dp, int reset) 375 + static void dp_display_host_phy_init(struct dp_display_private *dp) 396 376 { 397 - bool flip = false; 377 + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", 378 + dp->dp_display.connector_type, dp->core_initialized, 379 + dp->phy_initialized); 398 380 399 - DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized); 400 - if (dp->core_initialized) { 401 - DRM_DEBUG_DP("DP core already initialized\n"); 402 - return; 381 + if (!dp->phy_initialized) { 382 + dp_ctrl_phy_init(dp->ctrl); 383 + dp->phy_initialized = true; 403 384 } 385 + } 404 386 405 - if (dp->usbpd->orientation == ORIENTATION_CC2) 406 - flip = true; 387 + static void dp_display_host_phy_exit(struct dp_display_private *dp) 388 + { 389 + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", 390 + dp->dp_display.connector_type, dp->core_initialized, 391 + dp->phy_initialized); 407 392 408 - dp_power_init(dp->power, flip); 409 - dp_ctrl_host_init(dp->ctrl, flip, reset); 393 + if (dp->phy_initialized) { 394 + dp_ctrl_phy_exit(dp->ctrl); 395 + dp->phy_initialized = false; 396 + } 397 + } 398 + 399 + static void dp_display_host_init(struct dp_display_private *dp) 400 + { 401 + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", 402 + dp->dp_display.connector_type, dp->core_initialized, 403 + dp->phy_initialized); 404 + 405 + dp_power_init(dp->power, false); 406 + dp_ctrl_reset_irq_ctrl(dp->ctrl, true); 410 407 dp_aux_init(dp->aux); 411 408 dp->core_initialized = true; 412 409 } 413 410 414 411 static void dp_display_host_deinit(struct dp_display_private *dp) 415 412 { 416 - if (!dp->core_initialized) { 417 - DRM_DEBUG_DP("DP core not initialized\n"); 418 - return; 419 - } 413 + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", 414 + dp->dp_display.connector_type, dp->core_initialized, 415 + dp->phy_initialized); 420 416 421 - dp_ctrl_host_deinit(dp->ctrl); 417 + dp_ctrl_reset_irq_ctrl(dp->ctrl, false); 422 418 dp_aux_deinit(dp->aux); 423 419 dp_power_deinit(dp->power); 424 - 425 420 dp->core_initialized = false; 426 421 } 427 422 ··· 444 409 { 445 410 struct dp_display_private *dp = dev_get_dp_display_private(dev); 446 411 447 - dp_display_host_init(dp, false); 412 + dp_display_host_phy_init(dp); 448 413 449 414 return dp_display_process_hpd_high(dp); 450 415 } ··· 542 507 mutex_lock(&dp->event_mutex); 543 508 544 509 state = dp->hpd_state; 545 - DRM_DEBUG_DP("hpd_state=%d\n", state); 510 + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", 511 + dp->dp_display.connector_type, state); 512 + 546 513 if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { 547 514 mutex_unlock(&dp->event_mutex); 548 515 return 0; ··· 567 530 ret = dp_display_usbpd_configure_cb(&dp->pdev->dev); 568 531 if (ret) { /* link train failed */ 569 532 dp->hpd_state = ST_DISCONNECTED; 570 - 571 - if (ret == -ECONNRESET) { /* cable unplugged */ 572 - dp->core_initialized = false; 573 - } 574 - 575 533 } else { 576 534 /* start sentinel checking in case of missing uevent */ 577 535 dp_add_event(dp, EV_CONNECT_PENDING_TIMEOUT, 0, tout); ··· 576 544 dp_catalog_hpd_config_intr(dp->catalog, 577 545 DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); 578 546 547 + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", 548 + dp->dp_display.connector_type, state); 579 549 mutex_unlock(&dp->event_mutex); 580 550 581 551 /* uevent will complete connection part */ ··· 594 560 mutex_lock(&dp->event_mutex); 595 561 596 562 state = dp->hpd_state; 597 - if (state == ST_CONNECT_PENDING) 563 + if (state == ST_CONNECT_PENDING) { 598 564 dp->hpd_state = ST_CONNECTED; 565 + DRM_DEBUG_DP("type=%d\n", dp->dp_display.connector_type); 566 + } 599 567 600 568 mutex_unlock(&dp->event_mutex); 601 569 ··· 630 594 631 595 state = dp->hpd_state; 632 596 597 + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", 598 + dp->dp_display.connector_type, state); 599 + 633 600 /* disable irq_hpd/replug interrupts */ 634 601 dp_catalog_hpd_config_intr(dp->catalog, 635 602 DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false); ··· 643 604 if (state == ST_DISCONNECTED) { 644 605 /* triggered by irq_hdp with sink_count = 0 */ 645 606 if (dp->link->sink_count == 0) { 646 - dp_ctrl_off_phy(dp->ctrl); 647 - dp->core_initialized = false; 607 + dp_display_host_phy_exit(dp); 648 608 } 649 609 mutex_unlock(&dp->event_mutex); 650 610 return 0; ··· 675 637 /* start sentinel checking in case of missing uevent */ 676 638 dp_add_event(dp, EV_DISCONNECT_PENDING_TIMEOUT, 0, DP_TIMEOUT_5_SECOND); 677 639 678 - DRM_DEBUG_DP("hpd_state=%d\n", state); 679 640 /* signal the disconnect event early to ensure proper teardown */ 680 641 dp_display_handle_plugged_change(&dp->dp_display, false); 681 642 682 643 /* enable HDP plug interrupt to prepare for next plugin */ 683 644 dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); 645 + 646 + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", 647 + dp->dp_display.connector_type, state); 684 648 685 649 /* uevent will complete disconnection part */ 686 650 mutex_unlock(&dp->event_mutex); ··· 696 656 mutex_lock(&dp->event_mutex); 697 657 698 658 state = dp->hpd_state; 699 - if (state == ST_DISCONNECT_PENDING) 659 + if (state == ST_DISCONNECT_PENDING) { 700 660 dp->hpd_state = ST_DISCONNECTED; 661 + DRM_DEBUG_DP("type=%d\n", dp->dp_display.connector_type); 662 + } 701 663 702 664 mutex_unlock(&dp->event_mutex); 703 665 ··· 709 667 static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) 710 668 { 711 669 u32 state; 712 - int ret; 713 670 714 671 mutex_lock(&dp->event_mutex); 715 672 716 673 /* irq_hpd can happen at either connected or disconnected state */ 717 674 state = dp->hpd_state; 675 + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", 676 + dp->dp_display.connector_type, state); 677 + 718 678 if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { 719 679 mutex_unlock(&dp->event_mutex); 720 680 return 0; ··· 736 692 return 0; 737 693 } 738 694 739 - /* 740 - * dp core (ahb/aux clks) must be initialized before 741 - * irq_hpd be handled 742 - */ 743 - if (dp->core_initialized) { 744 - ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); 745 - if (ret == -ECONNRESET) { /* cable unplugged */ 746 - dp->core_initialized = false; 747 - } 748 - } 749 - DRM_DEBUG_DP("hpd_state=%d\n", state); 695 + dp_display_usbpd_attention_cb(&dp->pdev->dev); 696 + 697 + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", 698 + dp->dp_display.connector_type, state); 750 699 751 700 mutex_unlock(&dp->event_mutex); 752 701 ··· 929 892 930 893 dp_display->audio_enabled = false; 931 894 932 - /* triggered by irq_hpd with sink_count = 0 */ 933 895 if (dp->link->sink_count == 0) { 896 + /* 897 + * irq_hpd with sink_count = 0 898 + * hdmi unplugged out of dongle 899 + */ 934 900 dp_ctrl_off_link_stream(dp->ctrl); 935 901 } else { 902 + /* 903 + * unplugged interrupt 904 + * dongle unplugged out of DUT 905 + */ 936 906 dp_ctrl_off(dp->ctrl); 937 - dp->core_initialized = false; 907 + dp_display_host_phy_exit(dp); 938 908 } 939 909 940 910 dp_display->power_on = false; ··· 1071 1027 static void dp_display_config_hpd(struct dp_display_private *dp) 1072 1028 { 1073 1029 1074 - dp_display_host_init(dp, true); 1030 + dp_display_host_init(dp); 1075 1031 dp_catalog_ctrl_hpd_config(dp->catalog); 1076 1032 1077 1033 /* Enable interrupt first time ··· 1189 1145 1190 1146 hpd_isr_status = dp_catalog_hpd_get_intr_status(dp->catalog); 1191 1147 1192 - DRM_DEBUG_DP("hpd isr status=%#x\n", hpd_isr_status); 1193 1148 if (hpd_isr_status & 0x0F) { 1149 + DRM_DEBUG_DP("type=%d isr=0x%x\n", 1150 + dp->dp_display.connector_type, hpd_isr_status); 1194 1151 /* hpd related interrupts */ 1195 1152 if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK) 1196 1153 dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0); ··· 1344 1299 1345 1300 mutex_lock(&dp->event_mutex); 1346 1301 1347 - DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n", 1348 - dp->core_initialized, dp_display->power_on); 1302 + DRM_DEBUG_DP("Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", 1303 + dp->dp_display.connector_type, dp->core_initialized, 1304 + dp->phy_initialized, dp_display->power_on); 1349 1305 1350 1306 /* start from disconnected state */ 1351 1307 dp->hpd_state = ST_DISCONNECTED; 1352 1308 1353 1309 /* turn on dp ctrl/phy */ 1354 - dp_display_host_init(dp, true); 1310 + dp_display_host_init(dp); 1355 1311 1356 1312 dp_catalog_ctrl_hpd_config(dp->catalog); 1357 1313 1358 - /* 1359 - * set sink to normal operation mode -- D0 1360 - * before dpcd read 1361 - */ 1362 - dp_link_psm_config(dp->link, &dp->panel->link_info, false); 1363 1314 1364 1315 if (dp_catalog_link_is_connected(dp->catalog)) { 1316 + /* 1317 + * set sink to normal operation mode -- D0 1318 + * before dpcd read 1319 + */ 1320 + dp_display_host_phy_init(dp); 1321 + dp_link_psm_config(dp->link, &dp->panel->link_info, false); 1365 1322 sink_count = drm_dp_read_sink_count(dp->aux); 1366 1323 if (sink_count < 0) 1367 1324 sink_count = 0; 1325 + 1326 + dp_display_host_phy_exit(dp); 1368 1327 } 1369 1328 1370 1329 dp->link->sink_count = sink_count; ··· 1385 1336 dp_display_handle_plugged_change(dp_display, false); 1386 1337 } 1387 1338 1388 - DRM_DEBUG_DP("After, sink_count=%d is_connected=%d core_inited=%d power_on=%d\n", 1389 - dp->link->sink_count, dp->dp_display.is_connected, 1390 - dp->core_initialized, dp_display->power_on); 1339 + DRM_DEBUG_DP("After, type=%d sink_count=%d is_connected=%d \ 1340 + core_inited=%d phy_inited=%d power_on=%d\n", 1341 + dp->dp_display.connector_type, dp->link->sink_count, 1342 + dp->dp_display.is_connected, dp->core_initialized, 1343 + dp->phy_initialized, dp_display->power_on); 1391 1344 1392 1345 mutex_unlock(&dp->event_mutex); 1393 1346 ··· 1406 1355 1407 1356 mutex_lock(&dp->event_mutex); 1408 1357 1409 - DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n", 1410 - dp->core_initialized, dp_display->power_on); 1358 + DRM_DEBUG_DP("Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", 1359 + dp->dp_display.connector_type, dp->core_initialized, 1360 + dp->phy_initialized, dp_display->power_on); 1411 1361 1412 - if (dp->core_initialized == true) { 1413 - /* mainlink enabled */ 1414 - if (dp_power_clk_status(dp->power, DP_CTRL_PM)) 1415 - dp_ctrl_off_link_stream(dp->ctrl); 1362 + /* mainlink enabled */ 1363 + if (dp_power_clk_status(dp->power, DP_CTRL_PM)) 1364 + dp_ctrl_off_link_stream(dp->ctrl); 1416 1365 1417 - dp_display_host_deinit(dp); 1418 - } 1366 + dp_display_host_phy_exit(dp); 1367 + 1368 + /* host_init will be called at pm_resume */ 1369 + dp_display_host_deinit(dp); 1419 1370 1420 1371 dp->hpd_state = ST_SUSPENDED; 1421 1372 1422 - /* host_init will be called at pm_resume */ 1423 - dp->core_initialized = false; 1424 - 1425 - DRM_DEBUG_DP("After, core_inited=%d power_on=%d\n", 1426 - dp->core_initialized, dp_display->power_on); 1373 + DRM_DEBUG_DP("After, type=%d core_inited=%d phy_inited=%d power_on=%d\n", 1374 + dp->dp_display.connector_type, dp->core_initialized, 1375 + dp->phy_initialized, dp_display->power_on); 1427 1376 1428 1377 mutex_unlock(&dp->event_mutex); 1429 1378 ··· 1511 1460 struct drm_encoder *encoder) 1512 1461 { 1513 1462 struct msm_drm_private *priv; 1463 + struct dp_display_private *dp_priv; 1514 1464 int ret; 1515 1465 1516 1466 if (WARN_ON(!encoder) || WARN_ON(!dp_display) || WARN_ON(!dev)) ··· 1519 1467 1520 1468 priv = dev->dev_private; 1521 1469 dp_display->drm_dev = dev; 1470 + 1471 + dp_priv = container_of(dp_display, struct dp_display_private, dp_display); 1522 1472 1523 1473 ret = dp_display_request_irq(dp_display); 1524 1474 if (ret) { ··· 1538 1484 dp_display->connector = NULL; 1539 1485 return ret; 1540 1486 } 1487 + 1488 + dp_priv->panel->connector = dp_display->connector; 1541 1489 1542 1490 priv->connectors[priv->num_connectors++] = dp_display->connector; 1543 1491 ··· 1591 1535 state = dp_display->hpd_state; 1592 1536 1593 1537 if (state == ST_DISPLAY_OFF) 1594 - dp_display_host_init(dp_display, true); 1538 + dp_display_host_phy_init(dp_display); 1595 1539 1596 1540 dp_display_enable(dp_display, 0); 1597 1541
+1 -1
drivers/gpu/drm/msm/dp/dp_display.h
··· 16 16 struct drm_bridge *bridge; 17 17 struct drm_connector *connector; 18 18 struct drm_encoder *encoder; 19 - struct drm_bridge *panel_bridge; 19 + struct drm_bridge *next_bridge; 20 20 bool is_connected; 21 21 bool audio_enabled; 22 22 bool power_on;
+11 -10
drivers/gpu/drm/msm/dp/dp_drm.c
··· 169 169 170 170 drm_connector_attach_encoder(connector, dp_display->encoder); 171 171 172 - if (dp_display->panel_bridge) { 173 - ret = drm_bridge_attach(dp_display->encoder, 174 - dp_display->panel_bridge, NULL, 175 - DRM_BRIDGE_ATTACH_NO_CONNECTOR); 176 - if (ret < 0) { 177 - DRM_ERROR("failed to attach panel bridge: %d\n", ret); 178 - return ERR_PTR(ret); 179 - } 180 - } 181 - 182 172 return connector; 183 173 } 184 174 ··· 234 244 if (rc) { 235 245 DRM_ERROR("failed to attach bridge, rc=%d\n", rc); 236 246 return ERR_PTR(rc); 247 + } 248 + 249 + if (dp_display->next_bridge) { 250 + rc = drm_bridge_attach(dp_display->encoder, 251 + dp_display->next_bridge, bridge, 252 + DRM_BRIDGE_ATTACH_NO_CONNECTOR); 253 + if (rc < 0) { 254 + DRM_ERROR("failed to attach panel bridge: %d\n", rc); 255 + drm_bridge_remove(bridge); 256 + return ERR_PTR(rc); 257 + } 237 258 } 238 259 239 260 return bridge;
+5
drivers/gpu/drm/msm/dp/dp_panel.c
··· 212 212 if (drm_add_modes_noedid(connector, 640, 480)) 213 213 drm_set_preferred_mode(connector, 640, 480); 214 214 mutex_unlock(&connector->dev->mode_config.mutex); 215 + } else { 216 + /* always add fail-safe mode as backup mode */ 217 + mutex_lock(&connector->dev->mode_config.mutex); 218 + drm_add_modes_noedid(connector, 640, 480); 219 + mutex_unlock(&connector->dev->mode_config.mutex); 215 220 } 216 221 217 222 if (panel->aux_cfg_update_done) {
+22 -16
drivers/gpu/drm/msm/dp/dp_parser.c
··· 265 265 return 0; 266 266 } 267 267 268 - static int dp_parser_find_panel(struct dp_parser *parser) 268 + static int dp_parser_find_next_bridge(struct dp_parser *parser) 269 269 { 270 270 struct device *dev = &parser->pdev->dev; 271 - struct drm_panel *panel; 272 - int rc; 271 + struct drm_bridge *bridge; 273 272 274 - rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); 275 - if (rc) { 276 - DRM_ERROR("failed to acquire DRM panel: %d\n", rc); 277 - return rc; 278 - } 273 + bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); 274 + if (IS_ERR(bridge)) 275 + return PTR_ERR(bridge); 279 276 280 - parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel); 281 - if (IS_ERR(parser->panel_bridge)) { 282 - DRM_ERROR("failed to create panel bridge\n"); 283 - return PTR_ERR(parser->panel_bridge); 284 - } 277 + parser->next_bridge = bridge; 285 278 286 279 return 0; 287 280 } ··· 300 307 if (rc) 301 308 return rc; 302 309 303 - if (connector_type == DRM_MODE_CONNECTOR_eDP) { 304 - rc = dp_parser_find_panel(parser); 305 - if (rc) 310 + /* 311 + * External bridges are mandatory for eDP interfaces: one has to 312 + * provide at least an eDP panel (which gets wrapped into panel-bridge). 313 + * 314 + * For DisplayPort interfaces external bridges are optional, so 315 + * silently ignore an error if one is not present (-ENODEV). 316 + */ 317 + rc = dp_parser_find_next_bridge(parser); 318 + if (rc == -ENODEV) { 319 + if (connector_type == DRM_MODE_CONNECTOR_eDP) { 320 + DRM_ERROR("eDP: next bridge is not present\n"); 306 321 return rc; 322 + } 323 + } else if (rc) { 324 + if (rc != -EPROBE_DEFER) 325 + DRM_ERROR("DP: error parsing next bridge: %d\n", rc); 326 + return rc; 307 327 } 308 328 309 329 /* Map the corresponding regulator information according to
+2 -2
drivers/gpu/drm/msm/dp/dp_parser.h
··· 10 10 #include <linux/phy/phy.h> 11 11 #include <linux/phy/phy-dp.h> 12 12 13 - #include "dpu_io_util.h" 13 + #include "dp_clk_util.h" 14 14 #include "msm_drv.h" 15 15 16 16 #define DP_LABEL "MDSS DP DISPLAY" ··· 123 123 struct dp_display_data disp_data; 124 124 const struct dp_regulator_cfg *regulator_cfg; 125 125 u32 max_dp_lanes; 126 - struct drm_bridge *panel_bridge; 126 + struct drm_bridge *next_bridge; 127 127 128 128 int (*parse)(struct dp_parser *parser, int connector_type); 129 129 };
+3 -1
drivers/gpu/drm/msm/dsi/dsi.c
··· 4 4 */ 5 5 6 6 #include "dsi.h" 7 + #include "dsi_cfg.h" 7 8 8 9 struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi) 9 10 { ··· 176 175 } 177 176 178 177 static const struct of_device_id dt_match[] = { 179 - { .compatible = "qcom,mdss-dsi-ctrl" }, 178 + { .compatible = "qcom,mdss-dsi-ctrl", .data = NULL /* autodetect cfg */ }, 179 + { .compatible = "qcom,dsi-ctrl-6g-qcm2290", .data = &qcm2290_dsi_cfg_handler }, 180 180 {} 181 181 }; 182 182
+23
drivers/gpu/drm/msm/dsi/dsi_cfg.c
··· 213 213 .num_dsi = 1, 214 214 }; 215 215 216 + static const char * const dsi_qcm2290_bus_clk_names[] = { 217 + "iface", "bus", 218 + }; 219 + 220 + static const struct msm_dsi_config qcm2290_dsi_cfg = { 221 + .io_offset = DSI_6G_REG_SHIFT, 222 + .reg_cfg = { 223 + .num = 1, 224 + .regs = { 225 + {"vdda", 21800, 4 }, /* 1.2 V */ 226 + }, 227 + }, 228 + .bus_clk_names = dsi_qcm2290_bus_clk_names, 229 + .num_bus_clks = ARRAY_SIZE(dsi_qcm2290_bus_clk_names), 230 + .io_start = { 0x5e94000 }, 231 + .num_dsi = 1, 232 + }; 233 + 216 234 static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = { 217 235 .link_clk_set_rate = dsi_link_clk_set_rate_v2, 218 236 .link_clk_enable = dsi_link_clk_enable_v2, ··· 318 300 return cfg_hnd; 319 301 } 320 302 303 + /* Non autodetect configs */ 304 + const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler = { 305 + .cfg = &qcm2290_dsi_cfg, 306 + .ops = &msm_dsi_6g_v2_host_ops, 307 + };
+3
drivers/gpu/drm/msm/dsi/dsi_cfg.h
··· 60 60 61 61 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor); 62 62 63 + /* Non autodetect configs */ 64 + extern const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler; 65 + 63 66 #endif /* __MSM_DSI_CFG_H__ */ 64 67
+6 -2
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 212 212 int ret; 213 213 u32 major = 0, minor = 0; 214 214 215 + cfg_hnd = device_get_match_data(dev); 216 + if (cfg_hnd) 217 + return cfg_hnd; 218 + 215 219 ahb_clk = msm_clk_get(msm_host->pdev, "iface"); 216 220 if (IS_ERR(ahb_clk)) { 217 221 pr_err("%s: cannot get interface clock\n", __func__); ··· 1817 1813 goto fail; 1818 1814 } 1819 1815 1820 - msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", "DSI CTRL", &msm_host->ctrl_size); 1816 + msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size); 1821 1817 if (IS_ERR(msm_host->ctrl_base)) { 1822 1818 pr_err("%s: unable to map Dsi ctrl base\n", __func__); 1823 1819 ret = PTR_ERR(msm_host->ctrl_base); ··· 1881 1877 1882 1878 /* do not autoenable, will be enabled later */ 1883 1879 ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq, 1884 - IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, 1880 + IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, 1885 1881 "dsi_isr", msm_host); 1886 1882 if (ret < 0) { 1887 1883 dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+31 -34
drivers/gpu/drm/msm/dsi/dsi_manager.c
··· 305 305 return num; 306 306 } 307 307 308 - static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector, 309 - struct drm_display_mode *mode) 310 - { 311 - int id = dsi_mgr_connector_get_id(connector); 312 - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 313 - struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); 314 - struct msm_drm_private *priv = connector->dev->dev_private; 315 - struct msm_kms *kms = priv->kms; 316 - long actual, requested; 317 - 318 - DBG(""); 319 - requested = 1000 * mode->clock; 320 - actual = kms->funcs->round_pixclk(kms, requested, encoder); 321 - 322 - DBG("requested=%ld, actual=%ld", requested, actual); 323 - if (actual != requested) 324 - return MODE_CLOCK_RANGE; 325 - 326 - return MODE_OK; 327 - } 328 - 329 308 static struct drm_encoder * 330 309 dsi_mgr_connector_best_encoder(struct drm_connector *connector) 331 310 { ··· 315 336 return msm_dsi_get_encoder(msm_dsi); 316 337 } 317 338 318 - static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) 339 + static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) 319 340 { 320 341 int id = dsi_mgr_bridge_get_id(bridge); 321 342 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 322 343 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 323 344 struct mipi_dsi_host *host = msm_dsi->host; 324 - struct drm_panel *panel = msm_dsi->panel; 325 345 struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX]; 326 346 bool is_bonded_dsi = IS_BONDED_DSI(); 327 347 int ret; ··· 361 383 if (is_bonded_dsi && msm_dsi1) 362 384 msm_dsi_host_enable_irq(msm_dsi1->host); 363 385 386 + return; 387 + 388 + host1_on_fail: 389 + msm_dsi_host_power_off(host); 390 + host_on_fail: 391 + dsi_mgr_phy_disable(id); 392 + phy_en_fail: 393 + return; 394 + } 395 + 396 + static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) 397 + { 398 + int id = dsi_mgr_bridge_get_id(bridge); 399 + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 400 + struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 401 + struct mipi_dsi_host *host = msm_dsi->host; 402 + struct drm_panel *panel = msm_dsi->panel; 403 + bool is_bonded_dsi = IS_BONDED_DSI(); 404 + int ret; 405 + 406 + DBG("id=%d", id); 407 + if (!msm_dsi_device_connected(msm_dsi)) 408 + return; 409 + 410 + /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ 411 + if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) 412 + return; 413 + 364 414 /* Always call panel functions once, because even for dual panels, 365 415 * there is only one drm_panel instance. 366 416 */ ··· 423 417 if (panel) 424 418 drm_panel_unprepare(panel); 425 419 panel_prep_fail: 426 - msm_dsi_host_disable_irq(host); 427 - if (is_bonded_dsi && msm_dsi1) 428 - msm_dsi_host_disable_irq(msm_dsi1->host); 429 420 430 - if (is_bonded_dsi && msm_dsi1) 431 - msm_dsi_host_power_off(msm_dsi1->host); 432 - host1_on_fail: 433 - msm_dsi_host_power_off(host); 434 - host_on_fail: 435 - dsi_mgr_phy_disable(id); 436 - phy_en_fail: 437 421 return; 438 422 } 439 423 ··· 569 573 msm_dsi_host_set_display_mode(host, adjusted_mode); 570 574 if (is_bonded_dsi && other_dsi) 571 575 msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); 576 + 577 + dsi_mgr_bridge_power_on(bridge); 572 578 } 573 579 574 580 static const struct drm_connector_funcs dsi_mgr_connector_funcs = { ··· 584 586 585 587 static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = { 586 588 .get_modes = dsi_mgr_connector_get_modes, 587 - .mode_valid = dsi_mgr_connector_mode_valid, 588 589 .best_encoder = dsi_mgr_connector_best_encoder, 589 590 }; 590 591
+10 -4
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
··· 709 709 if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type)) 710 710 phy->cphy_mode = (phy_type == PHY_TYPE_CPHY); 711 711 712 - phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size); 712 + phy->base = msm_ioremap_size(pdev, "dsi_phy", &phy->base_size); 713 713 if (IS_ERR(phy->base)) { 714 714 DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); 715 715 ret = -ENOMEM; 716 716 goto fail; 717 717 } 718 718 719 - phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", "DSI_PLL", &phy->pll_size); 719 + phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", &phy->pll_size); 720 720 if (IS_ERR(phy->pll_base)) { 721 721 DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); 722 722 ret = -ENOMEM; ··· 724 724 } 725 725 726 726 if (phy->cfg->has_phy_lane) { 727 - phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", "DSI_PHY_LANE", &phy->lane_size); 727 + phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", &phy->lane_size); 728 728 if (IS_ERR(phy->lane_base)) { 729 729 DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy lane base\n", __func__); 730 730 ret = -ENOMEM; ··· 733 733 } 734 734 735 735 if (phy->cfg->has_phy_regulator) { 736 - phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", "DSI_PHY_REG", &phy->reg_size); 736 + phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", &phy->reg_size); 737 737 if (IS_ERR(phy->reg_base)) { 738 738 DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy regulator base\n", __func__); 739 739 ret = -ENOMEM; 740 740 goto fail; 741 741 } 742 + } 743 + 744 + if (phy->cfg->ops.parse_dt_properties) { 745 + ret = phy->cfg->ops.parse_dt_properties(phy); 746 + if (ret) 747 + goto fail; 742 748 } 743 749 744 750 ret = dsi_phy_regulator_init(phy);
+4
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
··· 25 25 void (*save_pll_state)(struct msm_dsi_phy *phy); 26 26 int (*restore_pll_state)(struct msm_dsi_phy *phy); 27 27 bool (*set_continuous_clock)(struct msm_dsi_phy *phy, bool enable); 28 + int (*parse_dt_properties)(struct msm_dsi_phy *phy); 28 29 }; 29 30 30 31 struct msm_dsi_phy_cfg { ··· 83 82 #define DSI_PIXEL_PLL_CLK 1 84 83 #define NUM_PROVIDED_CLKS 2 85 84 85 + #define DSI_LANE_MAX 5 86 + 86 87 struct msm_dsi_phy { 87 88 struct platform_device *pdev; 88 89 void __iomem *base; ··· 102 99 103 100 struct msm_dsi_dphy_timing timing; 104 101 const struct msm_dsi_phy_cfg *cfg; 102 + void *tuning_cfg; 105 103 106 104 enum msm_dsi_phy_usecase usecase; 107 105 bool regulator_ldo_mode;
+115 -7
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
··· 83 83 84 84 #define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, clk_hw) 85 85 86 + /** 87 + * struct dsi_phy_10nm_tuning_cfg - Holds 10nm PHY tuning config parameters. 88 + * @rescode_offset_top: Offset for pull-up legs rescode. 89 + * @rescode_offset_bot: Offset for pull-down legs rescode. 90 + * @vreg_ctrl: vreg ctrl to drive LDO level 91 + */ 92 + struct dsi_phy_10nm_tuning_cfg { 93 + u8 rescode_offset_top[DSI_LANE_MAX]; 94 + u8 rescode_offset_bot[DSI_LANE_MAX]; 95 + u8 vreg_ctrl; 96 + }; 97 + 86 98 /* 87 99 * Global list of private DSI PLL struct pointers. We need this for bonded DSI 88 100 * mode, where the master PLL's clk_ops needs access the slave's private data ··· 574 562 char clk_name[32], parent[32], vco_name[32]; 575 563 char parent2[32], parent3[32], parent4[32]; 576 564 struct clk_init_data vco_init = { 577 - .parent_names = (const char *[]){ "xo" }, 565 + .parent_data = &(const struct clk_parent_data) { 566 + .fw_name = "ref", 567 + }, 578 568 .num_parents = 1, 579 569 .name = vco_name, 580 570 .flags = CLK_IGNORE_UNUSED, ··· 761 747 int i; 762 748 u8 tx_dctrl[] = { 0x00, 0x00, 0x00, 0x04, 0x01 }; 763 749 void __iomem *lane_base = phy->lane_base; 750 + struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg; 764 751 765 752 if (phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS) 766 753 tx_dctrl[3] = 0x02; ··· 790 775 dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0); 791 776 dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i), 792 777 i == 4 ? 0x80 : 0x0); 793 - dsi_phy_write(lane_base + 794 - REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), 0x0); 795 - dsi_phy_write(lane_base + 796 - REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), 0x0); 778 + 779 + /* platform specific dsi phy drive strength adjustment */ 780 + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), 781 + tuning_cfg->rescode_offset_top[i]); 782 + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), 783 + tuning_cfg->rescode_offset_bot[i]); 784 + 797 785 dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i), 798 786 tx_dctrl[i]); 799 787 } ··· 817 799 u32 const timeout_us = 1000; 818 800 struct msm_dsi_dphy_timing *timing = &phy->timing; 819 801 void __iomem *base = phy->base; 802 + struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg; 820 803 u32 data; 821 804 822 805 DBG(""); ··· 853 834 /* Select MS1 byte-clk */ 854 835 dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10); 855 836 856 - /* Enable LDO */ 857 - dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, 0x59); 837 + /* Enable LDO with platform specific drive level/amplitude adjustment */ 838 + dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, 839 + tuning_cfg->vreg_ctrl); 858 840 859 841 /* Configure PHY lane swap (TODO: we need to calculate this) */ 860 842 dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21); ··· 942 922 DBG("DSI%d PHY disabled", phy->id); 943 923 } 944 924 925 + static int dsi_10nm_phy_parse_dt(struct msm_dsi_phy *phy) 926 + { 927 + struct device *dev = &phy->pdev->dev; 928 + struct dsi_phy_10nm_tuning_cfg *tuning_cfg; 929 + s8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */ 930 + s8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */ 931 + u32 ldo_level = 400; /* 400mV */ 932 + u8 level; 933 + int ret, i; 934 + 935 + tuning_cfg = devm_kzalloc(dev, sizeof(*tuning_cfg), GFP_KERNEL); 936 + if (!tuning_cfg) 937 + return -ENOMEM; 938 + 939 + /* Drive strength adjustment parameters */ 940 + ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-top", 941 + offset_top, DSI_LANE_MAX); 942 + if (ret && ret != -EINVAL) { 943 + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-top, %d\n", ret); 944 + return ret; 945 + } 946 + 947 + for (i = 0; i < DSI_LANE_MAX; i++) { 948 + if (offset_top[i] < -32 || offset_top[i] > 31) { 949 + DRM_DEV_ERROR(dev, 950 + "qcom,phy-rescode-offset-top value %d is not in range [-32..31]\n", 951 + offset_top[i]); 952 + return -EINVAL; 953 + } 954 + tuning_cfg->rescode_offset_top[i] = 0x3f & offset_top[i]; 955 + } 956 + 957 + ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-bot", 958 + offset_bot, DSI_LANE_MAX); 959 + if (ret && ret != -EINVAL) { 960 + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-bot, %d\n", ret); 961 + return ret; 962 + } 963 + 964 + for (i = 0; i < DSI_LANE_MAX; i++) { 965 + if (offset_bot[i] < -32 || offset_bot[i] > 31) { 966 + DRM_DEV_ERROR(dev, 967 + "qcom,phy-rescode-offset-bot value %d is not in range [-32..31]\n", 968 + offset_bot[i]); 969 + return -EINVAL; 970 + } 971 + tuning_cfg->rescode_offset_bot[i] = 0x3f & offset_bot[i]; 972 + } 973 + 974 + /* Drive level/amplitude adjustment parameters */ 975 + ret = of_property_read_u32(dev->of_node, "qcom,phy-drive-ldo-level", &ldo_level); 976 + if (ret && ret != -EINVAL) { 977 + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-drive-ldo-level, %d\n", ret); 978 + return ret; 979 + } 980 + 981 + switch (ldo_level) { 982 + case 375: 983 + level = 0; 984 + break; 985 + case 400: 986 + level = 1; 987 + break; 988 + case 425: 989 + level = 2; 990 + break; 991 + case 450: 992 + level = 3; 993 + break; 994 + case 475: 995 + level = 4; 996 + break; 997 + case 500: 998 + level = 5; 999 + break; 1000 + default: 1001 + DRM_DEV_ERROR(dev, "qcom,phy-drive-ldo-level %d is not supported\n", ldo_level); 1002 + return -EINVAL; 1003 + } 1004 + tuning_cfg->vreg_ctrl = 0x58 | (0x7 & level); 1005 + 1006 + phy->tuning_cfg = tuning_cfg; 1007 + 1008 + return 0; 1009 + } 1010 + 945 1011 const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { 946 1012 .has_phy_lane = true, 947 1013 .reg_cfg = { ··· 1042 936 .pll_init = dsi_pll_10nm_init, 1043 937 .save_pll_state = dsi_10nm_pll_save_state, 1044 938 .restore_pll_state = dsi_10nm_pll_restore_state, 939 + .parse_dt_properties = dsi_10nm_phy_parse_dt, 1045 940 }, 1046 941 .min_pll_rate = 1000000000UL, 1047 942 .max_pll_rate = 3500000000UL, ··· 1064 957 .pll_init = dsi_pll_10nm_init, 1065 958 .save_pll_state = dsi_10nm_pll_save_state, 1066 959 .restore_pll_state = dsi_10nm_pll_restore_state, 960 + .parse_dt_properties = dsi_10nm_phy_parse_dt, 1067 961 }, 1068 962 .min_pll_rate = 1000000000UL, 1069 963 .max_pll_rate = 3500000000UL,
+3 -1
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
··· 802 802 { 803 803 char clk_name[32], parent[32], vco_name[32]; 804 804 struct clk_init_data vco_init = { 805 - .parent_names = (const char *[]){ "xo" }, 805 + .parent_data = &(const struct clk_parent_data) { 806 + .fw_name = "ref", 807 + }, 806 808 .num_parents = 1, 807 809 .name = vco_name, 808 810 .flags = CLK_IGNORE_UNUSED,
+3 -1
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
··· 521 521 { 522 522 char clk_name[32], parent1[32], parent2[32], vco_name[32]; 523 523 struct clk_init_data vco_init = { 524 - .parent_names = (const char *[]){ "xo" }, 524 + .parent_data = &(const struct clk_parent_data) { 525 + .fw_name = "ref", .name = "xo", 526 + }, 525 527 .num_parents = 1, 526 528 .name = vco_name, 527 529 .flags = CLK_IGNORE_UNUSED,
+3 -1
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
··· 385 385 { 386 386 char *clk_name, *parent_name, *vco_name; 387 387 struct clk_init_data vco_init = { 388 - .parent_names = (const char *[]){ "pxo" }, 388 + .parent_data = &(const struct clk_parent_data) { 389 + .fw_name = "ref", 390 + }, 389 391 .num_parents = 1, 390 392 .flags = CLK_IGNORE_UNUSED, 391 393 .ops = &clk_ops_dsi_pll_28nm_vco,
+17 -9
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
··· 588 588 char clk_name[32], parent[32], vco_name[32]; 589 589 char parent2[32], parent3[32], parent4[32]; 590 590 struct clk_init_data vco_init = { 591 - .parent_names = (const char *[]){ "bi_tcxo" }, 591 + .parent_data = &(const struct clk_parent_data) { 592 + .fw_name = "ref", 593 + }, 592 594 .num_parents = 1, 593 595 .name = vco_name, 594 596 .flags = CLK_IGNORE_UNUSED, ··· 864 862 /* Alter PHY configurations if data rate less than 1.5GHZ*/ 865 863 less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000); 866 864 867 - /* For C-PHY, no low power settings for lower clk rate */ 868 - if (phy->cphy_mode) 869 - less_than_1500_mhz = false; 870 - 871 865 if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { 872 866 vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52; 873 - glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00; 874 - glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; 867 + if (phy->cphy_mode) { 868 + glbl_rescode_top_ctrl = 0x00; 869 + glbl_rescode_bot_ctrl = 0x3c; 870 + } else { 871 + glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00; 872 + glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; 873 + } 875 874 glbl_str_swi_cal_sel_ctrl = 0x00; 876 875 glbl_hstx_str_ctrl_0 = 0x88; 877 876 } else { 878 877 vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59; 879 - glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00; 880 - glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88; 878 + if (phy->cphy_mode) { 879 + glbl_str_swi_cal_sel_ctrl = 0x03; 880 + glbl_hstx_str_ctrl_0 = 0x66; 881 + } else { 882 + glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00; 883 + glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88; 884 + } 881 885 glbl_rescode_top_ctrl = 0x03; 882 886 glbl_rescode_bot_ctrl = 0x3c; 883 887 }
+3 -4
drivers/gpu/drm/msm/hdmi/hdmi.c
··· 133 133 hdmi->config = config; 134 134 spin_lock_init(&hdmi->reg_lock); 135 135 136 - hdmi->mmio = msm_ioremap(pdev, config->mmio_name, "HDMI"); 136 + hdmi->mmio = msm_ioremap(pdev, config->mmio_name); 137 137 if (IS_ERR(hdmi->mmio)) { 138 138 ret = PTR_ERR(hdmi->mmio); 139 139 goto fail; ··· 144 144 config->mmio_name); 145 145 hdmi->mmio_phy_addr = res->start; 146 146 147 - hdmi->qfprom_mmio = msm_ioremap(pdev, 148 - config->qfprom_mmio_name, "HDMI_QFPROM"); 147 + hdmi->qfprom_mmio = msm_ioremap(pdev, config->qfprom_mmio_name); 149 148 if (IS_ERR(hdmi->qfprom_mmio)) { 150 149 DRM_DEV_INFO(&pdev->dev, "can't find qfprom resource\n"); 151 150 hdmi->qfprom_mmio = NULL; ··· 305 306 } 306 307 307 308 ret = devm_request_irq(&pdev->dev, hdmi->irq, 308 - msm_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 309 + msm_hdmi_irq, IRQF_TRIGGER_HIGH, 309 310 "hdmi_isr", hdmi); 310 311 if (ret < 0) { 311 312 DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n",
+7 -4
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
··· 282 282 long actual, requested; 283 283 284 284 requested = 1000 * mode->clock; 285 - actual = kms->funcs->round_pixclk(kms, 286 - requested, hdmi_bridge->hdmi->encoder); 287 285 288 286 /* for mdp5/apq8074, we manage our own pixel clk (as opposed to 289 287 * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder 290 288 * instead): 291 289 */ 292 - if (config->pwr_clk_cnt > 0) 293 - actual = clk_round_rate(hdmi->pwr_clks[0], actual); 290 + if (kms->funcs->round_pixclk) 291 + actual = kms->funcs->round_pixclk(kms, 292 + requested, hdmi_bridge->hdmi->encoder); 293 + else if (config->pwr_clk_cnt > 0) 294 + actual = clk_round_rate(hdmi->pwr_clks[0], requested); 295 + else 296 + actual = requested; 294 297 295 298 DBG("requested=%ld, actual=%ld", requested, actual); 296 299
+1 -1
drivers/gpu/drm/msm/hdmi/hdmi_phy.c
··· 144 144 if (!phy->cfg) 145 145 return -ENODEV; 146 146 147 - phy->mmio = msm_ioremap(pdev, "hdmi_phy", "HDMI_PHY"); 147 + phy->mmio = msm_ioremap(pdev, "hdmi_phy"); 148 148 if (IS_ERR(phy->mmio)) { 149 149 DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); 150 150 return -ENOMEM;
+3 -4
drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c
··· 716 716 717 717 pll->pdev = pdev; 718 718 719 - pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); 719 + pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll"); 720 720 if (IS_ERR(pll->mmio_qserdes_com)) { 721 721 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 722 722 return -ENOMEM; 723 723 } 724 724 725 725 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 726 - char name[32], label[32]; 726 + char name[32]; 727 727 728 728 snprintf(name, sizeof(name), "hdmi_tx_l%d", i); 729 - snprintf(label, sizeof(label), "HDMI_TX_L%d", i); 730 729 731 - pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label); 730 + pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name); 732 731 if (IS_ERR(pll->mmio_qserdes_tx[i])) { 733 732 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 734 733 return -ENOMEM;
+1 -1
drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c
··· 434 434 if (!pll) 435 435 return -ENOMEM; 436 436 437 - pll->mmio = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); 437 + pll->mmio = msm_ioremap(pdev, "hdmi_pll"); 438 438 if (IS_ERR(pll->mmio)) { 439 439 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 440 440 return -ENOMEM;
-15
drivers/gpu/drm/msm/msm_atomic.c
··· 5 5 */ 6 6 7 7 #include <drm/drm_atomic_uapi.h> 8 - #include <drm/drm_gem_atomic_helper.h> 9 8 #include <drm/drm_vblank.h> 10 9 11 10 #include "msm_atomic_trace.h" 12 11 #include "msm_drv.h" 13 12 #include "msm_gem.h" 14 13 #include "msm_kms.h" 15 - 16 - int msm_atomic_prepare_fb(struct drm_plane *plane, 17 - struct drm_plane_state *new_state) 18 - { 19 - struct msm_drm_private *priv = plane->dev->dev_private; 20 - struct msm_kms *kms = priv->kms; 21 - 22 - if (!new_state->fb) 23 - return 0; 24 - 25 - drm_gem_plane_helper_prepare_fb(plane, new_state); 26 - 27 - return msm_framebuffer_prepare(new_state->fb, kms->aspace); 28 - } 29 14 30 15 /* 31 16 * Helpers to control vblanks while we flush.. basically just to ensure
+3 -3
drivers/gpu/drm/msm/msm_debugfs.c
··· 201 201 return 0; 202 202 } 203 203 204 - DEFINE_SIMPLE_ATTRIBUTE(shrink_fops, 205 - shrink_get, shrink_set, 206 - "0x%08llx\n"); 204 + DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops, 205 + shrink_get, shrink_set, 206 + "0x%08llx\n"); 207 207 208 208 209 209 static int msm_gem_show(struct seq_file *m, void *arg)
+5 -155
drivers/gpu/drm/msm/msm_drv.c
··· 57 57 .atomic_commit_tail = msm_atomic_commit_tail, 58 58 }; 59 59 60 - #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING 61 - static bool reglog; 62 - MODULE_PARM_DESC(reglog, "Enable register read/write logging"); 63 - module_param(reglog, bool, 0600); 64 - #else 65 - #define reglog 0 66 - #endif 67 - 68 60 #ifdef CONFIG_DRM_FBDEV_EMULATION 69 61 static bool fbdev = true; 70 62 MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer"); ··· 74 82 static bool modeset = true; 75 83 MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)"); 76 84 module_param(modeset, bool, 0600); 77 - 78 - /* 79 - * Util/helpers: 80 - */ 81 - 82 - struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, 83 - const char *name) 84 - { 85 - int i; 86 - char n[32]; 87 - 88 - snprintf(n, sizeof(n), "%s_clk", name); 89 - 90 - for (i = 0; bulk && i < count; i++) { 91 - if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n)) 92 - return bulk[i].clk; 93 - } 94 - 95 - 96 - return NULL; 97 - } 98 - 99 - struct clk *msm_clk_get(struct platform_device *pdev, const char *name) 100 - { 101 - struct clk *clk; 102 - char name2[32]; 103 - 104 - clk = devm_clk_get(&pdev->dev, name); 105 - if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 106 - return clk; 107 - 108 - snprintf(name2, sizeof(name2), "%s_clk", name); 109 - 110 - clk = devm_clk_get(&pdev->dev, name2); 111 - if (!IS_ERR(clk)) 112 - dev_warn(&pdev->dev, "Using legacy clk name binding. Use " 113 - "\"%s\" instead of \"%s\"\n", name, name2); 114 - 115 - return clk; 116 - } 117 - 118 - static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, 119 - const char *dbgname, bool quiet, phys_addr_t *psize) 120 - { 121 - struct resource *res; 122 - unsigned long size; 123 - void __iomem *ptr; 124 - 125 - if (name) 126 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 127 - else 128 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 129 - 130 - if (!res) { 131 - if (!quiet) 132 - DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); 133 - return ERR_PTR(-EINVAL); 134 - } 135 - 136 - size = resource_size(res); 137 - 138 - ptr = devm_ioremap(&pdev->dev, res->start, size); 139 - if (!ptr) { 140 - if (!quiet) 141 - DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); 142 - return ERR_PTR(-ENOMEM); 143 - } 144 - 145 - if (reglog) 146 - printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size); 147 - 148 - if (psize) 149 - *psize = size; 150 - 151 - return ptr; 152 - } 153 - 154 - void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 155 - const char *dbgname) 156 - { 157 - return _msm_ioremap(pdev, name, dbgname, false, NULL); 158 - } 159 - 160 - void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name, 161 - const char *dbgname) 162 - { 163 - return _msm_ioremap(pdev, name, dbgname, true, NULL); 164 - } 165 - 166 - void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, 167 - const char *dbgname, phys_addr_t *psize) 168 - { 169 - return _msm_ioremap(pdev, name, dbgname, false, psize); 170 - } 171 - 172 - void msm_writel(u32 data, void __iomem *addr) 173 - { 174 - if (reglog) 175 - printk(KERN_DEBUG "IO:W %p %08x\n", addr, data); 176 - writel(data, addr); 177 - } 178 - 179 - u32 msm_readl(const void __iomem *addr) 180 - { 181 - u32 val = readl(addr); 182 - if (reglog) 183 - pr_err("IO:R %p %08x\n", addr, val); 184 - return val; 185 - } 186 - 187 - void msm_rmw(void __iomem *addr, u32 mask, u32 or) 188 - { 189 - u32 val = msm_readl(addr); 190 - 191 - val &= ~mask; 192 - msm_writel(val | or, addr); 193 - } 194 - 195 - static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) 196 - { 197 - struct msm_hrtimer_work *work = container_of(t, 198 - struct msm_hrtimer_work, timer); 199 - 200 - kthread_queue_work(work->worker, &work->work); 201 - 202 - return HRTIMER_NORESTART; 203 - } 204 - 205 - void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, 206 - ktime_t wakeup_time, 207 - enum hrtimer_mode mode) 208 - { 209 - hrtimer_start(&work->timer, wakeup_time, mode); 210 - } 211 - 212 - void msm_hrtimer_work_init(struct msm_hrtimer_work *work, 213 - struct kthread_worker *worker, 214 - kthread_work_func_t fn, 215 - clockid_t clock_id, 216 - enum hrtimer_mode mode) 217 - { 218 - hrtimer_init(&work->timer, clock_id, mode); 219 - work->timer.function = msm_hrtimer_worktimer; 220 - work->worker = worker; 221 - kthread_init_work(&work->work, fn); 222 - } 223 85 224 86 static irqreturn_t msm_irq(int irq, void *arg) 225 87 { ··· 612 766 if (!gpu) 613 767 return -ENXIO; 614 768 615 - return gpu->funcs->get_param(gpu, args->param, &args->value); 769 + return gpu->funcs->get_param(gpu, file->driver_priv, 770 + args->param, &args->value); 616 771 } 617 772 618 773 static int msm_ioctl_gem_new(struct drm_device *dev, void *data, ··· 1285 1438 static const struct of_device_id dt_match[] = { 1286 1439 { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 }, 1287 1440 { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, 1441 + { .compatible = "qcom,msm8998-mdss", .data = (void *)KMS_DPU }, 1442 + { .compatible = "qcom,qcm2290-mdss", .data = (void *)KMS_DPU }, 1288 1443 { .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU }, 1289 1444 { .compatible = "qcom,sc7180-mdss", .data = (void *)KMS_DPU }, 1290 1445 { .compatible = "qcom,sc7280-mdss", .data = (void *)KMS_DPU }, 1446 + { .compatible = "qcom,sc8180x-mdss", .data = (void *)KMS_DPU }, 1291 1447 { .compatible = "qcom,sm8150-mdss", .data = (void *)KMS_DPU }, 1292 1448 { .compatible = "qcom,sm8250-mdss", .data = (void *)KMS_DPU }, 1293 1449 {}
+16 -30
drivers/gpu/drm/msm/msm_drv.h
··· 109 109 u32 num_dspp; 110 110 }; 111 111 112 - /** 113 - * struct msm_display_info - defines display properties 114 - * @intf_type: DRM_MODE_ENCODER_ type 115 - * @capabilities: Bitmask of display flags 116 - * @num_of_h_tiles: Number of horizontal tiles in case of split interface 117 - * @h_tile_instance: Controller instance used per tile. Number of elements is 118 - * based on num_of_h_tiles 119 - * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is 120 - * used instead of panel TE in cmd mode panels 121 - */ 122 - struct msm_display_info { 123 - int intf_type; 124 - uint32_t capabilities; 125 - uint32_t num_of_h_tiles; 126 - uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; 127 - bool is_te_using_watchdog_timer; 128 - }; 129 - 130 112 /* Commit/Event thread specific structure */ 131 113 struct msm_drm_thread { 132 114 struct drm_device *dev; ··· 239 257 240 258 struct msm_pending_timer; 241 259 242 - int msm_atomic_prepare_fb(struct drm_plane *plane, 243 - struct drm_plane_state *new_state); 244 260 int msm_atomic_init_pending_timer(struct msm_pending_timer *timer, 245 261 struct msm_kms *kms, int crtc_idx); 246 262 void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer); ··· 297 317 void msm_gem_prime_unpin(struct drm_gem_object *obj); 298 318 299 319 int msm_framebuffer_prepare(struct drm_framebuffer *fb, 300 - struct msm_gem_address_space *aspace); 320 + struct msm_gem_address_space *aspace, bool needs_dirtyfb); 301 321 void msm_framebuffer_cleanup(struct drm_framebuffer *fb, 302 - struct msm_gem_address_space *aspace); 322 + struct msm_gem_address_space *aspace, bool needed_dirtyfb); 303 323 uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, 304 324 struct msm_gem_address_space *aspace, int plane); 305 325 struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); ··· 460 480 461 481 struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, 462 482 const char *name); 463 - void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 464 - const char *dbgname); 483 + void __iomem *msm_ioremap(struct platform_device *pdev, const char *name); 465 484 void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, 466 - const char *dbgname, phys_addr_t *size); 467 - void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name, 468 - const char *dbgname); 469 - void msm_writel(u32 data, void __iomem *addr); 470 - u32 msm_readl(const void __iomem *addr); 471 - void msm_rmw(void __iomem *addr, u32 mask, u32 or); 485 + phys_addr_t *size); 486 + void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name); 487 + 488 + #define msm_writel(data, addr) writel((data), (addr)) 489 + #define msm_readl(addr) readl((addr)) 490 + 491 + static inline void msm_rmw(void __iomem *addr, u32 mask, u32 or) 492 + { 493 + u32 val = msm_readl(addr); 494 + 495 + val &= ~mask; 496 + msm_writel(val | or, addr); 497 + } 472 498 473 499 /** 474 500 * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work
+34 -7
drivers/gpu/drm/msm/msm_fb.c
··· 18 18 struct msm_framebuffer { 19 19 struct drm_framebuffer base; 20 20 const struct msm_format *format; 21 + 22 + /* Count of # of attached planes which need dirtyfb: */ 23 + refcount_t dirtyfb; 21 24 }; 22 25 #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) 23 26 24 27 static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, 25 28 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos); 26 29 30 + static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb, 31 + struct drm_file *file_priv, unsigned int flags, 32 + unsigned int color, struct drm_clip_rect *clips, 33 + unsigned int num_clips) 34 + { 35 + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); 36 + 37 + /* If this fb is not used on any display requiring pixel data to be 38 + * flushed, then skip dirtyfb 39 + */ 40 + if (refcount_read(&msm_fb->dirtyfb) == 0) 41 + return 0; 42 + 43 + return drm_atomic_helper_dirtyfb(fb, file_priv, flags, color, 44 + clips, num_clips); 45 + } 46 + 27 47 static const struct drm_framebuffer_funcs msm_framebuffer_funcs = { 28 48 .create_handle = drm_gem_fb_create_handle, 29 49 .destroy = drm_gem_fb_destroy, 30 - .dirty = drm_atomic_helper_dirtyfb, 50 + .dirty = msm_framebuffer_dirtyfb, 31 51 }; 32 52 33 53 #ifdef CONFIG_DEBUG_FS ··· 68 48 } 69 49 #endif 70 50 71 - /* prepare/pin all the fb's bo's for scanout. Note that it is not valid 72 - * to prepare an fb more multiple different initiator 'id's. But that 73 - * should be fine, since only the scanout (mdpN) side of things needs 74 - * this, the gpu doesn't care about fb's. 51 + /* prepare/pin all the fb's bo's for scanout. 75 52 */ 76 53 int msm_framebuffer_prepare(struct drm_framebuffer *fb, 77 - struct msm_gem_address_space *aspace) 54 + struct msm_gem_address_space *aspace, 55 + bool needs_dirtyfb) 78 56 { 57 + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); 79 58 int ret, i, n = fb->format->num_planes; 80 59 uint64_t iova; 60 + 61 + if (needs_dirtyfb) 62 + refcount_inc(&msm_fb->dirtyfb); 81 63 82 64 for (i = 0; i < n; i++) { 83 65 ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &iova); ··· 92 70 } 93 71 94 72 void msm_framebuffer_cleanup(struct drm_framebuffer *fb, 95 - struct msm_gem_address_space *aspace) 73 + struct msm_gem_address_space *aspace, 74 + bool needed_dirtyfb) 96 75 { 76 + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); 97 77 int i, n = fb->format->num_planes; 78 + 79 + if (needed_dirtyfb) 80 + refcount_dec(&msm_fb->dirtyfb); 98 81 99 82 for (i = 0; i < n; i++) 100 83 msm_gem_unpin_iova(fb->obj[i], aspace);
+3
drivers/gpu/drm/msm/msm_gem.h
··· 35 35 * will be non-NULL: 36 36 */ 37 37 struct pid *pid; 38 + 39 + /* @faults: the number of GPU hangs associated with this address space */ 40 + int faults; 38 41 }; 39 42 40 43 struct msm_gem_vma {
+10 -4
drivers/gpu/drm/msm/msm_gpu.c
··· 370 370 struct task_struct *task; 371 371 372 372 /* Increment the fault counts */ 373 - gpu->global_faults++; 374 373 submit->queue->faults++; 374 + submit->aspace->faults++; 375 375 376 376 task = get_pid_task(submit->pid, PIDTYPE_PID); 377 377 if (task) { ··· 389 389 } else { 390 390 msm_rd_dump_submit(priv->hangrd, submit, NULL); 391 391 } 392 + } else { 393 + /* 394 + * We couldn't attribute this fault to any particular context, 395 + * so increment the global fault count instead. 396 + */ 397 + gpu->global_faults++; 392 398 } 393 399 394 400 /* Record the crash state */ ··· 844 838 gpu->funcs = funcs; 845 839 gpu->name = name; 846 840 847 - gpu->worker = kthread_create_worker(0, "%s-worker", gpu->name); 841 + gpu->worker = kthread_create_worker(0, "gpu-worker"); 848 842 if (IS_ERR(gpu->worker)) { 849 843 ret = PTR_ERR(gpu->worker); 850 844 gpu->worker = NULL; ··· 867 861 868 862 869 863 /* Map registers: */ 870 - gpu->mmio = msm_ioremap(pdev, config->ioname, name); 864 + gpu->mmio = msm_ioremap(pdev, config->ioname); 871 865 if (IS_ERR(gpu->mmio)) { 872 866 ret = PTR_ERR(gpu->mmio); 873 867 goto fail; ··· 882 876 } 883 877 884 878 ret = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 885 - IRQF_TRIGGER_HIGH, gpu->name, gpu); 879 + IRQF_TRIGGER_HIGH, "gpu-irq", gpu); 886 880 if (ret) { 887 881 DRM_DEV_ERROR(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret); 888 882 goto fail;
+6 -2
drivers/gpu/drm/msm/msm_gpu.h
··· 42 42 * + z180_gpu 43 43 */ 44 44 struct msm_gpu_funcs { 45 - int (*get_param)(struct msm_gpu *gpu, uint32_t param, uint64_t *value); 45 + int (*get_param)(struct msm_gpu *gpu, struct msm_file_private *ctx, 46 + uint32_t param, uint64_t *value); 46 47 int (*hw_init)(struct msm_gpu *gpu); 47 48 int (*pm_suspend)(struct msm_gpu *gpu); 48 49 int (*pm_resume)(struct msm_gpu *gpu); ··· 200 199 /* does gpu need hw_init? */ 201 200 bool needs_hw_init; 202 201 203 - /* number of GPU hangs (for all contexts) */ 202 + /** 203 + * global_faults: number of GPU hangs not attributed to a particular 204 + * address space 205 + */ 204 206 int global_faults; 205 207 206 208 void __iomem *mmio;
+126
drivers/gpu/drm/msm/msm_io_utils.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved. 4 + * Copyright (C) 2013 Red Hat 5 + * Author: Rob Clark <robdclark@gmail.com> 6 + */ 7 + 8 + #include "msm_drv.h" 9 + 10 + /* 11 + * Util/helpers: 12 + */ 13 + 14 + struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, 15 + const char *name) 16 + { 17 + int i; 18 + char n[32]; 19 + 20 + snprintf(n, sizeof(n), "%s_clk", name); 21 + 22 + for (i = 0; bulk && i < count; i++) { 23 + if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n)) 24 + return bulk[i].clk; 25 + } 26 + 27 + 28 + return NULL; 29 + } 30 + 31 + struct clk *msm_clk_get(struct platform_device *pdev, const char *name) 32 + { 33 + struct clk *clk; 34 + char name2[32]; 35 + 36 + clk = devm_clk_get(&pdev->dev, name); 37 + if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 38 + return clk; 39 + 40 + snprintf(name2, sizeof(name2), "%s_clk", name); 41 + 42 + clk = devm_clk_get(&pdev->dev, name2); 43 + if (!IS_ERR(clk)) 44 + dev_warn(&pdev->dev, "Using legacy clk name binding. Use " 45 + "\"%s\" instead of \"%s\"\n", name, name2); 46 + 47 + return clk; 48 + } 49 + 50 + static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, 51 + bool quiet, phys_addr_t *psize) 52 + { 53 + struct resource *res; 54 + unsigned long size; 55 + void __iomem *ptr; 56 + 57 + if (name) 58 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 59 + else 60 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 61 + 62 + if (!res) { 63 + if (!quiet) 64 + DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); 65 + return ERR_PTR(-EINVAL); 66 + } 67 + 68 + size = resource_size(res); 69 + 70 + ptr = devm_ioremap(&pdev->dev, res->start, size); 71 + if (!ptr) { 72 + if (!quiet) 73 + DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); 74 + return ERR_PTR(-ENOMEM); 75 + } 76 + 77 + if (psize) 78 + *psize = size; 79 + 80 + return ptr; 81 + } 82 + 83 + void __iomem *msm_ioremap(struct platform_device *pdev, const char *name) 84 + { 85 + return _msm_ioremap(pdev, name, false, NULL); 86 + } 87 + 88 + void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name) 89 + { 90 + return _msm_ioremap(pdev, name, true, NULL); 91 + } 92 + 93 + void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, 94 + phys_addr_t *psize) 95 + { 96 + return _msm_ioremap(pdev, name, false, psize); 97 + } 98 + 99 + static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) 100 + { 101 + struct msm_hrtimer_work *work = container_of(t, 102 + struct msm_hrtimer_work, timer); 103 + 104 + kthread_queue_work(work->worker, &work->work); 105 + 106 + return HRTIMER_NORESTART; 107 + } 108 + 109 + void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, 110 + ktime_t wakeup_time, 111 + enum hrtimer_mode mode) 112 + { 113 + hrtimer_start(&work->timer, wakeup_time, mode); 114 + } 115 + 116 + void msm_hrtimer_work_init(struct msm_hrtimer_work *work, 117 + struct kthread_worker *worker, 118 + kthread_work_func_t fn, 119 + clockid_t clock_id, 120 + enum hrtimer_mode mode) 121 + { 122 + hrtimer_init(&work->timer, clock_id, mode); 123 + work->timer.function = msm_hrtimer_worktimer; 124 + work->worker = worker; 125 + kthread_init_work(&work->work, fn); 126 + }
+7 -1
drivers/gpu/drm/msm/msm_rd.c
··· 62 62 RD_FRAG_SHADER, 63 63 RD_BUFFER_CONTENTS, 64 64 RD_GPU_ID, 65 + RD_CHIP_ID, 65 66 }; 66 67 67 68 #define BUF_SZ 512 /* should be power of 2 */ ··· 197 196 198 197 /* the parsing tools need to know gpu-id to know which 199 198 * register database to load. 199 + * 200 + * Note: These particular params do not require a context 200 201 */ 201 - gpu->funcs->get_param(gpu, MSM_PARAM_GPU_ID, &val); 202 + gpu->funcs->get_param(gpu, NULL, MSM_PARAM_GPU_ID, &val); 202 203 gpu_id = val; 203 204 204 205 rd_write_section(rd, RD_GPU_ID, &gpu_id, sizeof(gpu_id)); 206 + 207 + gpu->funcs->get_param(gpu, NULL, MSM_PARAM_CHIP_ID, &val); 208 + rd_write_section(rd, RD_CHIP_ID, &val, sizeof(val)); 205 209 206 210 out: 207 211 mutex_unlock(&gpu->lock);