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

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

Next for v5.20

GPU:
- a619 support
- Fix for unclocked GMU register access
- Devcore dump enhancements

Core:

- client utilization via fdinfo support
- fix fence rollover issue
- gem: Lockdep false-positive warning fix
- gem: Switch to pfn mappings

DPU:

- constification of HW catalog
- support for using encoder as CRC source
- WB support on sc7180
- WB resolution fixes

DP:

- dropped custom bulk clock implementation
- made dp_bridge_mode_valid() return MODE_CLOCK_HIGH where applicable
- fix link retraining on resolution change

MDP5:

- MSM8953 perf data

HDMI:

- YAML'ification of schema
- dropped obsolete GPIO support
- misc cleanups

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGtuqswBGPw-kCYzJvckK2RR1XTeUEgaXwVG_mvpbv3gPA@mail.gmail.com

+1758 -1460
+7 -1
Documentation/devicetree/bindings/display/msm/dp-controller.yaml
··· 7 7 title: MSM Display Port Controller 8 8 9 9 maintainers: 10 - - Kuogee Hsieh <khsieh@codeaurora.org> 10 + - Kuogee Hsieh <quic_khsieh@quicinc.com> 11 11 12 12 description: | 13 13 Device tree bindings for DisplayPort host controller for MSM targets ··· 76 76 "#sound-dai-cells": 77 77 const: 0 78 78 79 + vdda-0p9-supply: true 80 + vdda-1p2-supply: true 81 + 79 82 ports: 80 83 $ref: /schemas/graph.yaml#/properties/ports 81 84 properties: ··· 139 136 #sound-dai-cells = <0>; 140 137 141 138 power-domains = <&rpmhpd SC7180_CX>; 139 + 140 + vdda-0p9-supply = <&vdda_usb_ss_dp_core>; 141 + vdda-1p2-supply = <&vdda_usb_ss_dp_1p2>; 142 142 143 143 ports { 144 144 #address-cells = <1>;
-99
Documentation/devicetree/bindings/display/msm/hdmi.txt
··· 1 - Qualcomm adreno/snapdragon hdmi output 2 - 3 - Required properties: 4 - - compatible: one of the following 5 - * "qcom,hdmi-tx-8996" 6 - * "qcom,hdmi-tx-8994" 7 - * "qcom,hdmi-tx-8084" 8 - * "qcom,hdmi-tx-8974" 9 - * "qcom,hdmi-tx-8660" 10 - * "qcom,hdmi-tx-8960" 11 - - reg: Physical base address and length of the controller's registers 12 - - reg-names: "core_physical" 13 - - interrupts: The interrupt signal from the hdmi block. 14 - - power-domains: Should be <&mmcc MDSS_GDSC>. 15 - - clocks: device clocks 16 - See ../clocks/clock-bindings.txt for details. 17 - - core-vdda-supply: phandle to supply regulator 18 - - hdmi-mux-supply: phandle to mux regulator 19 - - phys: the phandle for the HDMI PHY device 20 - - phy-names: the name of the corresponding PHY device 21 - 22 - Optional properties: 23 - - hpd-gpios: hpd pin 24 - - qcom,hdmi-tx-mux-en-gpios: hdmi mux enable pin 25 - - qcom,hdmi-tx-mux-sel-gpios: hdmi mux select pin 26 - - qcom,hdmi-tx-mux-lpm-gpios: hdmi mux lpm pin 27 - - power-domains: reference to the power domain(s), if available. 28 - - pinctrl-names: the pin control state names; should contain "default" 29 - - pinctrl-0: the default pinctrl state (active) 30 - - pinctrl-1: the "sleep" pinctrl state 31 - 32 - HDMI PHY: 33 - Required properties: 34 - - compatible: Could be the following 35 - * "qcom,hdmi-phy-8660" 36 - * "qcom,hdmi-phy-8960" 37 - * "qcom,hdmi-phy-8974" 38 - * "qcom,hdmi-phy-8084" 39 - * "qcom,hdmi-phy-8996" 40 - - #phy-cells: Number of cells in a PHY specifier; Should be 0. 41 - - reg: Physical base address and length of the registers of the PHY sub blocks. 42 - - reg-names: The names of register regions. The following regions are required: 43 - * "hdmi_phy" 44 - * "hdmi_pll" 45 - For HDMI PHY on msm8996, these additional register regions are required: 46 - * "hdmi_tx_l0" 47 - * "hdmi_tx_l1" 48 - * "hdmi_tx_l3" 49 - * "hdmi_tx_l4" 50 - - power-domains: Should be <&mmcc MDSS_GDSC>. 51 - - clocks: device clocks 52 - See Documentation/devicetree/bindings/clock/clock-bindings.txt for details. 53 - - core-vdda-supply: phandle to vdda regulator device node 54 - 55 - Example: 56 - 57 - / { 58 - ... 59 - 60 - hdmi: hdmi@4a00000 { 61 - compatible = "qcom,hdmi-tx-8960"; 62 - reg-names = "core_physical"; 63 - reg = <0x04a00000 0x2f0>; 64 - interrupts = <GIC_SPI 79 0>; 65 - power-domains = <&mmcc MDSS_GDSC>; 66 - clock-names = 67 - "core", 68 - "master_iface", 69 - "slave_iface"; 70 - clocks = 71 - <&mmcc HDMI_APP_CLK>, 72 - <&mmcc HDMI_M_AHB_CLK>, 73 - <&mmcc HDMI_S_AHB_CLK>; 74 - qcom,hdmi-tx-ddc-clk = <&msmgpio 70 GPIO_ACTIVE_HIGH>; 75 - qcom,hdmi-tx-ddc-data = <&msmgpio 71 GPIO_ACTIVE_HIGH>; 76 - qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>; 77 - core-vdda-supply = <&pm8921_hdmi_mvs>; 78 - hdmi-mux-supply = <&ext_3p3v>; 79 - pinctrl-names = "default", "sleep"; 80 - pinctrl-0 = <&hpd_active &ddc_active &cec_active>; 81 - pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>; 82 - 83 - phys = <&hdmi_phy>; 84 - phy-names = "hdmi_phy"; 85 - }; 86 - 87 - hdmi_phy: phy@4a00400 { 88 - compatible = "qcom,hdmi-phy-8960"; 89 - reg-names = "hdmi_phy", 90 - "hdmi_pll"; 91 - reg = <0x4a00400 0x60>, 92 - <0x4a00500 0x100>; 93 - #phy-cells = <0>; 94 - power-domains = <&mmcc MDSS_GDSC>; 95 - clock-names = "slave_iface"; 96 - clocks = <&mmcc HDMI_S_AHB_CLK>; 97 - core-vdda-supply = <&pm8921_hdmi_mvs>; 98 - }; 99 - };
+232
Documentation/devicetree/bindings/display/msm/hdmi.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/display/msm/hdmi.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Qualcomm Adreno/Snapdragon HDMI output 9 + 10 + maintainers: 11 + - Rob Clark <robdclark@gmail.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - qcom,hdmi-tx-8084 17 + - qcom,hdmi-tx-8660 18 + - qcom,hdmi-tx-8960 19 + - qcom,hdmi-tx-8974 20 + - qcom,hdmi-tx-8994 21 + - qcom,hdmi-tx-8996 22 + 23 + clocks: 24 + minItems: 1 25 + maxItems: 5 26 + 27 + clock-names: 28 + minItems: 1 29 + maxItems: 5 30 + 31 + reg: 32 + minItems: 1 33 + maxItems: 3 34 + 35 + reg-names: 36 + minItems: 1 37 + items: 38 + - const: core_physical 39 + - const: qfprom_physical 40 + - const: hdcp_physical 41 + 42 + interrupts: 43 + maxItems: 1 44 + 45 + phys: 46 + maxItems: 1 47 + 48 + phy-names: 49 + enum: 50 + - hdmi_phy 51 + - hdmi-phy 52 + deprecated: true 53 + 54 + core-vdda-supply: 55 + description: phandle to VDDA supply regulator 56 + 57 + hdmi-mux-supply: 58 + description: phandle to mux regulator 59 + deprecated: true 60 + 61 + core-vcc-supply: 62 + description: phandle to VCC supply regulator 63 + 64 + hpd-gpios: 65 + maxItems: 1 66 + description: hpd pin 67 + 68 + qcom,hdmi-tx-mux-en-gpios: 69 + maxItems: 1 70 + deprecated: true 71 + description: HDMI mux enable pin 72 + 73 + qcom,hdmi-tx-mux-sel-gpios: 74 + maxItems: 1 75 + deprecated: true 76 + description: HDMI mux select pin 77 + 78 + qcom,hdmi-tx-mux-lpm-gpios: 79 + maxItems: 1 80 + deprecated: true 81 + description: HDMI mux lpm pin 82 + 83 + '#sound-dai-cells': 84 + const: 1 85 + 86 + ports: 87 + type: object 88 + $ref: /schemas/graph.yaml#/properties/ports 89 + properties: 90 + port@0: 91 + $ref: /schemas/graph.yaml#/$defs/port-base 92 + description: | 93 + Input endpoints of the controller. 94 + 95 + port@1: 96 + $ref: /schemas/graph.yaml#/$defs/port-base 97 + description: | 98 + Output endpoints of the controller. 99 + 100 + required: 101 + - port@0 102 + 103 + required: 104 + - compatible 105 + - clocks 106 + - clock-names 107 + - reg 108 + - reg-names 109 + - interrupts 110 + - phys 111 + 112 + allOf: 113 + - if: 114 + properties: 115 + compatible: 116 + contains: 117 + enum: 118 + - qcom,hdmi-tx-8960 119 + - qcom,hdmi-tx-8660 120 + then: 121 + properties: 122 + clocks: 123 + minItems: 3 124 + maxItems: 3 125 + clock-names: 126 + items: 127 + - const: core 128 + - const: master_iface 129 + - const: slave_iface 130 + core-vcc-supplies: false 131 + 132 + - if: 133 + properties: 134 + compatible: 135 + contains: 136 + enum: 137 + - qcom,hdmi-tx-8974 138 + - qcom,hdmi-tx-8084 139 + - qcom,hdmi-tx-8994 140 + - qcom,hdmi-tx-8996 141 + then: 142 + properties: 143 + clocks: 144 + minItems: 5 145 + clock-names: 146 + items: 147 + - const: mdp_core 148 + - const: iface 149 + - const: core 150 + - const: alt_iface 151 + - const: extp 152 + hdmi-mux-supplies: false 153 + 154 + additionalProperties: false 155 + 156 + examples: 157 + - | 158 + #include <dt-bindings/gpio/gpio.h> 159 + #include <dt-bindings/interrupt-controller/irq.h> 160 + #include <dt-bindings/interrupt-controller/arm-gic.h> 161 + hdmi: hdmi@4a00000 { 162 + compatible = "qcom,hdmi-tx-8960"; 163 + reg-names = "core_physical"; 164 + reg = <0x04a00000 0x2f0>; 165 + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; 166 + clock-names = "core", 167 + "master_iface", 168 + "slave_iface"; 169 + clocks = <&clk 61>, 170 + <&clk 72>, 171 + <&clk 98>; 172 + hpd-gpios = <&msmgpio 72 GPIO_ACTIVE_HIGH>; 173 + core-vdda-supply = <&pm8921_hdmi_mvs>; 174 + hdmi-mux-supply = <&ext_3p3v>; 175 + pinctrl-names = "default", "sleep"; 176 + pinctrl-0 = <&hpd_active &ddc_active &cec_active>; 177 + pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>; 178 + 179 + phys = <&hdmi_phy>; 180 + }; 181 + - | 182 + #include <dt-bindings/clock/qcom,gcc-msm8996.h> 183 + #include <dt-bindings/clock/qcom,mmcc-msm8996.h> 184 + #include <dt-bindings/gpio/gpio.h> 185 + #include <dt-bindings/interrupt-controller/irq.h> 186 + #include <dt-bindings/interrupt-controller/arm-gic.h> 187 + hdmi@9a0000 { 188 + compatible = "qcom,hdmi-tx-8996"; 189 + reg = <0x009a0000 0x50c>, 190 + <0x00070000 0x6158>, 191 + <0x009e0000 0xfff>; 192 + reg-names = "core_physical", 193 + "qfprom_physical", 194 + "hdcp_physical"; 195 + 196 + interrupt-parent = <&mdss>; 197 + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; 198 + 199 + clocks = <&mmcc MDSS_MDP_CLK>, 200 + <&mmcc MDSS_AHB_CLK>, 201 + <&mmcc MDSS_HDMI_CLK>, 202 + <&mmcc MDSS_HDMI_AHB_CLK>, 203 + <&mmcc MDSS_EXTPCLK_CLK>; 204 + clock-names = "mdp_core", 205 + "iface", 206 + "core", 207 + "alt_iface", 208 + "extp"; 209 + 210 + phys = <&hdmi_phy>; 211 + #sound-dai-cells = <1>; 212 + 213 + pinctrl-names = "default", "sleep"; 214 + pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>; 215 + pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>; 216 + 217 + core-vdda-supply = <&vreg_l12a_1p8>; 218 + core-vcc-supply = <&vreg_s4a_1p8>; 219 + 220 + ports { 221 + #address-cells = <1>; 222 + #size-cells = <0>; 223 + 224 + port@0 { 225 + reg = <0>; 226 + endpoint { 227 + remote-endpoint = <&mdp5_intf3_out>; 228 + }; 229 + }; 230 + }; 231 + }; 232 + ...
+104
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-other.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/phy/qcom,hdmi-phy-other.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Qualcomm Adreno/Snapdragon HDMI phy 9 + 10 + maintainers: 11 + - Rob Clark <robdclark@gmail.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - qcom,hdmi-phy-8660 17 + - qcom,hdmi-phy-8960 18 + - qcom,hdmi-phy-8974 19 + - qcom,hdmi-phy-8084 20 + 21 + reg: 22 + maxItems: 2 23 + 24 + reg-names: 25 + items: 26 + - const: hdmi_phy 27 + - const: hdmi_pll 28 + 29 + clocks: 30 + minItems: 1 31 + maxItems: 2 32 + 33 + clock-names: 34 + minItems: 1 35 + maxItems: 2 36 + 37 + power-domains: 38 + maxItems: 1 39 + 40 + core-vdda-supply: 41 + description: phandle to VDDA supply regulator 42 + 43 + vddio-supply: 44 + description: phandle to VDD I/O supply regulator 45 + 46 + '#phy-cells': 47 + const: 0 48 + 49 + allOf: 50 + - if: 51 + properties: 52 + compatible: 53 + contains: 54 + enum: 55 + - qcom,hdmi-phy-8660 56 + - qcom,hdmi-phy-8960 57 + then: 58 + properties: 59 + clocks: 60 + maxItems: 1 61 + clock-names: 62 + items: 63 + - const: slave_iface 64 + vddio-supply: false 65 + 66 + - if: 67 + properties: 68 + compatible: 69 + contains: 70 + enum: 71 + - qcom,hdmi-phy-8084 72 + - qcom,hdmi-phy-8974 73 + then: 74 + properties: 75 + clocks: 76 + maxItems: 2 77 + clock-names: 78 + items: 79 + - const: iface 80 + - const: alt_iface 81 + 82 + required: 83 + - compatible 84 + - clocks 85 + - reg 86 + - reg-names 87 + - '#phy-cells' 88 + 89 + additionalProperties: false 90 + 91 + examples: 92 + - | 93 + hdmi_phy: phy@4a00400 { 94 + compatible = "qcom,hdmi-phy-8960"; 95 + reg-names = "hdmi_phy", 96 + "hdmi_pll"; 97 + reg = <0x4a00400 0x60>, 98 + <0x4a00500 0x100>; 99 + #phy-cells = <0>; 100 + power-domains = <&mmcc 1>; 101 + clock-names = "slave_iface"; 102 + clocks = <&clk 21>; 103 + core-vdda-supply = <&pm8921_hdmi_mvs>; 104 + };
+85
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-qmp.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/phy/qcom,hdmi-phy-qmp.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Qualcomm Adreno/Snapdragon QMP HDMI phy 9 + 10 + maintainers: 11 + - Rob Clark <robdclark@gmail.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - qcom,hdmi-phy-8996 17 + 18 + reg: 19 + maxItems: 6 20 + 21 + reg-names: 22 + items: 23 + - const: hdmi_pll 24 + - const: hdmi_tx_l0 25 + - const: hdmi_tx_l1 26 + - const: hdmi_tx_l2 27 + - const: hdmi_tx_l3 28 + - const: hdmi_phy 29 + 30 + clocks: 31 + maxItems: 2 32 + 33 + clock-names: 34 + items: 35 + - const: iface 36 + - const: ref 37 + 38 + power-domains: 39 + maxItems: 1 40 + 41 + vcca-supply: 42 + description: phandle to VCCA supply regulator 43 + 44 + vddio-supply: 45 + description: phandle to VDD I/O supply regulator 46 + 47 + '#phy-cells': 48 + const: 0 49 + 50 + required: 51 + - compatible 52 + - clocks 53 + - clock-names 54 + - reg 55 + - reg-names 56 + - '#phy-cells' 57 + 58 + additionalProperties: false 59 + 60 + examples: 61 + - | 62 + hdmi-phy@9a0600 { 63 + compatible = "qcom,hdmi-phy-8996"; 64 + reg = <0x009a0600 0x1c4>, 65 + <0x009a0a00 0x124>, 66 + <0x009a0c00 0x124>, 67 + <0x009a0e00 0x124>, 68 + <0x009a1000 0x124>, 69 + <0x009a1200 0x0c8>; 70 + reg-names = "hdmi_pll", 71 + "hdmi_tx_l0", 72 + "hdmi_tx_l1", 73 + "hdmi_tx_l2", 74 + "hdmi_tx_l3", 75 + "hdmi_phy"; 76 + 77 + clocks = <&mmcc 116>, 78 + <&gcc 214>; 79 + clock-names = "iface", 80 + "ref"; 81 + #phy-cells = <0>; 82 + 83 + vddio-supply = <&vreg_l12a_1p8>; 84 + vcca-supply = <&vreg_l28a_0p925>; 85 + };
+21
Documentation/gpu/drm-usage-stats.rst
··· 105 105 Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' 106 106 indicating kibi- or mebi-bytes. 107 107 108 + - drm-cycles-<str> <uint> 109 + 110 + Engine identifier string must be the same as the one specified in the 111 + drm-engine-<str> tag and shall contain the number of busy cycles for the given 112 + engine. 113 + 114 + Values are not required to be constantly monotonic if it makes the driver 115 + implementation easier, but are required to catch up with the previously reported 116 + larger value within a reasonable period. Upon observing a value lower than what 117 + was previously read, userspace is expected to stay with that larger previous 118 + value until a monotonic update is seen. 119 + 120 + - drm-maxfreq-<str> <uint> [Hz|MHz|KHz] 121 + 122 + Engine identifier string must be the same as the one specified in the 123 + drm-engine-<str> tag and shall contain the maximum frequency for the given 124 + engine. Taken together with drm-cycles-<str>, this can be used to calculate 125 + percentage utilization of the engine, whereas drm-engine-<str> only reflects 126 + time active without considering what frequency the engine is operating as a 127 + percentage of it's maximum frequency. 128 + 108 129 =============================== 109 130 Driver specific implementations 110 131 ===============================
-1
drivers/gpu/drm/msm/Makefile
··· 119 119 120 120 msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ 121 121 dp/dp_catalog.o \ 122 - dp/dp_clk_util.o \ 123 122 dp/dp_ctrl.o \ 124 123 dp/dp_display.o \ 125 124 dp/dp_drm.o \
-8
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
··· 1666 1666 { 1667 1667 u64 busy_cycles; 1668 1668 1669 - /* Only read the gpu busy if the hardware is already active */ 1670 - if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0) { 1671 - *out_sample_rate = 1; 1672 - return 0; 1673 - } 1674 - 1675 1669 busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, 1676 1670 REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); 1677 1671 *out_sample_rate = clk_get_rate(gpu->core_clk); 1678 - 1679 - pm_runtime_put(&gpu->pdev->dev); 1680 1672 1681 1673 return busy_cycles; 1682 1674 }
+19 -11
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
··· 102 102 A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF)); 103 103 } 104 104 105 - void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) 105 + void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, 106 + bool suspended) 106 107 { 107 108 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 108 109 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); ··· 128 127 129 128 /* 130 129 * This can get called from devfreq while the hardware is idle. Don't 131 - * bring up the power if it isn't already active 130 + * bring up the power if it isn't already active. All we're doing here 131 + * is updating the frequency so that when we come back online we're at 132 + * the right rate. 132 133 */ 133 - if (pm_runtime_get_if_in_use(gmu->dev) == 0) 134 + if (suspended) 134 135 return; 135 136 136 137 if (!gmu->legacy) { 137 138 a6xx_hfi_set_freq(gmu, perf_index); 138 139 dev_pm_opp_set_opp(&gpu->pdev->dev, opp); 139 - pm_runtime_put(gmu->dev); 140 140 return; 141 141 } 142 142 ··· 161 159 dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret); 162 160 163 161 dev_pm_opp_set_opp(&gpu->pdev->dev, opp); 164 - pm_runtime_put(gmu->dev); 165 162 } 166 163 167 164 unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu) ··· 505 504 506 505 static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value) 507 506 { 508 - return msm_writel(value, ptr + (offset << 2)); 507 + msm_writel(value, ptr + (offset << 2)); 509 508 } 510 509 511 510 static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, ··· 528 527 pdc_in_aop = true; 529 528 else if (adreno_is_a618(adreno_gpu) || adreno_is_a640_family(adreno_gpu)) 530 529 pdc_address_offset = 0x30090; 530 + else if (adreno_is_a619(adreno_gpu)) 531 + pdc_address_offset = 0x300a0; 531 532 else 532 533 pdc_address_offset = 0x30080; 533 534 ··· 604 601 605 602 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108); 606 603 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000); 607 - if (adreno_is_a618(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) 604 + if (adreno_is_a618(adreno_gpu) || adreno_is_a619(adreno_gpu) || 605 + adreno_is_a650_family(adreno_gpu)) 608 606 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2); 609 607 else 610 608 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3); ··· 899 895 return; 900 896 901 897 gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */ 902 - a6xx_gmu_set_freq(gpu, gpu_opp); 898 + a6xx_gmu_set_freq(gpu, gpu_opp, false); 903 899 dev_pm_opp_put(gpu_opp); 904 900 } 905 901 ··· 1541 1537 SZ_16M - SZ_16K, 0x04000, "icache"); 1542 1538 if (ret) 1543 1539 goto err_memory; 1540 + /* 1541 + * NOTE: when porting legacy ("pre-650-family") GPUs you may be tempted to add a condition 1542 + * to allocate icache/dcache here, as per downstream code flow, but it may not actually be 1543 + * necessary. If you omit this step and you don't get random pagefaults, you are likely 1544 + * good to go without this! 1545 + */ 1544 1546 } else if (adreno_is_a640_family(adreno_gpu)) { 1545 1547 ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache, 1546 1548 SZ_256K - SZ_16K, 0x04000, "icache"); ··· 1557 1547 SZ_256K - SZ_16K, 0x44000, "dcache"); 1558 1548 if (ret) 1559 1549 goto err_memory; 1560 - } else { 1561 - BUG_ON(adreno_is_a660_family(adreno_gpu)); 1562 - 1550 + } else if (adreno_is_a630(adreno_gpu) || adreno_is_a615_family(adreno_gpu)) { 1563 1551 /* HFI v1, has sptprac */ 1564 1552 gmu->legacy = true; 1565 1553
+2 -2
drivers/gpu/drm/msm/adreno/a6xx_gmu.h
··· 98 98 99 99 static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value) 100 100 { 101 - return msm_writel(value, gmu->mmio + (offset << 2)); 101 + msm_writel(value, gmu->mmio + (offset << 2)); 102 102 } 103 103 104 104 static inline void ··· 138 138 139 139 static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value) 140 140 { 141 - return msm_writel(value, gmu->rscc + (offset << 2)); 141 + msm_writel(value, gmu->rscc + (offset << 2)); 142 142 } 143 143 144 144 #define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \
+94 -12
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
··· 252 252 a6xx_flush(gpu, ring); 253 253 } 254 254 255 + /* For a615 family (a615, a616, a618 and a619) */ 256 + const struct adreno_reglist a615_hwcg[] = { 257 + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, 258 + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, 259 + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, 260 + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, 261 + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222}, 262 + {REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222}, 263 + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, 264 + {REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222}, 265 + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222}, 266 + {REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222}, 267 + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222}, 268 + {REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222}, 269 + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, 270 + {REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777}, 271 + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, 272 + {REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777}, 273 + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777}, 274 + {REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777}, 275 + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777}, 276 + {REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777}, 277 + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, 278 + {REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111}, 279 + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, 280 + {REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111}, 281 + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111}, 282 + {REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111}, 283 + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111}, 284 + {REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111}, 285 + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, 286 + {REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, 287 + {REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, 288 + {REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, 289 + {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004}, 290 + {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, 291 + {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, 292 + {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222}, 293 + {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002020}, 294 + {REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220}, 295 + {REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220}, 296 + {REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220}, 297 + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00}, 298 + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00}, 299 + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00}, 300 + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00}, 301 + {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022}, 302 + {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555}, 303 + {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011}, 304 + {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044}, 305 + {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, 306 + {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222}, 307 + {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, 308 + {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, 309 + {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, 310 + {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, 311 + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, 312 + {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, 313 + {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, 314 + {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, 315 + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002}, 316 + {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222}, 317 + {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222}, 318 + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, 319 + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, 320 + {}, 321 + }; 322 + 255 323 const struct adreno_reglist a630_hwcg[] = { 256 324 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222}, 257 325 {REG_A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222}, ··· 623 555 gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0); 624 556 } 625 557 626 - /* For a615, a616, a618, A619, a630, a640 and a680 */ 558 + /* For a615, a616, a618, a619, a630, a640 and a680 */ 627 559 static const u32 a6xx_protect[] = { 628 560 A6XX_PROTECT_RDONLY(0x00000, 0x04ff), 629 561 A6XX_PROTECT_RDONLY(0x00501, 0x0005), ··· 1514 1446 1515 1447 static void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value) 1516 1448 { 1517 - return msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2)); 1449 + msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2)); 1518 1450 } 1519 1451 1520 1452 static void a6xx_llc_deactivate(struct a6xx_gpu *a6xx_gpu) ··· 1726 1658 /* 19.2MHz */ 1727 1659 *out_sample_rate = 19200000; 1728 1660 1729 - /* Only read the gpu busy if the hardware is already active */ 1730 - if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0) 1731 - return 0; 1732 - 1733 1661 busy_cycles = gmu_read64(&a6xx_gpu->gmu, 1734 1662 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L, 1735 1663 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H); 1736 1664 1737 - 1738 - pm_runtime_put(a6xx_gpu->gmu.dev); 1739 - 1740 1665 return busy_cycles; 1741 1666 } 1742 1667 1743 - static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) 1668 + static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, 1669 + bool suspended) 1744 1670 { 1745 1671 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 1746 1672 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 1747 1673 1748 1674 mutex_lock(&a6xx_gpu->gmu.lock); 1749 - a6xx_gmu_set_freq(gpu, opp); 1675 + a6xx_gmu_set_freq(gpu, opp, suspended); 1750 1676 mutex_unlock(&a6xx_gpu->gmu.lock); 1751 1677 } 1752 1678 ··· 1799 1737 return ERR_CAST(mmu); 1800 1738 1801 1739 return msm_gem_address_space_create(mmu, 1802 - "gpu", 0x100000000ULL, SZ_4G); 1740 + "gpu", 0x100000000ULL, 1741 + adreno_private_address_space_size(gpu)); 1803 1742 } 1804 1743 1805 1744 static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) ··· 1826 1763 return UINT_MAX; 1827 1764 } 1828 1765 1766 + static u32 a619_get_speed_bin(u32 fuse) 1767 + { 1768 + if (fuse == 0) 1769 + return 0; 1770 + else if (fuse == 120) 1771 + return 4; 1772 + else if (fuse == 138) 1773 + return 3; 1774 + else if (fuse == 169) 1775 + return 2; 1776 + else if (fuse == 180) 1777 + return 1; 1778 + 1779 + return UINT_MAX; 1780 + } 1781 + 1829 1782 static u32 adreno_7c3_get_speed_bin(u32 fuse) 1830 1783 { 1831 1784 if (fuse == 0) ··· 1860 1781 1861 1782 if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) 1862 1783 val = a618_get_speed_bin(fuse); 1784 + 1785 + if (adreno_cmp_rev(ADRENO_REV(6, 1, 9, ANY_ID), rev)) 1786 + val = a619_get_speed_bin(fuse); 1863 1787 1864 1788 if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) 1865 1789 val = adreno_7c3_get_speed_bin(fuse);
+2 -1
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
··· 77 77 int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); 78 78 void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); 79 79 80 - void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp); 80 + void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, 81 + bool suspended); 81 82 unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu); 82 83 83 84 void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+63 -2
drivers/gpu/drm/msm/adreno/a6xx_hfi.c
··· 205 205 { 206 206 struct a6xx_hfi_msg_fw_version msg = { 0 }; 207 207 208 - /* Currently supporting version 1.1 */ 209 - msg.supported_version = (1 << 28) | (1 << 16); 208 + /* Currently supporting version 1.10 */ 209 + msg.supported_version = (1 << 28) | (1 << 19) | (1 << 17); 210 210 211 211 return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_FW_VERSION, &msg, sizeof(msg), 212 212 version, sizeof(*version)); ··· 283 283 msg->cnoc_cmds_addrs[0] = 0x5007c; 284 284 msg->cnoc_cmds_data[0][0] = 0x40000000; 285 285 msg->cnoc_cmds_data[1][0] = 0x60000001; 286 + } 287 + 288 + static void a619_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) 289 + { 290 + msg->bw_level_num = 13; 291 + 292 + msg->ddr_cmds_num = 3; 293 + msg->ddr_wait_bitmask = 0x0; 294 + 295 + msg->ddr_cmds_addrs[0] = 0x50000; 296 + msg->ddr_cmds_addrs[1] = 0x50004; 297 + msg->ddr_cmds_addrs[2] = 0x50080; 298 + 299 + msg->ddr_cmds_data[0][0] = 0x40000000; 300 + msg->ddr_cmds_data[0][1] = 0x40000000; 301 + msg->ddr_cmds_data[0][2] = 0x40000000; 302 + msg->ddr_cmds_data[1][0] = 0x6000030c; 303 + msg->ddr_cmds_data[1][1] = 0x600000db; 304 + msg->ddr_cmds_data[1][2] = 0x60000008; 305 + msg->ddr_cmds_data[2][0] = 0x60000618; 306 + msg->ddr_cmds_data[2][1] = 0x600001b6; 307 + msg->ddr_cmds_data[2][2] = 0x60000008; 308 + msg->ddr_cmds_data[3][0] = 0x60000925; 309 + msg->ddr_cmds_data[3][1] = 0x60000291; 310 + msg->ddr_cmds_data[3][2] = 0x60000008; 311 + msg->ddr_cmds_data[4][0] = 0x60000dc1; 312 + msg->ddr_cmds_data[4][1] = 0x600003dc; 313 + msg->ddr_cmds_data[4][2] = 0x60000008; 314 + msg->ddr_cmds_data[5][0] = 0x600010ad; 315 + msg->ddr_cmds_data[5][1] = 0x600004ae; 316 + msg->ddr_cmds_data[5][2] = 0x60000008; 317 + msg->ddr_cmds_data[6][0] = 0x600014c3; 318 + msg->ddr_cmds_data[6][1] = 0x600005d4; 319 + msg->ddr_cmds_data[6][2] = 0x60000008; 320 + msg->ddr_cmds_data[7][0] = 0x6000176a; 321 + msg->ddr_cmds_data[7][1] = 0x60000693; 322 + msg->ddr_cmds_data[7][2] = 0x60000008; 323 + msg->ddr_cmds_data[8][0] = 0x60001f01; 324 + msg->ddr_cmds_data[8][1] = 0x600008b5; 325 + msg->ddr_cmds_data[8][2] = 0x60000008; 326 + msg->ddr_cmds_data[9][0] = 0x60002940; 327 + msg->ddr_cmds_data[9][1] = 0x60000b95; 328 + msg->ddr_cmds_data[9][2] = 0x60000008; 329 + msg->ddr_cmds_data[10][0] = 0x60002f68; 330 + msg->ddr_cmds_data[10][1] = 0x60000d50; 331 + msg->ddr_cmds_data[10][2] = 0x60000008; 332 + msg->ddr_cmds_data[11][0] = 0x60003700; 333 + msg->ddr_cmds_data[11][1] = 0x60000f71; 334 + msg->ddr_cmds_data[11][2] = 0x60000008; 335 + msg->ddr_cmds_data[12][0] = 0x60003fce; 336 + msg->ddr_cmds_data[12][1] = 0x600011ea; 337 + msg->ddr_cmds_data[12][2] = 0x60000008; 338 + 339 + msg->cnoc_cmds_num = 1; 340 + msg->cnoc_wait_bitmask = 0x0; 341 + 342 + msg->cnoc_cmds_addrs[0] = 0x50054; 343 + 344 + msg->cnoc_cmds_data[0][0] = 0x40000000; 286 345 } 287 346 288 347 static void a640_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) ··· 521 462 522 463 if (adreno_is_a618(adreno_gpu)) 523 464 a618_build_bw_table(&msg); 465 + else if (adreno_is_a619(adreno_gpu)) 466 + a619_build_bw_table(&msg); 524 467 else if (adreno_is_a640_family(adreno_gpu)) 525 468 a640_build_bw_table(&msg); 526 469 else if (adreno_is_a650(adreno_gpu))
+23
drivers/gpu/drm/msm/adreno/adreno_device.c
··· 265 265 .inactive_period = DRM_MSM_INACTIVE_PERIOD, 266 266 .init = a6xx_gpu_init, 267 267 }, { 268 + .rev = ADRENO_REV(6, 1, 9, ANY_ID), 269 + .revn = 619, 270 + .name = "A619", 271 + .fw = { 272 + [ADRENO_FW_SQE] = "a630_sqe.fw", 273 + [ADRENO_FW_GMU] = "a619_gmu.bin", 274 + }, 275 + .gmem = SZ_512K, 276 + .inactive_period = DRM_MSM_INACTIVE_PERIOD, 277 + .init = a6xx_gpu_init, 278 + .zapfw = "a615_zap.mdt", 279 + .hwcg = a615_hwcg, 280 + }, { 268 281 .rev = ADRENO_REV(6, 3, 0, ANY_ID), 269 282 .revn = 630, 270 283 .name = "A630", ··· 316 303 .init = a6xx_gpu_init, 317 304 .zapfw = "a650_zap.mdt", 318 305 .hwcg = a650_hwcg, 306 + .address_space_size = SZ_16G, 319 307 }, { 320 308 .rev = ADRENO_REV(6, 6, 0, ANY_ID), 321 309 .revn = 660, ··· 330 316 .init = a6xx_gpu_init, 331 317 .zapfw = "a660_zap.mdt", 332 318 .hwcg = a660_hwcg, 319 + .address_space_size = SZ_16G, 333 320 }, { 334 321 .rev = ADRENO_REV(6, 3, 5, ANY_ID), 335 322 .fw = { ··· 341 326 .inactive_period = DRM_MSM_INACTIVE_PERIOD, 342 327 .init = a6xx_gpu_init, 343 328 .hwcg = a660_hwcg, 329 + .address_space_size = SZ_16G, 344 330 }, { 345 331 .rev = ADRENO_REV(6, 8, 0, ANY_ID), 346 332 .revn = 680, ··· 371 355 MODULE_FIRMWARE("qcom/a530_zap.b00"); 372 356 MODULE_FIRMWARE("qcom/a530_zap.b01"); 373 357 MODULE_FIRMWARE("qcom/a530_zap.b02"); 358 + MODULE_FIRMWARE("qcom/a619_gmu.bin"); 374 359 MODULE_FIRMWARE("qcom/a630_sqe.fw"); 375 360 MODULE_FIRMWARE("qcom/a630_gmu.bin"); 376 361 MODULE_FIRMWARE("qcom/a630_zap.mbn"); ··· 431 414 ret = adreno_load_fw(adreno_gpu); 432 415 if (ret) 433 416 return NULL; 417 + 418 + /* 419 + * Now that we have firmware loaded, and are ready to begin 420 + * booting the gpu, go ahead and enable runpm: 421 + */ 422 + pm_runtime_enable(&pdev->dev); 434 423 435 424 /* Make sure pm runtime is active and reset any previous errors */ 436 425 pm_runtime_set_active(&pdev->dev);
+23 -6
drivers/gpu/drm/msm/adreno/adreno_gpu.c
··· 21 21 #include "msm_gem.h" 22 22 #include "msm_mmu.h" 23 23 24 + static u64 address_space_size = 0; 25 + MODULE_PARM_DESC(address_space_size, "Override for size of processes private GPU address space"); 26 + module_param(address_space_size, ullong, 0600); 27 + 24 28 static bool zap_available = true; 25 29 26 30 static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname, ··· 230 226 mmu->funcs->destroy(mmu); 231 227 232 228 return aspace; 229 + } 230 + 231 + u64 adreno_private_address_space_size(struct msm_gpu *gpu) 232 + { 233 + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 234 + 235 + if (address_space_size) 236 + return address_space_size; 237 + 238 + if (adreno_gpu->info->address_space_size) 239 + return adreno_gpu->info->address_space_size; 240 + 241 + return SZ_4G; 233 242 } 234 243 235 244 int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, ··· 807 790 for (i = 0; i < gpu->nr_rings; i++) { 808 791 drm_printf(p, " - id: %d\n", i); 809 792 drm_printf(p, " iova: 0x%016llx\n", state->ring[i].iova); 810 - drm_printf(p, " last-fence: %d\n", state->ring[i].seqno); 811 - drm_printf(p, " retired-fence: %d\n", state->ring[i].fence); 812 - drm_printf(p, " rptr: %d\n", state->ring[i].rptr); 813 - drm_printf(p, " wptr: %d\n", state->ring[i].wptr); 814 - drm_printf(p, " size: %d\n", MSM_GPU_RINGBUFFER_SZ); 793 + drm_printf(p, " last-fence: %u\n", state->ring[i].seqno); 794 + drm_printf(p, " retired-fence: %u\n", state->ring[i].fence); 795 + drm_printf(p, " rptr: %u\n", state->ring[i].rptr); 796 + drm_printf(p, " wptr: %u\n", state->ring[i].wptr); 797 + drm_printf(p, " size: %u\n", MSM_GPU_RINGBUFFER_SZ); 815 798 816 799 adreno_show_object(p, &state->ring[i].data, 817 800 state->ring[i].data_size, &state->ring[i].encoded); ··· 824 807 drm_printf(p, " - iova: 0x%016llx\n", 825 808 state->bos[i].iova); 826 809 drm_printf(p, " size: %zd\n", state->bos[i].size); 810 + drm_printf(p, " name: %-32s\n", state->bos[i].name); 827 811 828 812 adreno_show_object(p, &state->bos[i].data, 829 813 state->bos[i].size, &state->bos[i].encoded); ··· 1065 1047 pm_runtime_set_autosuspend_delay(dev, 1066 1048 adreno_gpu->info->inactive_period); 1067 1049 pm_runtime_use_autosuspend(dev); 1068 - pm_runtime_enable(dev); 1069 1050 1070 1051 return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, 1071 1052 gpu_name, &adreno_gpu_config);
+22 -10
drivers/gpu/drm/msm/adreno/adreno_gpu.h
··· 57 57 u32 value; 58 58 }; 59 59 60 - extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[]; 60 + extern const struct adreno_reglist a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[]; 61 61 62 62 struct adreno_info { 63 63 struct adreno_rev rev; ··· 70 70 const char *zapfw; 71 71 u32 inactive_period; 72 72 const struct adreno_reglist *hwcg; 73 + u64 address_space_size; 73 74 }; 74 75 75 76 const struct adreno_info *adreno_info(struct adreno_rev rev); ··· 200 199 201 200 static inline int adreno_is_a430(struct adreno_gpu *gpu) 202 201 { 203 - return gpu->revn == 430; 202 + return gpu->revn == 430; 204 203 } 205 204 206 205 static inline int adreno_is_a506(struct adreno_gpu *gpu) ··· 240 239 241 240 static inline int adreno_is_a618(struct adreno_gpu *gpu) 242 241 { 243 - return gpu->revn == 618; 242 + return gpu->revn == 618; 243 + } 244 + 245 + static inline int adreno_is_a619(struct adreno_gpu *gpu) 246 + { 247 + return gpu->revn == 619; 244 248 } 245 249 246 250 static inline int adreno_is_a630(struct adreno_gpu *gpu) 247 251 { 248 - return gpu->revn == 630; 252 + return gpu->revn == 630; 249 253 } 250 254 251 255 static inline int adreno_is_a640_family(struct adreno_gpu *gpu) ··· 260 254 261 255 static inline int adreno_is_a650(struct adreno_gpu *gpu) 262 256 { 263 - return gpu->revn == 650; 257 + return gpu->revn == 650; 264 258 } 265 259 266 260 static inline int adreno_is_7c3(struct adreno_gpu *gpu) 267 261 { 268 262 /* The order of args is important here to handle ANY_ID correctly */ 269 - return adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), gpu->rev); 263 + return adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), gpu->rev); 270 264 } 271 265 272 266 static inline int adreno_is_a660(struct adreno_gpu *gpu) 273 267 { 274 - return gpu->revn == 660; 268 + return gpu->revn == 660; 269 + } 270 + 271 + /* check for a615, a616, a618, a619 or any derivatives */ 272 + static inline int adreno_is_a615_family(struct adreno_gpu *gpu) 273 + { 274 + return gpu->revn == 615 || gpu->revn == 616 || gpu->revn == 618 || gpu->revn == 619; 275 275 } 276 276 277 277 static inline int adreno_is_a660_family(struct adreno_gpu *gpu) 278 278 { 279 - return adreno_is_a660(gpu) || adreno_is_7c3(gpu); 279 + return adreno_is_a660(gpu) || adreno_is_7c3(gpu); 280 280 } 281 281 282 282 /* check for a650, a660, or any derivatives */ 283 283 static inline int adreno_is_a650_family(struct adreno_gpu *gpu) 284 284 { 285 - return gpu->revn == 650 || gpu->revn == 620 || 286 - adreno_is_a660_family(gpu); 285 + return gpu->revn == 650 || gpu->revn == 620 || adreno_is_a660_family(gpu); 287 286 } 288 287 288 + u64 adreno_private_address_space_size(struct msm_gpu *gpu); 289 289 int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, 290 290 uint32_t param, uint64_t *value, uint32_t *len); 291 291 int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
+12 -12
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
··· 53 53 crtc_plane_bw += pstate->plane_fetch_bw; 54 54 } 55 55 56 - bw_factor = kms->catalog->perf.bw_inefficiency_factor; 56 + bw_factor = kms->catalog->perf->bw_inefficiency_factor; 57 57 if (bw_factor) { 58 58 crtc_plane_bw *= bw_factor; 59 59 do_div(crtc_plane_bw, 100); ··· 90 90 crtc_clk = max(pstate->plane_clk, crtc_clk); 91 91 } 92 92 93 - clk_factor = kms->catalog->perf.clk_inefficiency_factor; 93 + clk_factor = kms->catalog->perf->clk_inefficiency_factor; 94 94 if (clk_factor) { 95 95 crtc_clk *= clk_factor; 96 96 do_div(crtc_clk, 100); ··· 128 128 perf->core_clk_rate = kms->perf.fix_core_clk_rate; 129 129 } else { 130 130 perf->bw_ctl = _dpu_core_perf_calc_bw(kms, crtc); 131 - perf->max_per_pipe_ib = kms->catalog->perf.min_dram_ib; 131 + perf->max_per_pipe_ib = kms->catalog->perf->min_dram_ib; 132 132 perf->core_clk_rate = _dpu_core_perf_calc_clk(kms, crtc, state); 133 133 } 134 134 ··· 189 189 bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000); 190 190 DRM_DEBUG_ATOMIC("calculated bandwidth=%uk\n", bw); 191 191 192 - threshold = kms->catalog->perf.max_bw_high; 192 + threshold = kms->catalog->perf->max_bw_high; 193 193 194 194 DRM_DEBUG_ATOMIC("final threshold bw limit = %d\n", threshold); 195 195 ··· 413 413 const char __user *user_buf, size_t count, loff_t *ppos) 414 414 { 415 415 struct dpu_core_perf *perf = file->private_data; 416 - struct dpu_perf_cfg *cfg = &perf->catalog->perf; 416 + const struct dpu_perf_cfg *cfg = perf->catalog->perf; 417 417 u32 perf_mode = 0; 418 418 int ret; 419 419 ··· 468 468 int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) 469 469 { 470 470 struct dpu_core_perf *perf = &dpu_kms->perf; 471 - struct dpu_mdss_cfg *catalog = perf->catalog; 471 + const struct dpu_mdss_cfg *catalog = perf->catalog; 472 472 struct dentry *entry; 473 473 474 474 entry = debugfs_create_dir("core_perf", parent); ··· 480 480 debugfs_create_u32("enable_bw_release", 0600, entry, 481 481 (u32 *)&perf->enable_bw_release); 482 482 debugfs_create_u32("threshold_low", 0600, entry, 483 - (u32 *)&catalog->perf.max_bw_low); 483 + (u32 *)&catalog->perf->max_bw_low); 484 484 debugfs_create_u32("threshold_high", 0600, entry, 485 - (u32 *)&catalog->perf.max_bw_high); 485 + (u32 *)&catalog->perf->max_bw_high); 486 486 debugfs_create_u32("min_core_ib", 0600, entry, 487 - (u32 *)&catalog->perf.min_core_ib); 487 + (u32 *)&catalog->perf->min_core_ib); 488 488 debugfs_create_u32("min_llcc_ib", 0600, entry, 489 - (u32 *)&catalog->perf.min_llcc_ib); 489 + (u32 *)&catalog->perf->min_llcc_ib); 490 490 debugfs_create_u32("min_dram_ib", 0600, entry, 491 - (u32 *)&catalog->perf.min_dram_ib); 491 + (u32 *)&catalog->perf->min_dram_ib); 492 492 debugfs_create_file("perf_mode", 0600, entry, 493 493 (u32 *)perf, &dpu_core_perf_mode_fops); 494 494 debugfs_create_u64("fix_core_clk_rate", 0600, entry, ··· 517 517 518 518 int dpu_core_perf_init(struct dpu_core_perf *perf, 519 519 struct drm_device *dev, 520 - struct dpu_mdss_cfg *catalog, 520 + const struct dpu_mdss_cfg *catalog, 521 521 struct clk *core_clk) 522 522 { 523 523 perf->dev = dev;
+2 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
··· 68 68 struct dpu_core_perf { 69 69 struct drm_device *dev; 70 70 struct dentry *debugfs_root; 71 - struct dpu_mdss_cfg *catalog; 71 + const struct dpu_mdss_cfg *catalog; 72 72 struct clk *core_clk; 73 73 u64 core_clk_rate; 74 74 u64 max_core_clk_rate; ··· 119 119 */ 120 120 int dpu_core_perf_init(struct dpu_core_perf *perf, 121 121 struct drm_device *dev, 122 - struct dpu_mdss_cfg *catalog, 122 + const struct dpu_mdss_cfg *catalog, 123 123 struct clk *core_clk); 124 124 125 125 struct dpu_kms;
+92 -25
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 4 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 4 5 * Copyright (C) 2013 Red Hat 5 6 * Author: Rob Clark <robdclark@gmail.com> ··· 81 80 if (!strcmp(src_name, "auto") || 82 81 !strcmp(src_name, "lm")) 83 82 return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; 83 + if (!strcmp(src_name, "encoder")) 84 + return DPU_CRTC_CRC_SOURCE_ENCODER; 84 85 85 86 return DPU_CRTC_CRC_SOURCE_INVALID; 86 87 } ··· 98 95 return -EINVAL; 99 96 } 100 97 101 - if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) 98 + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) { 102 99 *values_cnt = crtc_state->num_mixers; 100 + } else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) { 101 + struct drm_encoder *drm_enc; 102 + 103 + *values_cnt = 0; 104 + 105 + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) 106 + *values_cnt += dpu_encoder_get_crc_values_cnt(drm_enc); 107 + } 103 108 104 109 return 0; 110 + } 111 + 112 + static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) 113 + { 114 + struct dpu_crtc_mixer *m; 115 + int i; 116 + 117 + for (i = 0; i < crtc_state->num_mixers; ++i) { 118 + m = &crtc_state->mixers[i]; 119 + 120 + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) 121 + continue; 122 + 123 + /* Calculate MISR over 1 frame */ 124 + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); 125 + } 126 + } 127 + 128 + static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc) 129 + { 130 + struct drm_encoder *drm_enc; 131 + 132 + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) 133 + dpu_encoder_setup_misr(drm_enc); 105 134 } 106 135 107 136 static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) ··· 142 107 enum dpu_crtc_crc_source current_source; 143 108 struct dpu_crtc_state *crtc_state; 144 109 struct drm_device *drm_dev = crtc->dev; 145 - struct dpu_crtc_mixer *m; 146 110 147 111 bool was_enabled; 148 112 bool enable = false; 149 - int i, ret = 0; 113 + int ret = 0; 150 114 151 115 if (source < 0) { 152 116 DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index); ··· 182 148 183 149 crtc_state->crc_frame_skip_count = 0; 184 150 185 - for (i = 0; i < crtc_state->num_mixers; ++i) { 186 - m = &crtc_state->mixers[i]; 187 - 188 - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) 189 - continue; 190 - 191 - /* Calculate MISR over 1 frame */ 192 - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); 193 - } 194 - 151 + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) 152 + dpu_crtc_setup_lm_misr(crtc_state); 153 + else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) 154 + dpu_crtc_setup_encoder_misr(crtc); 155 + else 156 + ret = -EINVAL; 195 157 196 158 cleanup: 197 159 drm_modeset_unlock(&crtc->mutex); ··· 206 176 return dpu_encoder_get_vsync_count(encoder); 207 177 } 208 178 209 - 210 - static int dpu_crtc_get_crc(struct drm_crtc *crtc) 179 + static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, 180 + struct dpu_crtc_state *crtc_state) 211 181 { 212 - struct dpu_crtc_state *crtc_state; 213 182 struct dpu_crtc_mixer *m; 214 183 u32 crcs[CRTC_DUAL_MIXERS]; 215 184 216 - int i = 0; 217 185 int rc = 0; 218 - 219 - crtc_state = to_dpu_crtc_state(crtc->state); 186 + int i; 220 187 221 188 BUILD_BUG_ON(ARRAY_SIZE(crcs) != ARRAY_SIZE(crtc_state->mixers)); 222 - 223 - /* Skip first 2 frames in case of "uncooked" CRCs */ 224 - if (crtc_state->crc_frame_skip_count < 2) { 225 - crtc_state->crc_frame_skip_count++; 226 - return 0; 227 - } 228 189 229 190 for (i = 0; i < crtc_state->num_mixers; ++i) { 230 191 ··· 235 214 236 215 return drm_crtc_add_crc_entry(crtc, true, 237 216 drm_crtc_accurate_vblank_count(crtc), crcs); 217 + } 218 + 219 + static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc) 220 + { 221 + struct drm_encoder *drm_enc; 222 + int rc, pos = 0; 223 + u32 crcs[INTF_MAX]; 224 + 225 + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) { 226 + rc = dpu_encoder_get_crc(drm_enc, crcs, pos); 227 + if (rc < 0) { 228 + if (rc != -ENODATA) 229 + DRM_DEBUG_DRIVER("MISR read failed\n"); 230 + 231 + return rc; 232 + } 233 + 234 + pos += rc; 235 + } 236 + 237 + return drm_crtc_add_crc_entry(crtc, true, 238 + drm_crtc_accurate_vblank_count(crtc), crcs); 239 + } 240 + 241 + static int dpu_crtc_get_crc(struct drm_crtc *crtc) 242 + { 243 + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); 244 + 245 + /* Skip first 2 frames in case of "uncooked" CRCs */ 246 + if (crtc_state->crc_frame_skip_count < 2) { 247 + crtc_state->crc_frame_skip_count++; 248 + return 0; 249 + } 250 + 251 + if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) 252 + return dpu_crtc_get_lm_crc(crtc, crtc_state); 253 + else if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_ENCODER) 254 + return dpu_crtc_get_encoder_crc(crtc); 255 + 256 + return -EINVAL; 238 257 } 239 258 240 259 static bool dpu_crtc_get_scanout_position(struct drm_crtc *crtc, ··· 422 361 drm_atomic_crtc_for_each_plane(plane, crtc) { 423 362 state = plane->state; 424 363 if (!state) 364 + continue; 365 + 366 + if (!state->visible) 425 367 continue; 426 368 427 369 pstate = to_dpu_plane_state(state); ··· 1198 1134 goto end; 1199 1135 } 1200 1136 if (cnt >= DPU_STAGE_MAX * 4) 1137 + continue; 1138 + 1139 + if (!pstate->visible) 1201 1140 continue; 1202 1141 1203 1142 pstates[cnt].dpu_pstate = dpu_pstate;
+5 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 4 * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. 4 5 * Copyright (C) 2013 Red Hat 5 6 * Author: Rob Clark <robdclark@gmail.com> ··· 13 12 #include <drm/drm_crtc.h> 14 13 #include "dpu_kms.h" 15 14 #include "dpu_core_perf.h" 16 - #include "dpu_hw_blk.h" 17 15 18 16 #define DPU_CRTC_NAME_SIZE 12 19 17 ··· 73 73 * enum dpu_crtc_crc_source: CRC source 74 74 * @DPU_CRTC_CRC_SOURCE_NONE: no source set 75 75 * @DPU_CRTC_CRC_SOURCE_LAYER_MIXER: CRC in layer mixer 76 + * @DPU_CRTC_CRC_SOURCE_ENCODER: CRC in encoder 76 77 * @DPU_CRTC_CRC_SOURCE_INVALID: Invalid source 77 78 */ 78 79 enum dpu_crtc_crc_source { 79 80 DPU_CRTC_CRC_SOURCE_NONE = 0, 80 81 DPU_CRTC_CRC_SOURCE_LAYER_MIXER, 82 + DPU_CRTC_CRC_SOURCE_ENCODER, 81 83 DPU_CRTC_CRC_SOURCE_MAX, 82 84 DPU_CRTC_CRC_SOURCE_INVALID = -1 83 85 }; ··· 203 201 * @mixers : List of active mixers 204 202 * @num_ctls : Number of ctl paths in use 205 203 * @hw_ctls : List of active ctl paths 204 + * @crc_source : CRC source 205 + * @crc_frame_skip_count: Number of frames skipped before getting CRC 206 206 */ 207 207 struct dpu_crtc_state { 208 208 struct drm_crtc_state base;
+121 -62
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
··· 225 225 return dpu_enc->wide_bus_en; 226 226 } 227 227 228 + int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc) 229 + { 230 + struct dpu_encoder_virt *dpu_enc; 231 + int i, num_intf = 0; 232 + 233 + dpu_enc = to_dpu_encoder_virt(drm_enc); 234 + 235 + for (i = 0; i < dpu_enc->num_phys_encs; i++) { 236 + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 237 + 238 + if (phys->hw_intf && phys->hw_intf->ops.setup_misr 239 + && phys->hw_intf->ops.collect_misr) 240 + num_intf++; 241 + } 242 + 243 + return num_intf; 244 + } 245 + 246 + void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) 247 + { 248 + struct dpu_encoder_virt *dpu_enc; 249 + 250 + int i; 251 + 252 + dpu_enc = to_dpu_encoder_virt(drm_enc); 253 + 254 + for (i = 0; i < dpu_enc->num_phys_encs; i++) { 255 + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 256 + 257 + if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) 258 + continue; 259 + 260 + phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); 261 + } 262 + } 263 + 264 + int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos) 265 + { 266 + struct dpu_encoder_virt *dpu_enc; 267 + 268 + int i, rc = 0, entries_added = 0; 269 + 270 + if (!drm_enc->crtc) { 271 + DRM_ERROR("no crtc found for encoder %d\n", drm_enc->index); 272 + return -EINVAL; 273 + } 274 + 275 + dpu_enc = to_dpu_encoder_virt(drm_enc); 276 + 277 + for (i = 0; i < dpu_enc->num_phys_encs; i++) { 278 + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 279 + 280 + if (!phys->hw_intf || !phys->hw_intf->ops.collect_misr) 281 + continue; 282 + 283 + rc = phys->hw_intf->ops.collect_misr(phys->hw_intf, &crcs[pos + entries_added]); 284 + if (rc) 285 + return rc; 286 + entries_added++; 287 + } 288 + 289 + return entries_added; 290 + } 291 + 228 292 static void _dpu_encoder_setup_dither(struct dpu_hw_pingpong *hw_pp, unsigned bpc) 229 293 { 230 294 struct dpu_hw_dither_cfg dither_cfg = { 0 }; ··· 698 634 } 699 635 700 636 if (hw_mdptop->ops.setup_vsync_source && 701 - disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) { 637 + disp_info->is_cmd_mode) { 702 638 for (i = 0; i < dpu_enc->num_phys_encs; i++) 703 639 vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx; 704 640 ··· 782 718 } 783 719 dpu_enc = to_dpu_encoder_virt(drm_enc); 784 720 priv = drm_enc->dev->dev_private; 785 - is_vid_mode = dpu_enc->disp_info.capabilities & 786 - MSM_DISPLAY_CAP_VID_MODE; 721 + is_vid_mode = !dpu_enc->disp_info.is_cmd_mode; 787 722 788 723 /* 789 724 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET ··· 1111 1048 phys->hw_pp = dpu_enc->hw_pp[i]; 1112 1049 phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); 1113 1050 1114 - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) 1115 - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); 1116 - 1117 - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) 1118 - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); 1119 - 1120 - if (!phys->hw_intf && !phys->hw_wb) { 1121 - DPU_ERROR_ENC(dpu_enc, 1122 - "no intf or wb block assigned at idx: %d\n", i); 1123 - return; 1124 - } 1125 - 1126 - if (phys->hw_intf && phys->hw_wb) { 1127 - DPU_ERROR_ENC(dpu_enc, 1128 - "invalid phys both intf and wb block at idx: %d\n", i); 1129 - return; 1130 - } 1131 - 1132 1051 phys->cached_mode = crtc_state->adjusted_mode; 1133 1052 if (phys->ops.atomic_mode_set) 1134 1053 phys->ops.atomic_mode_set(phys, crtc_state, conn_state); ··· 1250 1205 mutex_unlock(&dpu_enc->enc_lock); 1251 1206 } 1252 1207 1253 - static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog, 1208 + static enum dpu_intf dpu_encoder_get_intf(const struct dpu_mdss_cfg *catalog, 1254 1209 enum dpu_intf_type type, u32 controller_id) 1255 1210 { 1256 1211 int i = 0; 1257 1212 1258 - if (type != INTF_WB) { 1259 - for (i = 0; i < catalog->intf_count; i++) { 1260 - if (catalog->intf[i].type == type 1261 - && catalog->intf[i].controller_id == controller_id) { 1262 - return catalog->intf[i].id; 1263 - } 1213 + if (type == INTF_WB) 1214 + return INTF_MAX; 1215 + 1216 + for (i = 0; i < catalog->intf_count; i++) { 1217 + if (catalog->intf[i].type == type 1218 + && catalog->intf[i].controller_id == controller_id) { 1219 + return catalog->intf[i].id; 1264 1220 } 1265 1221 } 1266 1222 1267 1223 return INTF_MAX; 1268 1224 } 1269 1225 1270 - static enum dpu_wb dpu_encoder_get_wb(struct dpu_mdss_cfg *catalog, 1226 + static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog, 1271 1227 enum dpu_intf_type type, u32 controller_id) 1272 1228 { 1273 1229 int i = 0; 1274 1230 1275 1231 if (type != INTF_WB) 1276 - goto end; 1232 + return WB_MAX; 1277 1233 1278 1234 for (i = 0; i < catalog->wb_count; i++) { 1279 1235 if (catalog->wb[i].id == controller_id) 1280 1236 return catalog->wb[i].id; 1281 1237 } 1282 1238 1283 - end: 1284 1239 return WB_MAX; 1285 1240 } 1286 1241 ··· 1648 1603 1649 1604 /* update only for command mode primary ctl */ 1650 1605 if ((phys == dpu_enc->cur_master) && 1651 - (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) 1606 + disp_info->is_cmd_mode 1652 1607 && ctl->ops.trigger_pending) 1653 1608 ctl->ops.trigger_pending(ctl); 1654 1609 } ··· 2184 2139 return -EINVAL; 2185 2140 } 2186 2141 2187 - if (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE) { 2188 - enc = dpu_encoder_phys_vid_init(params); 2189 - 2190 - if (IS_ERR_OR_NULL(enc)) { 2191 - DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n", 2192 - PTR_ERR(enc)); 2193 - return enc == NULL ? -EINVAL : PTR_ERR(enc); 2194 - } 2195 - 2196 - dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; 2197 - ++dpu_enc->num_phys_encs; 2198 - } 2199 - 2200 - if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) { 2201 - enc = dpu_encoder_phys_cmd_init(params); 2202 - 2203 - if (IS_ERR_OR_NULL(enc)) { 2204 - DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n", 2205 - PTR_ERR(enc)); 2206 - return enc == NULL ? -EINVAL : PTR_ERR(enc); 2207 - } 2208 - 2209 - dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; 2210 - ++dpu_enc->num_phys_encs; 2211 - } 2212 2142 2213 2143 if (disp_info->intf_type == DRM_MODE_ENCODER_VIRTUAL) { 2214 2144 enc = dpu_encoder_phys_wb_init(params); 2215 2145 2216 - if (IS_ERR_OR_NULL(enc)) { 2146 + if (IS_ERR(enc)) { 2217 2147 DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", 2218 - PTR_ERR(enc)); 2219 - return enc == NULL ? -EINVAL : PTR_ERR(enc); 2148 + PTR_ERR(enc)); 2149 + return PTR_ERR(enc); 2150 + } 2151 + 2152 + dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; 2153 + ++dpu_enc->num_phys_encs; 2154 + } else if (disp_info->is_cmd_mode) { 2155 + enc = dpu_encoder_phys_cmd_init(params); 2156 + 2157 + if (IS_ERR(enc)) { 2158 + DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n", 2159 + PTR_ERR(enc)); 2160 + return PTR_ERR(enc); 2161 + } 2162 + 2163 + dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; 2164 + ++dpu_enc->num_phys_encs; 2165 + } else { 2166 + enc = dpu_encoder_phys_vid_init(params); 2167 + 2168 + if (IS_ERR(enc)) { 2169 + DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n", 2170 + PTR_ERR(enc)); 2171 + return PTR_ERR(enc); 2220 2172 } 2221 2173 2222 2174 dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; ··· 2272 2230 2273 2231 DPU_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles); 2274 2232 2275 - if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) || 2276 - (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE)) 2233 + if (disp_info->intf_type != DRM_MODE_ENCODER_VIRTUAL) 2277 2234 dpu_enc->idle_pc_supported = 2278 2235 dpu_kms->catalog->caps->has_idle_pc; 2279 2236 ··· 2335 2294 struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 2336 2295 atomic_set(&phys->vsync_cnt, 0); 2337 2296 atomic_set(&phys->underrun_cnt, 0); 2297 + 2298 + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) 2299 + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); 2300 + 2301 + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) 2302 + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); 2303 + 2304 + if (!phys->hw_intf && !phys->hw_wb) { 2305 + DPU_ERROR_ENC(dpu_enc, "no intf or wb block assigned at idx: %d\n", i); 2306 + ret = -EINVAL; 2307 + } 2308 + 2309 + if (phys->hw_intf && phys->hw_wb) { 2310 + DPU_ERROR_ENC(dpu_enc, 2311 + "invalid phys both intf and wb block at idx: %d\n", i); 2312 + ret = -EINVAL; 2313 + } 2338 2314 } 2315 + 2339 2316 mutex_unlock(&dpu_enc->enc_lock); 2340 2317 2341 2318 return ret;
+24 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 4 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 4 5 * Copyright (C) 2013 Red Hat 5 6 * Author: Rob Clark <robdclark@gmail.com> ··· 22 21 /** 23 22 * struct msm_display_info - defines display properties 24 23 * @intf_type: DRM_MODE_ENCODER_ type 25 - * @capabilities: Bitmask of display flags 26 24 * @num_of_h_tiles: Number of horizontal tiles in case of split interface 27 25 * @h_tile_instance: Controller instance used per tile. Number of elements is 28 26 * based on num_of_h_tiles 27 + * @is_cmd_mode Boolean to indicate if the CMD mode is requested 29 28 * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is 30 29 * used instead of panel TE in cmd mode panels 31 30 * @dsc: DSC configuration data for DSC-enabled displays 32 31 */ 33 32 struct msm_display_info { 34 33 int intf_type; 35 - uint32_t capabilities; 36 34 uint32_t num_of_h_tiles; 37 35 uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; 36 + bool is_cmd_mode; 38 37 bool is_te_using_watchdog_timer; 39 38 struct msm_display_dsc_config *dsc; 40 39 }; ··· 174 173 int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc); 175 174 176 175 bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc); 176 + 177 + /** 178 + * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained 179 + * in virtual encoder that can collect CRC values 180 + * @drm_enc: Pointer to previously created drm encoder structure 181 + * Returns: Number of physical encoders for given drm encoder 182 + */ 183 + int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc); 184 + 185 + /** 186 + * dpu_encoder_setup_misr - enable misr calculations 187 + * @drm_enc: Pointer to previously created drm encoder structure 188 + */ 189 + void dpu_encoder_setup_misr(const struct drm_encoder *drm_encoder); 190 + 191 + /** 192 + * dpu_encoder_get_crc - get the crc value from interface blocks 193 + * @drm_enc: Pointer to previously created drm encoder structure 194 + * Returns: 0 on success, error otherwise 195 + */ 196 + int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos); 177 197 178 198 /** 179 199 * dpu_encoder_use_dsc_merge - returns true if the encoder uses DSC merge topology.
+8 -11
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
··· 14 14 #include "dpu_hw_top.h" 15 15 #include "dpu_hw_wb.h" 16 16 #include "dpu_hw_lm.h" 17 - #include "dpu_hw_blk.h" 18 17 #include "dpu_hw_merge3d.h" 19 18 #include "dpu_hw_interrupts.h" 20 19 #include "dpu_core_irq.h" 21 20 #include "dpu_vbif.h" 22 21 #include "dpu_crtc.h" 23 22 #include "disp/msm_disp_snapshot.h" 24 - 25 - #define DEFAULT_MAX_WRITEBACK_WIDTH 2048 26 23 27 24 #define to_dpu_encoder_phys_wb(x) \ 28 25 container_of(x, struct dpu_encoder_phys_wb, base) ··· 102 105 { 103 106 struct dpu_hw_wb *hw_wb; 104 107 struct dpu_hw_wb_qos_cfg qos_cfg; 105 - struct dpu_mdss_cfg *catalog; 106 - struct dpu_qos_lut_tbl *qos_lut_tb; 108 + const struct dpu_mdss_cfg *catalog; 109 + const struct dpu_qos_lut_tbl *qos_lut_tb; 107 110 108 111 if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) { 109 112 DPU_ERROR("invalid parameter(s)\n"); ··· 117 120 memset(&qos_cfg, 0, sizeof(struct dpu_hw_wb_qos_cfg)); 118 121 qos_cfg.danger_safe_en = true; 119 122 qos_cfg.danger_lut = 120 - catalog->perf.danger_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 123 + catalog->perf->danger_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 121 124 122 - qos_cfg.safe_lut = catalog->perf.safe_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 125 + qos_cfg.safe_lut = catalog->perf->safe_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 123 126 124 - qos_lut_tb = &catalog->perf.qos_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 127 + qos_lut_tb = &catalog->perf->qos_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; 125 128 qos_cfg.creq_lut = _dpu_hw_get_qos_lut(qos_lut_tb, 0); 126 129 127 130 if (hw_wb->ops.setup_qos_lut) ··· 165 168 if (hw_wb->ops.setup_cdp) { 166 169 memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg)); 167 170 168 - cdp_cfg.enable = phys_enc->dpu_kms->catalog->perf.cdp_cfg 171 + cdp_cfg.enable = phys_enc->dpu_kms->catalog->perf->cdp_cfg 169 172 [DPU_PERF_CDP_USAGE_NRT].wr_enable; 170 173 cdp_cfg.ubwc_meta_enable = 171 174 DPU_FORMAT_IS_UBWC(wb_cfg->dest.format); ··· 277 280 DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, 278 281 mode->vdisplay); 279 282 return -EINVAL; 280 - } else if (fb->width > DEFAULT_MAX_WRITEBACK_WIDTH) { 283 + } else if (fb->width > phys_enc->hw_wb->caps->maxlinewidth) { 281 284 DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n", 282 - fb->width, DEFAULT_MAX_WRITEBACK_WIDTH); 285 + fb->width, phys_enc->hw_wb->caps->maxlinewidth); 283 286 return -EINVAL; 284 287 } 285 288
-25
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. 3 - */ 4 - 5 - #ifndef _DPU_HW_BLK_H 6 - #define _DPU_HW_BLK_H 7 - 8 - #include <linux/types.h> 9 - #include <linux/list.h> 10 - 11 - struct dpu_hw_blk; 12 - 13 - 14 - /** 15 - * struct dpu_hw_blk - definition of hardware block object 16 - * @list: list of hardware blocks 17 - * @type: hardware block type 18 - * @id: instance id 19 - * @refcount: reference/usage count 20 - */ 21 - struct dpu_hw_blk { 22 - /* opaque */ 23 - }; 24 - 25 - #endif /*_DPU_HW_BLK_H */
+230 -282
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
··· 50 50 #define DMA_CURSOR_MSM8998_MASK \ 51 51 (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR)) 52 52 53 - #define MIXER_SDM845_MASK \ 53 + #define MIXER_MSM8998_MASK \ 54 54 (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER)) 55 55 56 + #define MIXER_SDM845_MASK \ 57 + (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) 58 + 56 59 #define MIXER_SC7180_MASK \ 57 - (BIT(DPU_DIM_LAYER)) 60 + (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) 58 61 59 62 #define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER) 60 63 ··· 939 936 }; 940 937 941 938 static const struct dpu_lm_cfg msm8998_lm[] = { 942 - LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, 939 + LM_BLK("lm_0", LM_0, 0x44000, MIXER_MSM8998_MASK, 943 940 &msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0), 944 - LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, 941 + LM_BLK("lm_1", LM_1, 0x45000, MIXER_MSM8998_MASK, 945 942 &msm8998_lm_sblk, PINGPONG_1, LM_5, DSPP_1), 946 - LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, 943 + LM_BLK("lm_2", LM_2, 0x46000, MIXER_MSM8998_MASK, 947 944 &msm8998_lm_sblk, PINGPONG_2, LM_0, 0), 948 - LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, 945 + LM_BLK("lm_3", LM_3, 0x47000, MIXER_MSM8998_MASK, 949 946 &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), 950 - LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, 947 + LM_BLK("lm_4", LM_4, 0x48000, MIXER_MSM8998_MASK, 951 948 &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), 952 - LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, 949 + LM_BLK("lm_5", LM_5, 0x49000, MIXER_MSM8998_MASK, 953 950 &msm8998_lm_sblk, PINGPONG_3, LM_1, 0), 954 951 }; 955 952 ··· 1015 1012 1016 1013 static const struct dpu_lm_cfg sc7280_lm[] = { 1017 1014 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK, 1018 - &sc7180_lm_sblk, PINGPONG_0, 0, 0), 1015 + &sc7180_lm_sblk, PINGPONG_0, 0, DSPP_0), 1019 1016 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SC7180_MASK, 1020 1017 &sc7180_lm_sblk, PINGPONG_2, LM_3, 0), 1021 1018 LM_BLK("lm_3", LM_3, 0x47000, MIXER_SC7180_MASK, ··· 1288 1285 * Writeback blocks config 1289 1286 *************************************************************/ 1290 1287 #define WB_BLK(_name, _id, _base, _features, _clk_ctrl, \ 1291 - __xin_id, vbif_id, _reg, _wb_done_bit) \ 1288 + __xin_id, vbif_id, _reg, _max_linewidth, _wb_done_bit) \ 1292 1289 { \ 1293 1290 .name = _name, .id = _id, \ 1294 1291 .base = _base, .len = 0x2c8, \ ··· 1298 1295 .clk_ctrl = _clk_ctrl, \ 1299 1296 .xin_id = __xin_id, \ 1300 1297 .vbif_idx = vbif_id, \ 1301 - .maxlinewidth = DEFAULT_DPU_LINE_WIDTH, \ 1298 + .maxlinewidth = _max_linewidth, \ 1302 1299 .intr_wb_done = DPU_IRQ_IDX(_reg, _wb_done_bit) \ 1303 1300 } 1304 1301 1305 1302 static const struct dpu_wb_cfg sm8250_wb[] = { 1306 1303 WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, 1307 - VBIF_RT, MDP_SSPP_TOP0_INTR, 4), 1304 + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), 1308 1305 }; 1309 1306 1310 1307 /************************************************************* ··· 1339 1336 .default_ot_wr_limit = 32, 1340 1337 .features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM), 1341 1338 .xin_halt_timeout = 0x4000, 1339 + .qos_rp_remap_size = 0x20, 1342 1340 .dynamic_ot_rd_tbl = { 1343 1341 .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), 1344 1342 .cfg = msm8998_ot_rdwr_cfg, ··· 1367 1363 .base = 0, .len = 0x1040, 1368 1364 .features = BIT(DPU_VBIF_QOS_REMAP), 1369 1365 .xin_halt_timeout = 0x4000, 1366 + .qos_rp_remap_size = 0x40, 1370 1367 .qos_rt_tbl = { 1371 1368 .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl), 1372 1369 .priority_lvl = sdm845_rt_pri_lvl, ··· 1722 1717 .bw_inefficiency_factor = 120, 1723 1718 }; 1724 1719 /************************************************************* 1725 - * Hardware catalog init 1720 + * Hardware catalog 1726 1721 *************************************************************/ 1727 1722 1728 - /* 1729 - * msm8998_cfg_init(): populate sdm845 dpu sub-blocks reg offsets 1730 - * and instance counts. 1731 - */ 1732 - static void msm8998_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1733 - { 1734 - *dpu_cfg = (struct dpu_mdss_cfg){ 1735 - .caps = &msm8998_dpu_caps, 1736 - .mdp_count = ARRAY_SIZE(msm8998_mdp), 1737 - .mdp = msm8998_mdp, 1738 - .ctl_count = ARRAY_SIZE(msm8998_ctl), 1739 - .ctl = msm8998_ctl, 1740 - .sspp_count = ARRAY_SIZE(msm8998_sspp), 1741 - .sspp = msm8998_sspp, 1742 - .mixer_count = ARRAY_SIZE(msm8998_lm), 1743 - .mixer = msm8998_lm, 1744 - .dspp_count = ARRAY_SIZE(msm8998_dspp), 1745 - .dspp = msm8998_dspp, 1746 - .pingpong_count = ARRAY_SIZE(sdm845_pp), 1747 - .pingpong = sdm845_pp, 1748 - .intf_count = ARRAY_SIZE(msm8998_intf), 1749 - .intf = msm8998_intf, 1750 - .vbif_count = ARRAY_SIZE(msm8998_vbif), 1751 - .vbif = msm8998_vbif, 1752 - .reg_dma_count = 0, 1753 - .perf = msm8998_perf_data, 1754 - .mdss_irqs = IRQ_SM8250_MASK, 1755 - }; 1756 - } 1757 - 1758 - /* 1759 - * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets 1760 - * and instance counts. 1761 - */ 1762 - static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1763 - { 1764 - *dpu_cfg = (struct dpu_mdss_cfg){ 1765 - .caps = &sdm845_dpu_caps, 1766 - .mdp_count = ARRAY_SIZE(sdm845_mdp), 1767 - .mdp = sdm845_mdp, 1768 - .ctl_count = ARRAY_SIZE(sdm845_ctl), 1769 - .ctl = sdm845_ctl, 1770 - .sspp_count = ARRAY_SIZE(sdm845_sspp), 1771 - .sspp = sdm845_sspp, 1772 - .mixer_count = ARRAY_SIZE(sdm845_lm), 1773 - .mixer = sdm845_lm, 1774 - .pingpong_count = ARRAY_SIZE(sdm845_pp), 1775 - .pingpong = sdm845_pp, 1776 - .dsc_count = ARRAY_SIZE(sdm845_dsc), 1777 - .dsc = sdm845_dsc, 1778 - .intf_count = ARRAY_SIZE(sdm845_intf), 1779 - .intf = sdm845_intf, 1780 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1781 - .vbif = sdm845_vbif, 1782 - .reg_dma_count = 1, 1783 - .dma_cfg = sdm845_regdma, 1784 - .perf = sdm845_perf_data, 1785 - .mdss_irqs = IRQ_SDM845_MASK, 1786 - }; 1787 - } 1788 - 1789 - /* 1790 - * sc7180_cfg_init(): populate sc7180 dpu sub-blocks reg offsets 1791 - * and instance counts. 1792 - */ 1793 - static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1794 - { 1795 - *dpu_cfg = (struct dpu_mdss_cfg){ 1796 - .caps = &sc7180_dpu_caps, 1797 - .mdp_count = ARRAY_SIZE(sc7180_mdp), 1798 - .mdp = sc7180_mdp, 1799 - .ctl_count = ARRAY_SIZE(sc7180_ctl), 1800 - .ctl = sc7180_ctl, 1801 - .sspp_count = ARRAY_SIZE(sc7180_sspp), 1802 - .sspp = sc7180_sspp, 1803 - .mixer_count = ARRAY_SIZE(sc7180_lm), 1804 - .mixer = sc7180_lm, 1805 - .dspp_count = ARRAY_SIZE(sc7180_dspp), 1806 - .dspp = sc7180_dspp, 1807 - .pingpong_count = ARRAY_SIZE(sc7180_pp), 1808 - .pingpong = sc7180_pp, 1809 - .intf_count = ARRAY_SIZE(sc7180_intf), 1810 - .intf = sc7180_intf, 1811 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1812 - .vbif = sdm845_vbif, 1813 - .reg_dma_count = 1, 1814 - .dma_cfg = sdm845_regdma, 1815 - .perf = sc7180_perf_data, 1816 - .mdss_irqs = IRQ_SC7180_MASK, 1817 - }; 1818 - } 1819 - 1820 - /* 1821 - * sm8150_cfg_init(): populate sm8150 dpu sub-blocks reg offsets 1822 - * and instance counts. 1823 - */ 1824 - static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1825 - { 1826 - *dpu_cfg = (struct dpu_mdss_cfg){ 1827 - .caps = &sm8150_dpu_caps, 1828 - .mdp_count = ARRAY_SIZE(sdm845_mdp), 1829 - .mdp = sdm845_mdp, 1830 - .ctl_count = ARRAY_SIZE(sm8150_ctl), 1831 - .ctl = sm8150_ctl, 1832 - .sspp_count = ARRAY_SIZE(sdm845_sspp), 1833 - .sspp = sdm845_sspp, 1834 - .mixer_count = ARRAY_SIZE(sm8150_lm), 1835 - .mixer = sm8150_lm, 1836 - .dspp_count = ARRAY_SIZE(sm8150_dspp), 1837 - .dspp = sm8150_dspp, 1838 - .pingpong_count = ARRAY_SIZE(sm8150_pp), 1839 - .pingpong = sm8150_pp, 1840 - .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1841 - .merge_3d = sm8150_merge_3d, 1842 - .intf_count = ARRAY_SIZE(sm8150_intf), 1843 - .intf = sm8150_intf, 1844 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1845 - .vbif = sdm845_vbif, 1846 - .reg_dma_count = 1, 1847 - .dma_cfg = sm8150_regdma, 1848 - .perf = sm8150_perf_data, 1849 - .mdss_irqs = IRQ_SDM845_MASK, 1850 - }; 1851 - } 1852 - 1853 - /* 1854 - * sc8180x_cfg_init(): populate sc8180 dpu sub-blocks reg offsets 1855 - * and instance counts. 1856 - */ 1857 - static void sc8180x_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1858 - { 1859 - *dpu_cfg = (struct dpu_mdss_cfg){ 1860 - .caps = &sc8180x_dpu_caps, 1861 - .mdp_count = ARRAY_SIZE(sc8180x_mdp), 1862 - .mdp = sc8180x_mdp, 1863 - .ctl_count = ARRAY_SIZE(sm8150_ctl), 1864 - .ctl = sm8150_ctl, 1865 - .sspp_count = ARRAY_SIZE(sdm845_sspp), 1866 - .sspp = sdm845_sspp, 1867 - .mixer_count = ARRAY_SIZE(sm8150_lm), 1868 - .mixer = sm8150_lm, 1869 - .pingpong_count = ARRAY_SIZE(sm8150_pp), 1870 - .pingpong = sm8150_pp, 1871 - .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1872 - .merge_3d = sm8150_merge_3d, 1873 - .intf_count = ARRAY_SIZE(sc8180x_intf), 1874 - .intf = sc8180x_intf, 1875 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1876 - .vbif = sdm845_vbif, 1877 - .reg_dma_count = 1, 1878 - .dma_cfg = sm8150_regdma, 1879 - .perf = sc8180x_perf_data, 1880 - .mdss_irqs = IRQ_SC8180X_MASK, 1881 - }; 1882 - } 1883 - 1884 - /* 1885 - * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets 1886 - * and instance counts. 1887 - */ 1888 - static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1889 - { 1890 - *dpu_cfg = (struct dpu_mdss_cfg){ 1891 - .caps = &sm8250_dpu_caps, 1892 - .mdp_count = ARRAY_SIZE(sm8250_mdp), 1893 - .mdp = sm8250_mdp, 1894 - .ctl_count = ARRAY_SIZE(sm8150_ctl), 1895 - .ctl = sm8150_ctl, 1896 - .sspp_count = ARRAY_SIZE(sm8250_sspp), 1897 - .sspp = sm8250_sspp, 1898 - .mixer_count = ARRAY_SIZE(sm8150_lm), 1899 - .mixer = sm8150_lm, 1900 - .dspp_count = ARRAY_SIZE(sm8150_dspp), 1901 - .dspp = sm8150_dspp, 1902 - .pingpong_count = ARRAY_SIZE(sm8150_pp), 1903 - .pingpong = sm8150_pp, 1904 - .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1905 - .merge_3d = sm8150_merge_3d, 1906 - .intf_count = ARRAY_SIZE(sm8150_intf), 1907 - .intf = sm8150_intf, 1908 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1909 - .vbif = sdm845_vbif, 1910 - .wb_count = ARRAY_SIZE(sm8250_wb), 1911 - .wb = sm8250_wb, 1912 - .reg_dma_count = 1, 1913 - .dma_cfg = sm8250_regdma, 1914 - .perf = sm8250_perf_data, 1915 - .mdss_irqs = IRQ_SM8250_MASK, 1916 - }; 1917 - } 1918 - 1919 - static void sc7280_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1920 - { 1921 - *dpu_cfg = (struct dpu_mdss_cfg){ 1922 - .caps = &sc7280_dpu_caps, 1923 - .mdp_count = ARRAY_SIZE(sc7280_mdp), 1924 - .mdp = sc7280_mdp, 1925 - .ctl_count = ARRAY_SIZE(sc7280_ctl), 1926 - .ctl = sc7280_ctl, 1927 - .sspp_count = ARRAY_SIZE(sc7280_sspp), 1928 - .sspp = sc7280_sspp, 1929 - .mixer_count = ARRAY_SIZE(sc7280_lm), 1930 - .mixer = sc7280_lm, 1931 - .pingpong_count = ARRAY_SIZE(sc7280_pp), 1932 - .pingpong = sc7280_pp, 1933 - .intf_count = ARRAY_SIZE(sc7280_intf), 1934 - .intf = sc7280_intf, 1935 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1936 - .vbif = sdm845_vbif, 1937 - .perf = sc7280_perf_data, 1938 - .mdss_irqs = IRQ_SC7280_MASK, 1939 - }; 1940 - } 1941 - 1942 - 1943 - /* 1944 - * qcm2290_cfg_init(): populate qcm2290 dpu sub-blocks reg offsets 1945 - * and instance counts. 1946 - */ 1947 - static void qcm2290_cfg_init(struct dpu_mdss_cfg *dpu_cfg) 1948 - { 1949 - *dpu_cfg = (struct dpu_mdss_cfg){ 1950 - .caps = &qcm2290_dpu_caps, 1951 - .mdp_count = ARRAY_SIZE(qcm2290_mdp), 1952 - .mdp = qcm2290_mdp, 1953 - .ctl_count = ARRAY_SIZE(qcm2290_ctl), 1954 - .ctl = qcm2290_ctl, 1955 - .sspp_count = ARRAY_SIZE(qcm2290_sspp), 1956 - .sspp = qcm2290_sspp, 1957 - .mixer_count = ARRAY_SIZE(qcm2290_lm), 1958 - .mixer = qcm2290_lm, 1959 - .dspp_count = ARRAY_SIZE(qcm2290_dspp), 1960 - .dspp = qcm2290_dspp, 1961 - .pingpong_count = ARRAY_SIZE(qcm2290_pp), 1962 - .pingpong = qcm2290_pp, 1963 - .intf_count = ARRAY_SIZE(qcm2290_intf), 1964 - .intf = qcm2290_intf, 1965 - .vbif_count = ARRAY_SIZE(sdm845_vbif), 1966 - .vbif = sdm845_vbif, 1967 - .reg_dma_count = 1, 1968 - .dma_cfg = sdm845_regdma, 1969 - .perf = qcm2290_perf_data, 1970 - .mdss_irqs = IRQ_SC7180_MASK, 1971 - }; 1972 - } 1973 - 1974 - static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = { 1975 - { .hw_rev = DPU_HW_VER_300, .cfg_init = msm8998_cfg_init}, 1976 - { .hw_rev = DPU_HW_VER_301, .cfg_init = msm8998_cfg_init}, 1977 - { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init}, 1978 - { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init}, 1979 - { .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init}, 1980 - { .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init}, 1981 - { .hw_rev = DPU_HW_VER_510, .cfg_init = sc8180x_cfg_init}, 1982 - { .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init}, 1983 - { .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init}, 1984 - { .hw_rev = DPU_HW_VER_650, .cfg_init = qcm2290_cfg_init}, 1985 - { .hw_rev = DPU_HW_VER_720, .cfg_init = sc7280_cfg_init}, 1723 + static const struct dpu_mdss_cfg msm8998_dpu_cfg = { 1724 + .caps = &msm8998_dpu_caps, 1725 + .mdp_count = ARRAY_SIZE(msm8998_mdp), 1726 + .mdp = msm8998_mdp, 1727 + .ctl_count = ARRAY_SIZE(msm8998_ctl), 1728 + .ctl = msm8998_ctl, 1729 + .sspp_count = ARRAY_SIZE(msm8998_sspp), 1730 + .sspp = msm8998_sspp, 1731 + .mixer_count = ARRAY_SIZE(msm8998_lm), 1732 + .mixer = msm8998_lm, 1733 + .dspp_count = ARRAY_SIZE(msm8998_dspp), 1734 + .dspp = msm8998_dspp, 1735 + .pingpong_count = ARRAY_SIZE(sdm845_pp), 1736 + .pingpong = sdm845_pp, 1737 + .intf_count = ARRAY_SIZE(msm8998_intf), 1738 + .intf = msm8998_intf, 1739 + .vbif_count = ARRAY_SIZE(msm8998_vbif), 1740 + .vbif = msm8998_vbif, 1741 + .reg_dma_count = 0, 1742 + .perf = &msm8998_perf_data, 1743 + .mdss_irqs = IRQ_SM8250_MASK, 1986 1744 }; 1987 1745 1988 - void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg) 1989 - { 1990 - kfree(dpu_cfg); 1991 - } 1746 + static const struct dpu_mdss_cfg sdm845_dpu_cfg = { 1747 + .caps = &sdm845_dpu_caps, 1748 + .mdp_count = ARRAY_SIZE(sdm845_mdp), 1749 + .mdp = sdm845_mdp, 1750 + .ctl_count = ARRAY_SIZE(sdm845_ctl), 1751 + .ctl = sdm845_ctl, 1752 + .sspp_count = ARRAY_SIZE(sdm845_sspp), 1753 + .sspp = sdm845_sspp, 1754 + .mixer_count = ARRAY_SIZE(sdm845_lm), 1755 + .mixer = sdm845_lm, 1756 + .pingpong_count = ARRAY_SIZE(sdm845_pp), 1757 + .pingpong = sdm845_pp, 1758 + .dsc_count = ARRAY_SIZE(sdm845_dsc), 1759 + .dsc = sdm845_dsc, 1760 + .intf_count = ARRAY_SIZE(sdm845_intf), 1761 + .intf = sdm845_intf, 1762 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1763 + .vbif = sdm845_vbif, 1764 + .reg_dma_count = 1, 1765 + .dma_cfg = &sdm845_regdma, 1766 + .perf = &sdm845_perf_data, 1767 + .mdss_irqs = IRQ_SDM845_MASK, 1768 + }; 1992 1769 1993 - struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev) 1770 + static const struct dpu_mdss_cfg sc7180_dpu_cfg = { 1771 + .caps = &sc7180_dpu_caps, 1772 + .mdp_count = ARRAY_SIZE(sc7180_mdp), 1773 + .mdp = sc7180_mdp, 1774 + .ctl_count = ARRAY_SIZE(sc7180_ctl), 1775 + .ctl = sc7180_ctl, 1776 + .sspp_count = ARRAY_SIZE(sc7180_sspp), 1777 + .sspp = sc7180_sspp, 1778 + .mixer_count = ARRAY_SIZE(sc7180_lm), 1779 + .mixer = sc7180_lm, 1780 + .dspp_count = ARRAY_SIZE(sc7180_dspp), 1781 + .dspp = sc7180_dspp, 1782 + .pingpong_count = ARRAY_SIZE(sc7180_pp), 1783 + .pingpong = sc7180_pp, 1784 + .intf_count = ARRAY_SIZE(sc7180_intf), 1785 + .intf = sc7180_intf, 1786 + .wb_count = ARRAY_SIZE(sm8250_wb), 1787 + .wb = sm8250_wb, 1788 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1789 + .vbif = sdm845_vbif, 1790 + .reg_dma_count = 1, 1791 + .dma_cfg = &sdm845_regdma, 1792 + .perf = &sc7180_perf_data, 1793 + .mdss_irqs = IRQ_SC7180_MASK, 1794 + }; 1795 + 1796 + static const struct dpu_mdss_cfg sm8150_dpu_cfg = { 1797 + .caps = &sm8150_dpu_caps, 1798 + .mdp_count = ARRAY_SIZE(sdm845_mdp), 1799 + .mdp = sdm845_mdp, 1800 + .ctl_count = ARRAY_SIZE(sm8150_ctl), 1801 + .ctl = sm8150_ctl, 1802 + .sspp_count = ARRAY_SIZE(sdm845_sspp), 1803 + .sspp = sdm845_sspp, 1804 + .mixer_count = ARRAY_SIZE(sm8150_lm), 1805 + .mixer = sm8150_lm, 1806 + .dspp_count = ARRAY_SIZE(sm8150_dspp), 1807 + .dspp = sm8150_dspp, 1808 + .pingpong_count = ARRAY_SIZE(sm8150_pp), 1809 + .pingpong = sm8150_pp, 1810 + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1811 + .merge_3d = sm8150_merge_3d, 1812 + .intf_count = ARRAY_SIZE(sm8150_intf), 1813 + .intf = sm8150_intf, 1814 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1815 + .vbif = sdm845_vbif, 1816 + .reg_dma_count = 1, 1817 + .dma_cfg = &sm8150_regdma, 1818 + .perf = &sm8150_perf_data, 1819 + .mdss_irqs = IRQ_SDM845_MASK, 1820 + }; 1821 + 1822 + static const struct dpu_mdss_cfg sc8180x_dpu_cfg = { 1823 + .caps = &sc8180x_dpu_caps, 1824 + .mdp_count = ARRAY_SIZE(sc8180x_mdp), 1825 + .mdp = sc8180x_mdp, 1826 + .ctl_count = ARRAY_SIZE(sm8150_ctl), 1827 + .ctl = sm8150_ctl, 1828 + .sspp_count = ARRAY_SIZE(sdm845_sspp), 1829 + .sspp = sdm845_sspp, 1830 + .mixer_count = ARRAY_SIZE(sm8150_lm), 1831 + .mixer = sm8150_lm, 1832 + .pingpong_count = ARRAY_SIZE(sm8150_pp), 1833 + .pingpong = sm8150_pp, 1834 + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1835 + .merge_3d = sm8150_merge_3d, 1836 + .intf_count = ARRAY_SIZE(sc8180x_intf), 1837 + .intf = sc8180x_intf, 1838 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1839 + .vbif = sdm845_vbif, 1840 + .reg_dma_count = 1, 1841 + .dma_cfg = &sm8150_regdma, 1842 + .perf = &sc8180x_perf_data, 1843 + .mdss_irqs = IRQ_SC8180X_MASK, 1844 + }; 1845 + 1846 + static const struct dpu_mdss_cfg sm8250_dpu_cfg = { 1847 + .caps = &sm8250_dpu_caps, 1848 + .mdp_count = ARRAY_SIZE(sm8250_mdp), 1849 + .mdp = sm8250_mdp, 1850 + .ctl_count = ARRAY_SIZE(sm8150_ctl), 1851 + .ctl = sm8150_ctl, 1852 + .sspp_count = ARRAY_SIZE(sm8250_sspp), 1853 + .sspp = sm8250_sspp, 1854 + .mixer_count = ARRAY_SIZE(sm8150_lm), 1855 + .mixer = sm8150_lm, 1856 + .dspp_count = ARRAY_SIZE(sm8150_dspp), 1857 + .dspp = sm8150_dspp, 1858 + .pingpong_count = ARRAY_SIZE(sm8150_pp), 1859 + .pingpong = sm8150_pp, 1860 + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), 1861 + .merge_3d = sm8150_merge_3d, 1862 + .intf_count = ARRAY_SIZE(sm8150_intf), 1863 + .intf = sm8150_intf, 1864 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1865 + .vbif = sdm845_vbif, 1866 + .wb_count = ARRAY_SIZE(sm8250_wb), 1867 + .wb = sm8250_wb, 1868 + .reg_dma_count = 1, 1869 + .dma_cfg = &sm8250_regdma, 1870 + .perf = &sm8250_perf_data, 1871 + .mdss_irqs = IRQ_SM8250_MASK, 1872 + }; 1873 + 1874 + static const struct dpu_mdss_cfg sc7280_dpu_cfg = { 1875 + .caps = &sc7280_dpu_caps, 1876 + .mdp_count = ARRAY_SIZE(sc7280_mdp), 1877 + .mdp = sc7280_mdp, 1878 + .ctl_count = ARRAY_SIZE(sc7280_ctl), 1879 + .ctl = sc7280_ctl, 1880 + .sspp_count = ARRAY_SIZE(sc7280_sspp), 1881 + .sspp = sc7280_sspp, 1882 + .dspp_count = ARRAY_SIZE(sc7180_dspp), 1883 + .dspp = sc7180_dspp, 1884 + .mixer_count = ARRAY_SIZE(sc7280_lm), 1885 + .mixer = sc7280_lm, 1886 + .pingpong_count = ARRAY_SIZE(sc7280_pp), 1887 + .pingpong = sc7280_pp, 1888 + .intf_count = ARRAY_SIZE(sc7280_intf), 1889 + .intf = sc7280_intf, 1890 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1891 + .vbif = sdm845_vbif, 1892 + .perf = &sc7280_perf_data, 1893 + .mdss_irqs = IRQ_SC7280_MASK, 1894 + }; 1895 + 1896 + static const struct dpu_mdss_cfg qcm2290_dpu_cfg = { 1897 + .caps = &qcm2290_dpu_caps, 1898 + .mdp_count = ARRAY_SIZE(qcm2290_mdp), 1899 + .mdp = qcm2290_mdp, 1900 + .ctl_count = ARRAY_SIZE(qcm2290_ctl), 1901 + .ctl = qcm2290_ctl, 1902 + .sspp_count = ARRAY_SIZE(qcm2290_sspp), 1903 + .sspp = qcm2290_sspp, 1904 + .mixer_count = ARRAY_SIZE(qcm2290_lm), 1905 + .mixer = qcm2290_lm, 1906 + .dspp_count = ARRAY_SIZE(qcm2290_dspp), 1907 + .dspp = qcm2290_dspp, 1908 + .pingpong_count = ARRAY_SIZE(qcm2290_pp), 1909 + .pingpong = qcm2290_pp, 1910 + .intf_count = ARRAY_SIZE(qcm2290_intf), 1911 + .intf = qcm2290_intf, 1912 + .vbif_count = ARRAY_SIZE(sdm845_vbif), 1913 + .vbif = sdm845_vbif, 1914 + .reg_dma_count = 1, 1915 + .dma_cfg = &sdm845_regdma, 1916 + .perf = &qcm2290_perf_data, 1917 + .mdss_irqs = IRQ_SC7180_MASK, 1918 + }; 1919 + 1920 + static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = { 1921 + { .hw_rev = DPU_HW_VER_300, .dpu_cfg = &msm8998_dpu_cfg}, 1922 + { .hw_rev = DPU_HW_VER_301, .dpu_cfg = &msm8998_dpu_cfg}, 1923 + { .hw_rev = DPU_HW_VER_400, .dpu_cfg = &sdm845_dpu_cfg}, 1924 + { .hw_rev = DPU_HW_VER_401, .dpu_cfg = &sdm845_dpu_cfg}, 1925 + { .hw_rev = DPU_HW_VER_500, .dpu_cfg = &sm8150_dpu_cfg}, 1926 + { .hw_rev = DPU_HW_VER_501, .dpu_cfg = &sm8150_dpu_cfg}, 1927 + { .hw_rev = DPU_HW_VER_510, .dpu_cfg = &sc8180x_dpu_cfg}, 1928 + { .hw_rev = DPU_HW_VER_600, .dpu_cfg = &sm8250_dpu_cfg}, 1929 + { .hw_rev = DPU_HW_VER_620, .dpu_cfg = &sc7180_dpu_cfg}, 1930 + { .hw_rev = DPU_HW_VER_650, .dpu_cfg = &qcm2290_dpu_cfg}, 1931 + { .hw_rev = DPU_HW_VER_720, .dpu_cfg = &sc7280_dpu_cfg}, 1932 + }; 1933 + 1934 + const struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev) 1994 1935 { 1995 1936 int i; 1996 1937 struct dpu_mdss_cfg *dpu_cfg; ··· 1946 1995 return ERR_PTR(-ENOMEM); 1947 1996 1948 1997 for (i = 0; i < ARRAY_SIZE(cfg_handler); i++) { 1949 - if (cfg_handler[i].hw_rev == hw_rev) { 1950 - cfg_handler[i].cfg_init(dpu_cfg); 1951 - dpu_cfg->hwversion = hw_rev; 1952 - return dpu_cfg; 1953 - } 1998 + if (cfg_handler[i].hw_rev == hw_rev) 1999 + return cfg_handler[i].dpu_cfg; 1954 2000 } 1955 2001 1956 2002 DPU_ERROR("unsupported chipset id:%X\n", hw_rev); 1957 - dpu_hw_catalog_deinit(dpu_cfg); 2003 + 1958 2004 return ERR_PTR(-ENODEV); 1959 2005 } 1960 2006
+8 -12
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
··· 145 145 * @DPU_MIXER_SOURCESPLIT Layer mixer supports source-split configuration 146 146 * @DPU_MIXER_GC Gamma correction block 147 147 * @DPU_DIM_LAYER Layer mixer supports dim layer 148 + * @DPU_MIXER_COMBINED_ALPHA Layer mixer has combined alpha register 148 149 * @DPU_MIXER_MAX maximum value 149 150 */ 150 151 enum { ··· 153 152 DPU_MIXER_SOURCESPLIT, 154 153 DPU_MIXER_GC, 155 154 DPU_DIM_LAYER, 155 + DPU_MIXER_COMBINED_ALPHA, 156 156 DPU_MIXER_MAX 157 157 }; 158 158 ··· 709 707 * @ot_rd_limit default OT read limit 710 708 * @ot_wr_limit default OT write limit 711 709 * @xin_halt_timeout maximum time (in usec) for xin to halt 710 + * @qos_rp_remap_size size of VBIF_XINL_QOS_RP_REMAP register space 712 711 * @dynamic_ot_rd_tbl dynamic OT read configuration table 713 712 * @dynamic_ot_wr_tbl dynamic OT write configuration table 714 713 * @qos_rt_tbl real-time QoS priority table ··· 722 719 u32 default_ot_rd_limit; 723 720 u32 default_ot_wr_limit; 724 721 u32 xin_halt_timeout; 722 + u32 qos_rp_remap_size; 725 723 struct dpu_vbif_dynamic_ot_tbl dynamic_ot_rd_tbl; 726 724 struct dpu_vbif_dynamic_ot_tbl dynamic_ot_wr_tbl; 727 725 struct dpu_vbif_qos_tbl qos_rt_tbl; ··· 826 822 * @mdss_irqs: Bitmap with the irqs supported by the target 827 823 */ 828 824 struct dpu_mdss_cfg { 829 - u32 hwversion; 830 - 831 825 const struct dpu_caps *caps; 832 826 833 827 u32 mdp_count; ··· 859 857 const struct dpu_wb_cfg *wb; 860 858 861 859 u32 reg_dma_count; 862 - struct dpu_reg_dma_cfg dma_cfg; 860 + const struct dpu_reg_dma_cfg *dma_cfg; 863 861 864 862 u32 ad_count; 865 863 ··· 868 866 869 867 /* Add additional block data structures here */ 870 868 871 - struct dpu_perf_cfg perf; 869 + const struct dpu_perf_cfg *perf; 872 870 const struct dpu_format_extended *dma_formats; 873 871 const struct dpu_format_extended *cursor_formats; 874 872 const struct dpu_format_extended *vig_formats; ··· 878 876 879 877 struct dpu_mdss_hw_cfg_handler { 880 878 u32 hw_rev; 881 - void (*cfg_init)(struct dpu_mdss_cfg *dpu_cfg); 879 + const struct dpu_mdss_cfg *dpu_cfg; 882 880 }; 883 881 884 882 /** ··· 888 886 * 889 887 * Return: dpu config structure 890 888 */ 891 - struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev); 892 - 893 - /** 894 - * dpu_hw_catalog_deinit - dpu hardware catalog cleanup 895 - * @dpu_cfg: pointer returned from init function 896 - */ 897 - void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg); 889 + const struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev); 898 890 899 891 #endif /* _DPU_HW_CATALOG_H */
+1 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
··· 58 58 59 59 for (i = 0; i < m->ctl_count; i++) { 60 60 if (ctl == m->ctl[i].id) { 61 - b->base_off = addr; 62 - b->blk_off = m->ctl[i].base; 63 - b->length = m->ctl[i].len; 64 - b->hwversion = m->hwversion; 61 + b->blk_addr = addr + m->ctl[i].base; 65 62 b->log_mask = DPU_DBG_MASK_CTL; 66 63 return &m->ctl[i]; 67 64 }
-1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
··· 10 10 #include "dpu_hw_util.h" 11 11 #include "dpu_hw_catalog.h" 12 12 #include "dpu_hw_sspp.h" 13 - #include "dpu_hw_blk.h" 14 13 15 14 /** 16 15 * dpu_ctl_mode_sel: Interface mode selection
+3 -6
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
··· 158 158 } 159 159 160 160 static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc, 161 - struct dpu_mdss_cfg *m, 161 + const struct dpu_mdss_cfg *m, 162 162 void __iomem *addr, 163 163 struct dpu_hw_blk_reg_map *b) 164 164 { ··· 166 166 167 167 for (i = 0; i < m->dsc_count; i++) { 168 168 if (dsc == m->dsc[i].id) { 169 - b->base_off = addr; 170 - b->blk_off = m->dsc[i].base; 171 - b->length = m->dsc[i].len; 172 - b->hwversion = m->hwversion; 169 + b->blk_addr = addr + m->dsc[i].base; 173 170 b->log_mask = DPU_DBG_MASK_DSC; 174 171 return &m->dsc[i]; 175 172 } ··· 184 187 }; 185 188 186 189 struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr, 187 - struct dpu_mdss_cfg *m) 190 + const struct dpu_mdss_cfg *m) 188 191 { 189 192 struct dpu_hw_dsc *c; 190 193 struct dpu_dsc_cfg *cfg;
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
··· 64 64 * Returns: Error code or allocated dpu_hw_dsc context 65 65 */ 66 66 struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr, 67 - struct dpu_mdss_cfg *m); 67 + const struct dpu_mdss_cfg *m); 68 68 69 69 /** 70 70 * dpu_hw_dsc_destroy - destroys dsc driver context
+1 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
··· 80 80 81 81 for (i = 0; i < m->dspp_count; i++) { 82 82 if (dspp == m->dspp[i].id) { 83 - b->base_off = addr; 84 - b->blk_off = m->dspp[i].base; 85 - b->length = m->dspp[i].len; 86 - b->hwversion = m->hwversion; 83 + b->blk_addr = addr + m->dspp[i].base; 87 84 b->log_mask = DPU_DBG_MASK_DSPP; 88 85 return &m->dspp[i]; 89 86 }
-2
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h
··· 5 5 #ifndef _DPU_HW_DSPP_H 6 6 #define _DPU_HW_DSPP_H 7 7 8 - #include "dpu_hw_blk.h" 9 - 10 8 struct dpu_hw_dspp; 11 9 12 10 /**
+3 -5
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
··· 398 398 return intr_status; 399 399 } 400 400 401 - static void __intr_offset(struct dpu_mdss_cfg *m, 401 + static void __intr_offset(const struct dpu_mdss_cfg *m, 402 402 void __iomem *addr, struct dpu_hw_blk_reg_map *hw) 403 403 { 404 - hw->base_off = addr; 405 - hw->blk_off = m->mdp[0].base; 406 - hw->hwversion = m->hwversion; 404 + hw->blk_addr = addr + m->mdp[0].base; 407 405 } 408 406 409 407 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, 410 - struct dpu_mdss_cfg *m) 408 + const struct dpu_mdss_cfg *m) 411 409 { 412 410 struct dpu_hw_intr *intr; 413 411 int nirq = MDP_INTR_MAX * 32;
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
··· 67 67 * @m : pointer to mdss catalog data 68 68 */ 69 69 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, 70 - struct dpu_mdss_cfg *m); 70 + const struct dpu_mdss_cfg *m); 71 71 72 72 /** 73 73 * dpu_hw_intr_destroy(): Cleanup interrutps hw object
+19 -5
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 5 */ 4 6 5 7 #include "dpu_hwio.h" ··· 69 67 #define INTF_CFG2_DATABUS_WIDEN BIT(0) 70 68 #define INTF_CFG2_DATA_HCTL_EN BIT(4) 71 69 70 + #define INTF_MISR_CTRL 0x180 71 + #define INTF_MISR_SIGNATURE 0x184 72 + 72 73 static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, 73 74 const struct dpu_mdss_cfg *m, 74 75 void __iomem *addr, ··· 82 77 for (i = 0; i < m->intf_count; i++) { 83 78 if ((intf == m->intf[i].id) && 84 79 (m->intf[i].type != INTF_NONE)) { 85 - b->base_off = addr; 86 - b->blk_off = m->intf[i].base; 87 - b->length = m->intf[i].len; 88 - b->hwversion = m->hwversion; 80 + b->blk_addr = addr + m->intf[i].base; 89 81 b->log_mask = DPU_DBG_MASK_INTF; 90 82 return &m->intf[i]; 91 83 } ··· 321 319 return DPU_REG_READ(c, INTF_LINE_COUNT); 322 320 } 323 321 322 + static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) 323 + { 324 + dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); 325 + } 326 + 327 + static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) 328 + { 329 + return dpu_hw_collect_misr(&intf->hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value); 330 + } 331 + 324 332 static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, 325 333 unsigned long cap) 326 334 { ··· 341 329 ops->get_line_count = dpu_hw_intf_get_line_count; 342 330 if (cap & BIT(DPU_INTF_INPUT_CTRL)) 343 331 ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; 332 + ops->setup_misr = dpu_hw_intf_setup_misr; 333 + ops->collect_misr = dpu_hw_intf_collect_misr; 344 334 } 345 335 346 336 struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
+7 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 5 */ 4 6 5 7 #ifndef _DPU_HW_INTF_H ··· 10 8 #include "dpu_hw_catalog.h" 11 9 #include "dpu_hw_mdss.h" 12 10 #include "dpu_hw_util.h" 13 - #include "dpu_hw_blk.h" 14 11 15 12 struct dpu_hw_intf; 16 13 ··· 58 57 * @ get_line_count: reads current vertical line counter 59 58 * @bind_pingpong_blk: enable/disable the connection with pingpong which will 60 59 * feed pixels to this interface 60 + * @setup_misr: enable/disable MISR 61 + * @collect_misr: read MISR signature 61 62 */ 62 63 struct dpu_hw_intf_ops { 63 64 void (*setup_timing_gen)(struct dpu_hw_intf *intf, ··· 80 77 void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, 81 78 bool enable, 82 79 const enum dpu_pingpong pp); 80 + void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); 81 + int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); 83 82 }; 84 83 85 84 struct dpu_hw_intf {
+7 -46
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 4 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 4 5 */ 5 6 ··· 28 27 29 28 #define LM_MISR_CTRL 0x310 30 29 #define LM_MISR_SIGNATURE 0x314 31 - #define LM_MISR_FRAME_COUNT_MASK 0xFF 32 - #define LM_MISR_CTRL_ENABLE BIT(8) 33 - #define LM_MISR_CTRL_STATUS BIT(9) 34 - #define LM_MISR_CTRL_STATUS_CLEAR BIT(10) 35 - #define LM_MISR_CTRL_FREE_RUN_MASK BIT(31) 36 30 37 31 38 32 static const struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, ··· 39 43 40 44 for (i = 0; i < m->mixer_count; i++) { 41 45 if (mixer == m->mixer[i].id) { 42 - b->base_off = addr; 43 - b->blk_off = m->mixer[i].base; 44 - b->length = m->mixer[i].len; 45 - b->hwversion = m->hwversion; 46 + b->blk_addr = addr + m->mixer[i].base; 46 47 b->log_mask = DPU_DBG_MASK_LM; 47 48 return &m->mixer[i]; 48 49 } ··· 101 108 102 109 static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) 103 110 { 104 - struct dpu_hw_blk_reg_map *c = &ctx->hw; 105 - u32 config = 0; 106 - 107 - DPU_REG_WRITE(c, LM_MISR_CTRL, LM_MISR_CTRL_STATUS_CLEAR); 108 - 109 - /* Clear old MISR value (in case it's read before a new value is calculated)*/ 110 - wmb(); 111 - 112 - if (enable) { 113 - config = (frame_count & LM_MISR_FRAME_COUNT_MASK) | 114 - LM_MISR_CTRL_ENABLE | LM_MISR_CTRL_FREE_RUN_MASK; 115 - 116 - DPU_REG_WRITE(c, LM_MISR_CTRL, config); 117 - } else { 118 - DPU_REG_WRITE(c, LM_MISR_CTRL, 0); 119 - } 120 - 111 + dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); 121 112 } 122 113 123 114 static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) 124 115 { 125 - struct dpu_hw_blk_reg_map *c = &ctx->hw; 126 - u32 ctrl = 0; 127 - 128 - if (!misr_value) 129 - return -EINVAL; 130 - 131 - ctrl = DPU_REG_READ(c, LM_MISR_CTRL); 132 - 133 - if (!(ctrl & LM_MISR_CTRL_ENABLE)) 134 - return -ENODATA; 135 - 136 - if (!(ctrl & LM_MISR_CTRL_STATUS)) 137 - return -EINVAL; 138 - 139 - *misr_value = DPU_REG_READ(c, LM_MISR_SIGNATURE); 140 - 141 - return 0; 116 + return dpu_hw_collect_misr(&ctx->hw, LM_MISR_CTRL, LM_MISR_SIGNATURE, misr_value); 142 117 } 143 118 144 - static void dpu_hw_lm_setup_blend_config_sdm845(struct dpu_hw_mixer *ctx, 119 + static void dpu_hw_lm_setup_blend_config_combined_alpha(struct dpu_hw_mixer *ctx, 145 120 u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op) 146 121 { 147 122 struct dpu_hw_blk_reg_map *c = &ctx->hw; ··· 165 204 unsigned long features) 166 205 { 167 206 ops->setup_mixer_out = dpu_hw_lm_setup_out; 168 - if (m->hwversion >= DPU_HW_VER_400) 169 - ops->setup_blend_config = dpu_hw_lm_setup_blend_config_sdm845; 207 + if (test_bit(DPU_MIXER_COMBINED_ALPHA, &features)) 208 + ops->setup_blend_config = dpu_hw_lm_setup_blend_config_combined_alpha; 170 209 else 171 210 ops->setup_blend_config = dpu_hw_lm_setup_blend_config; 172 211 ops->setup_alpha_out = dpu_hw_lm_setup_color3;
-1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h
··· 8 8 9 9 #include "dpu_hw_mdss.h" 10 10 #include "dpu_hw_util.h" 11 - #include "dpu_hw_blk.h" 12 11 13 12 struct dpu_hw_mixer; 14 13
+1 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c
··· 23 23 24 24 for (i = 0; i < m->merge_3d_count; i++) { 25 25 if (idx == m->merge_3d[i].id) { 26 - b->base_off = addr; 27 - b->blk_off = m->merge_3d[i].base; 28 - b->length = m->merge_3d[i].len; 29 - b->hwversion = m->hwversion; 26 + b->blk_addr = addr + m->merge_3d[i].base; 30 27 b->log_mask = DPU_DBG_MASK_PINGPONG; 31 28 return &m->merge_3d[i]; 32 29 }
-1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h
··· 8 8 #include "dpu_hw_catalog.h" 9 9 #include "dpu_hw_mdss.h" 10 10 #include "dpu_hw_util.h" 11 - #include "dpu_hw_blk.h" 12 11 13 12 struct dpu_hw_merge_3d; 14 13
+2 -5
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
··· 51 51 52 52 for (i = 0; i < m->pingpong_count; i++) { 53 53 if (pp == m->pingpong[i].id) { 54 - b->base_off = addr; 55 - b->blk_off = m->pingpong[i].base; 56 - b->length = m->pingpong[i].len; 57 - b->hwversion = m->hwversion; 54 + b->blk_addr = addr + m->pingpong[i].base; 58 55 b->log_mask = DPU_DBG_MASK_PINGPONG; 59 56 return &m->pingpong[i]; 60 57 } ··· 155 158 return -EINVAL; 156 159 157 160 c = &pp->hw; 158 - rc = readl_poll_timeout(c->base_off + c->blk_off + PP_LINE_COUNT, 161 + rc = readl_poll_timeout(c->blk_addr + PP_LINE_COUNT, 159 162 val, (val & 0xffff) >= 1, 10, timeout_us); 160 163 161 164 return rc;
-1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
··· 8 8 #include "dpu_hw_catalog.h" 9 9 #include "dpu_hw_mdss.h" 10 10 #include "dpu_hw_util.h" 11 - #include "dpu_hw_blk.h" 12 11 13 12 #define DITHER_MATRIX_SZ 16 14 13
+3 -6
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
··· 761 761 762 762 static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp, 763 763 void __iomem *addr, 764 - struct dpu_mdss_cfg *catalog, 764 + const struct dpu_mdss_cfg *catalog, 765 765 struct dpu_hw_blk_reg_map *b) 766 766 { 767 767 int i; ··· 769 769 if ((sspp < SSPP_MAX) && catalog && addr && b) { 770 770 for (i = 0; i < catalog->sspp_count; i++) { 771 771 if (sspp == catalog->sspp[i].id) { 772 - b->base_off = addr; 773 - b->blk_off = catalog->sspp[i].base; 774 - b->length = catalog->sspp[i].len; 775 - b->hwversion = catalog->hwversion; 772 + b->blk_addr = addr + catalog->sspp[i].base; 776 773 b->log_mask = DPU_DBG_MASK_SSPP; 777 774 return &catalog->sspp[i]; 778 775 } ··· 780 783 } 781 784 782 785 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, 783 - void __iomem *addr, struct dpu_mdss_cfg *catalog, 786 + void __iomem *addr, const struct dpu_mdss_cfg *catalog, 784 787 bool is_virtual_pipe) 785 788 { 786 789 struct dpu_hw_pipe *hw_pipe;
+2 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
··· 8 8 #include "dpu_hw_catalog.h" 9 9 #include "dpu_hw_mdss.h" 10 10 #include "dpu_hw_util.h" 11 - #include "dpu_hw_blk.h" 12 11 #include "dpu_formats.h" 13 12 14 13 struct dpu_hw_pipe; ··· 359 360 struct dpu_hw_pipe { 360 361 struct dpu_hw_blk base; 361 362 struct dpu_hw_blk_reg_map hw; 362 - struct dpu_mdss_cfg *catalog; 363 + const struct dpu_mdss_cfg *catalog; 363 364 const struct dpu_mdp_cfg *mdp; 364 365 365 366 /* Pipe */ ··· 380 381 * @is_virtual_pipe: is this pipe virtual pipe 381 382 */ 382 383 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, 383 - void __iomem *addr, struct dpu_mdss_cfg *catalog, 384 + void __iomem *addr, const struct dpu_mdss_cfg *catalog, 384 385 bool is_virtual_pipe); 385 386 386 387 /**
+1 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
··· 285 285 286 286 for (i = 0; i < m->mdp_count; i++) { 287 287 if (mdp == m->mdp[i].id) { 288 - b->base_off = addr; 289 - b->blk_off = m->mdp[i].base; 290 - b->length = m->mdp[i].len; 291 - b->hwversion = m->hwversion; 288 + b->blk_addr = addr + m->mdp[i].base; 292 289 b->log_mask = DPU_DBG_MASK_TOP; 293 290 return &m->mdp[i]; 294 291 }
-1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h
··· 8 8 #include "dpu_hw_catalog.h" 9 9 #include "dpu_hw_mdss.h" 10 10 #include "dpu_hw_util.h" 11 - #include "dpu_hw_blk.h" 12 11 13 12 struct dpu_hw_mdp; 14 13
+51 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 5 */ 4 6 #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ 5 7 ··· 82 80 /* don't need to mutex protect this */ 83 81 if (c->log_mask & dpu_hw_util_log_mask) 84 82 DPU_DEBUG_DRIVER("[%s:0x%X] <= 0x%X\n", 85 - name, c->blk_off + reg_off, val); 86 - writel_relaxed(val, c->base_off + c->blk_off + reg_off); 83 + name, reg_off, val); 84 + writel_relaxed(val, c->blk_addr + reg_off); 87 85 } 88 86 89 87 int dpu_reg_read(struct dpu_hw_blk_reg_map *c, u32 reg_off) 90 88 { 91 - return readl_relaxed(c->base_off + c->blk_off + reg_off); 89 + return readl_relaxed(c->blk_addr + reg_off); 92 90 } 93 91 94 92 u32 *dpu_hw_util_get_log_mask_ptr(void) ··· 446 444 /* if last fl is zero, use as default */ 447 445 if (!tbl->entries[i-1].fl) 448 446 return tbl->entries[i-1].lut; 447 + 448 + return 0; 449 + } 450 + 451 + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, 452 + u32 misr_ctrl_offset, 453 + bool enable, u32 frame_count) 454 + { 455 + u32 config = 0; 456 + 457 + DPU_REG_WRITE(c, misr_ctrl_offset, MISR_CTRL_STATUS_CLEAR); 458 + 459 + /* Clear old MISR value (in case it's read before a new value is calculated)*/ 460 + wmb(); 461 + 462 + if (enable) { 463 + config = (frame_count & MISR_FRAME_COUNT_MASK) | 464 + MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; 465 + 466 + DPU_REG_WRITE(c, misr_ctrl_offset, config); 467 + } else { 468 + DPU_REG_WRITE(c, misr_ctrl_offset, 0); 469 + } 470 + 471 + } 472 + 473 + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, 474 + u32 misr_ctrl_offset, 475 + u32 misr_signature_offset, 476 + u32 *misr_value) 477 + { 478 + u32 ctrl = 0; 479 + 480 + if (!misr_value) 481 + return -EINVAL; 482 + 483 + ctrl = DPU_REG_READ(c, misr_ctrl_offset); 484 + 485 + if (!(ctrl & MISR_CTRL_ENABLE)) 486 + return -ENODATA; 487 + 488 + if (!(ctrl & MISR_CTRL_STATUS)) 489 + return -EINVAL; 490 + 491 + *misr_value = DPU_REG_READ(c, misr_signature_offset); 449 492 450 493 return 0; 451 494 }
+26 -10
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 4 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 4 5 */ 5 6 ··· 13 12 #include "dpu_hw_catalog.h" 14 13 15 14 #define REG_MASK(n) ((BIT(n)) - 1) 15 + #define MISR_FRAME_COUNT_MASK 0xFF 16 + #define MISR_CTRL_ENABLE BIT(8) 17 + #define MISR_CTRL_STATUS BIT(9) 18 + #define MISR_CTRL_STATUS_CLEAR BIT(10) 19 + #define MISR_CTRL_FREE_RUN_MASK BIT(31) 16 20 17 21 /* 18 22 * This is the common struct maintained by each sub block 19 23 * for mapping the register offsets in this block to the 20 24 * absoulute IO address 21 - * @base_off: mdp register mapped offset 22 - * @blk_off: pipe offset relative to mdss offset 23 - * @length length of register block offset 24 - * @xin_id xin id 25 - * @hwversion mdss hw version number 25 + * @blk_addr: hw block register mapped address 26 + * @log_mask: log mask for this block 26 27 */ 27 28 struct dpu_hw_blk_reg_map { 28 - void __iomem *base_off; 29 - u32 blk_off; 30 - u32 length; 31 - u32 xin_id; 32 - u32 hwversion; 29 + void __iomem *blk_addr; 33 30 u32 log_mask; 31 + }; 32 + 33 + /** 34 + * struct dpu_hw_blk - opaque hardware block object 35 + */ 36 + struct dpu_hw_blk { 37 + /* opaque */ 34 38 }; 35 39 36 40 /** ··· 348 342 349 343 u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, 350 344 u32 total_fl); 345 + 346 + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, 347 + u32 misr_ctrl_offset, 348 + bool enable, 349 + u32 frame_count); 350 + 351 + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, 352 + u32 misr_ctrl_offset, 353 + u32 misr_signature_offset, 354 + u32 *misr_value); 351 355 352 356 #endif /* _DPU_HW_UTIL_H */
+3 -6
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c
··· 30 30 #define VBIF_XIN_HALT_CTRL0 0x0200 31 31 #define VBIF_XIN_HALT_CTRL1 0x0204 32 32 #define VBIF_XINL_QOS_RP_REMAP_000 0x0550 33 - #define VBIF_XINL_QOS_LVL_REMAP_000(v) (v < DPU_HW_VER_400 ? 0x570 : 0x0590) 33 + #define VBIF_XINL_QOS_LVL_REMAP_000(vbif) (VBIF_XINL_QOS_RP_REMAP_000 + (vbif)->cap->qos_rp_remap_size) 34 34 35 35 static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif, 36 36 u32 *pnd_errors, u32 *src_errors) ··· 163 163 164 164 c = &vbif->hw; 165 165 166 - reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(c->hwversion); 166 + reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(vbif); 167 167 reg_high = ((xin_id & 0x8) >> 3) * 4 + (level * 8); 168 168 reg_shift = (xin_id & 0x7) * 4; 169 169 ··· 220 220 221 221 for (i = 0; i < m->vbif_count; i++) { 222 222 if (vbif == m->vbif[i].id) { 223 - b->base_off = addr; 224 - b->blk_off = m->vbif[i].base; 225 - b->length = m->vbif[i].len; 226 - b->hwversion = m->hwversion; 223 + b->blk_addr = addr + m->vbif[i].base; 227 224 b->log_mask = DPU_DBG_MASK_VBIF; 228 225 return &m->vbif[i]; 229 226 }
+1 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
··· 60 60 61 61 for (i = 0; i < m->wb_count; i++) { 62 62 if (wb == m->wb[i].id) { 63 - b->base_off = addr; 64 - b->blk_off = m->wb[i].base; 65 - b->length = m->wb[i].len; 66 - b->hwversion = m->hwversion; 63 + b->blk_addr = addr + m->wb[i].base; 67 64 return &m->wb[i]; 68 65 } 69 66 }
+8 -31
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
··· 583 583 } 584 584 585 585 info.h_tile_instance[info.num_of_h_tiles++] = i; 586 - info.capabilities = msm_dsi_is_cmd_mode(priv->dsi[i]) ? 587 - MSM_DISPLAY_CAP_CMD_MODE : 588 - MSM_DISPLAY_CAP_VID_MODE; 586 + info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]); 589 587 590 588 info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]); 591 589 ··· 636 638 637 639 info.num_of_h_tiles = 1; 638 640 info.h_tile_instance[0] = i; 639 - info.capabilities = MSM_DISPLAY_CAP_VID_MODE; 640 641 info.intf_type = encoder->encoder_type; 641 642 rc = dpu_encoder_setup(dev, encoder, &info); 642 643 if (rc) { ··· 743 746 unsigned int num_encoders; 744 747 745 748 struct msm_drm_private *priv; 746 - struct dpu_mdss_cfg *catalog; 749 + const struct dpu_mdss_cfg *catalog; 747 750 748 751 int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; 749 752 int max_crtc_count; ··· 840 843 dpu_rm_destroy(&dpu_kms->rm); 841 844 dpu_kms->rm_init = false; 842 845 843 - if (dpu_kms->catalog) 844 - dpu_hw_catalog_deinit(dpu_kms->catalog); 845 846 dpu_kms->catalog = NULL; 846 847 847 848 if (dpu_kms->vbif[VBIF_NRT]) ··· 901 906 { 902 907 int i; 903 908 struct dpu_kms *dpu_kms; 904 - struct dpu_mdss_cfg *cat; 909 + const struct dpu_mdss_cfg *cat; 905 910 struct dpu_hw_mdp *top; 906 911 907 912 dpu_kms = to_dpu_kms(kms); ··· 946 951 msm_disp_snapshot_add_block(disp_state, cat->wb[i].len, 947 952 dpu_kms->mmio + cat->wb[i].base, "wb_%d", i); 948 953 949 - msm_disp_snapshot_add_block(disp_state, top->hw.length, 950 - dpu_kms->mmio + top->hw.blk_off, "top"); 954 + msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len, 955 + dpu_kms->mmio + cat->mdp[0].base, "top"); 951 956 952 957 pm_runtime_put_sync(&dpu_kms->pdev->dev); 953 958 } ··· 993 998 994 999 static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) 995 1000 { 996 - struct iommu_domain *domain; 997 1001 struct msm_gem_address_space *aspace; 998 - struct msm_mmu *mmu; 999 - struct device *dpu_dev = dpu_kms->dev->dev; 1000 - struct device *mdss_dev = dpu_dev->parent; 1001 1002 1002 - domain = iommu_domain_alloc(&platform_bus_type); 1003 - if (!domain) 1004 - return 0; 1005 - 1006 - /* IOMMUs are a part of MDSS device tree binding, not the 1007 - * MDP/DPU device. */ 1008 - mmu = msm_iommu_new(mdss_dev, domain); 1009 - if (IS_ERR(mmu)) { 1010 - iommu_domain_free(domain); 1011 - return PTR_ERR(mmu); 1012 - } 1013 - aspace = msm_gem_address_space_create(mmu, "dpu1", 1014 - 0x1000, 0x100000000 - 0x1000); 1015 - 1016 - if (IS_ERR(aspace)) { 1017 - mmu->funcs->destroy(mmu); 1003 + aspace = msm_kms_init_aspace(dpu_kms->dev); 1004 + if (IS_ERR(aspace)) 1018 1005 return PTR_ERR(aspace); 1019 - } 1020 1006 1021 1007 dpu_kms->base.aspace = aspace; 1008 + 1022 1009 return 0; 1023 1010 } 1024 1011
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
··· 69 69 struct msm_kms base; 70 70 struct drm_device *dev; 71 71 int core_rev; 72 - struct dpu_mdss_cfg *catalog; 72 + const struct dpu_mdss_cfg *catalog; 73 73 74 74 /* io/register spaces: */ 75 75 void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma;
+10 -10
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
··· 108 108 bool is_rt_pipe; 109 109 bool is_virtual; 110 110 struct list_head mplane_list; 111 - struct dpu_mdss_cfg *catalog; 111 + const struct dpu_mdss_cfg *catalog; 112 112 }; 113 113 114 114 static const uint64_t supported_format_modifiers[] = { ··· 162 162 vbp = mode->vtotal - mode->vsync_end; 163 163 vpw = mode->vsync_end - mode->vsync_start; 164 164 vfp = mode->vsync_start - mode->vdisplay; 165 - hw_latency_lines = dpu_kms->catalog->perf.min_prefill_lines; 165 + hw_latency_lines = dpu_kms->catalog->perf->min_prefill_lines; 166 166 scale_factor = src_height > dst_height ? 167 167 mult_frac(src_height, 1, dst_height) : 1; 168 168 ··· 311 311 } 312 312 313 313 qos_lut = _dpu_hw_get_qos_lut( 314 - &pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl); 314 + &pdpu->catalog->perf->qos_lut_tbl[lut_usage], total_fl); 315 315 316 316 trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0, 317 317 (fmt) ? fmt->base.pixel_format : 0, ··· 338 338 u32 danger_lut, safe_lut; 339 339 340 340 if (!pdpu->is_rt_pipe) { 341 - danger_lut = pdpu->catalog->perf.danger_lut_tbl 341 + danger_lut = pdpu->catalog->perf->danger_lut_tbl 342 342 [DPU_QOS_LUT_USAGE_NRT]; 343 - safe_lut = pdpu->catalog->perf.safe_lut_tbl 343 + safe_lut = pdpu->catalog->perf->safe_lut_tbl 344 344 [DPU_QOS_LUT_USAGE_NRT]; 345 345 } else { 346 346 fmt = dpu_get_dpu_format_ext( ··· 348 348 fb->modifier); 349 349 350 350 if (fmt && DPU_FORMAT_IS_LINEAR(fmt)) { 351 - danger_lut = pdpu->catalog->perf.danger_lut_tbl 351 + danger_lut = pdpu->catalog->perf->danger_lut_tbl 352 352 [DPU_QOS_LUT_USAGE_LINEAR]; 353 - safe_lut = pdpu->catalog->perf.safe_lut_tbl 353 + safe_lut = pdpu->catalog->perf->safe_lut_tbl 354 354 [DPU_QOS_LUT_USAGE_LINEAR]; 355 355 } else { 356 - danger_lut = pdpu->catalog->perf.danger_lut_tbl 356 + danger_lut = pdpu->catalog->perf->danger_lut_tbl 357 357 [DPU_QOS_LUT_USAGE_MACROTILE]; 358 - safe_lut = pdpu->catalog->perf.safe_lut_tbl 358 + safe_lut = pdpu->catalog->perf->safe_lut_tbl 359 359 [DPU_QOS_LUT_USAGE_MACROTILE]; 360 360 } 361 361 } ··· 1227 1227 1228 1228 memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg)); 1229 1229 1230 - cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg 1230 + cdp_cfg.enable = pdpu->catalog->perf->cdp_cfg 1231 1231 [DPU_PERF_CDP_USAGE_RT].rd_enable; 1232 1232 cdp_cfg.ubwc_meta_enable = 1233 1233 DPU_FORMAT_IS_UBWC(fmt);
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
··· 95 95 } 96 96 97 97 int dpu_rm_init(struct dpu_rm *rm, 98 - struct dpu_mdss_cfg *cat, 98 + const struct dpu_mdss_cfg *cat, 99 99 void __iomem *mmio) 100 100 { 101 101 int rc, i;
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
··· 42 42 * @Return: 0 on Success otherwise -ERROR 43 43 */ 44 44 int dpu_rm_init(struct dpu_rm *rm, 45 - struct dpu_mdss_cfg *cat, 45 + const struct dpu_mdss_cfg *cat, 46 46 void __iomem *mmio); 47 47 48 48 /**
+10 -19
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
··· 13 13 #include "msm_mmu.h" 14 14 #include "mdp4_kms.h" 15 15 16 - static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev); 17 - 18 16 static int mdp4_hw_init(struct msm_kms *kms) 19 17 { 20 18 struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); ··· 384 386 static int mdp4_kms_init(struct drm_device *dev) 385 387 { 386 388 struct platform_device *pdev = to_platform_device(dev->dev); 387 - struct mdp4_platform_config *config = mdp4_get_config(pdev); 388 389 struct msm_drm_private *priv = dev->dev_private; 389 390 struct mdp4_kms *mdp4_kms; 390 391 struct msm_kms *kms = NULL; 392 + struct iommu_domain *iommu; 391 393 struct msm_gem_address_space *aspace; 392 394 int irq, ret; 393 395 u32 major, minor; 396 + unsigned long max_clk; 397 + 398 + /* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */ 399 + max_clk = 266667000; 394 400 395 401 mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); 396 402 if (!mdp4_kms) { ··· 462 460 goto fail; 463 461 } 464 462 465 - clk_set_rate(mdp4_kms->clk, config->max_clk); 463 + clk_set_rate(mdp4_kms->clk, max_clk); 466 464 467 465 read_mdp_hw_revision(mdp4_kms, &major, &minor); 468 466 ··· 482 480 ret = PTR_ERR(mdp4_kms->lut_clk); 483 481 goto fail; 484 482 } 485 - clk_set_rate(mdp4_kms->lut_clk, config->max_clk); 483 + clk_set_rate(mdp4_kms->lut_clk, max_clk); 486 484 } 487 485 488 486 pm_runtime_enable(dev->dev); ··· 499 497 mdp4_disable(mdp4_kms); 500 498 mdelay(16); 501 499 502 - if (config->iommu) { 503 - struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, 504 - config->iommu); 500 + iommu = iommu_domain_alloc(pdev->dev.bus); 501 + if (iommu) { 502 + struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu); 505 503 506 504 aspace = msm_gem_address_space_create(mmu, 507 505 "mdp4", 0x1000, 0x100000000 - 0x1000); ··· 553 551 mdp4_destroy(kms); 554 552 555 553 return ret; 556 - } 557 - 558 - static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev) 559 - { 560 - static struct mdp4_platform_config config = {}; 561 - 562 - /* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */ 563 - config.max_clk = 266667000; 564 - config.iommu = iommu_domain_alloc(&platform_bus_type); 565 - 566 - return &config; 567 554 } 568 555 569 556 static const struct dev_pm_ops mdp4_pm_ops = {
-6
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h
··· 42 42 }; 43 43 #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base) 44 44 45 - /* platform config data (ie. from DT, or pdata) */ 46 - struct mdp4_platform_config { 47 - struct iommu_domain *iommu; 48 - uint32_t max_clk; 49 - }; 50 - 51 45 static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data) 52 46 { 53 47 msm_writel(data, mdp4_kms->mmio + reg);
+5 -16
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
··· 837 837 [2] = INTF_DSI, 838 838 }, 839 839 }, 840 + .perf = { 841 + .ab_inefficiency = 100, 842 + .ib_inefficiency = 200, 843 + .clk_inefficiency = 105 844 + }, 840 845 .max_clk = 400000000, 841 846 }; 842 847 ··· 1253 1248 { .revision = 3, .config = { .hw = &sdm630_config } }, 1254 1249 }; 1255 1250 1256 - static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev); 1257 - 1258 1251 const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler) 1259 1252 { 1260 1253 return cfg_handler->config.hw; ··· 1277 1274 uint32_t major, uint32_t minor) 1278 1275 { 1279 1276 struct drm_device *dev = mdp5_kms->dev; 1280 - struct platform_device *pdev = to_platform_device(dev->dev); 1281 1277 struct mdp5_cfg_handler *cfg_handler; 1282 1278 const struct mdp5_cfg_handler *cfg_handlers; 1283 - struct mdp5_cfg_platform *pconfig; 1284 1279 int i, ret = 0, num_handlers; 1285 1280 1286 1281 cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL); ··· 1321 1320 cfg_handler->revision = minor; 1322 1321 cfg_handler->config.hw = mdp5_cfg; 1323 1322 1324 - pconfig = mdp5_get_config(pdev); 1325 - memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig)); 1326 - 1327 1323 DBG("MDP5: %s hw config selected", mdp5_cfg->name); 1328 1324 1329 1325 return cfg_handler; ··· 1330 1332 mdp5_cfg_destroy(cfg_handler); 1331 1333 1332 1334 return ERR_PTR(ret); 1333 - } 1334 - 1335 - static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev) 1336 - { 1337 - static struct mdp5_cfg_platform config = {}; 1338 - 1339 - config.iommu = iommu_domain_alloc(&platform_bus_type); 1340 - 1341 - return &config; 1342 1335 }
-6
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
··· 104 104 uint32_t max_clk; 105 105 }; 106 106 107 - /* platform config data (ie. from DT, or pdata) */ 108 - struct mdp5_cfg_platform { 109 - struct iommu_domain *iommu; 110 - }; 111 - 112 107 struct mdp5_cfg { 113 108 const struct mdp5_cfg_hw *hw; 114 - struct mdp5_cfg_platform platform; 115 109 }; 116 110 117 111 struct mdp5_kms;
+6 -25
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
··· 557 557 struct msm_kms *kms; 558 558 struct msm_gem_address_space *aspace; 559 559 int irq, i, ret; 560 - struct device *iommu_dev; 561 560 562 561 ret = mdp5_init(to_platform_device(dev->dev), dev); 563 562 ··· 600 601 } 601 602 mdelay(16); 602 603 603 - if (config->platform.iommu) { 604 - struct msm_mmu *mmu; 605 - 606 - iommu_dev = &pdev->dev; 607 - if (!dev_iommu_fwspec_get(iommu_dev)) 608 - iommu_dev = iommu_dev->parent; 609 - 610 - mmu = msm_iommu_new(iommu_dev, config->platform.iommu); 611 - 612 - aspace = msm_gem_address_space_create(mmu, "mdp5", 613 - 0x1000, 0x100000000 - 0x1000); 614 - 615 - if (IS_ERR(aspace)) { 616 - if (!IS_ERR(mmu)) 617 - mmu->funcs->destroy(mmu); 618 - ret = PTR_ERR(aspace); 619 - goto fail; 620 - } 621 - 622 - kms->aspace = aspace; 623 - } else { 624 - DRM_DEV_INFO(&pdev->dev, 625 - "no iommu, fallback to phys contig buffers for scanout\n"); 626 - aspace = NULL; 604 + aspace = msm_kms_init_aspace(mdp5_kms->dev); 605 + if (IS_ERR(aspace)) { 606 + ret = PTR_ERR(aspace); 607 + goto fail; 627 608 } 609 + 610 + kms->aspace = aspace; 628 611 629 612 pm_runtime_put_sync(&pdev->dev); 630 613
+2 -1
drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
··· 123 123 { 124 124 struct msm_drm_private *priv = s->dev->dev_private; 125 125 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); 126 - struct mdp5_global_state *state = mdp5_get_global_state(s); 126 + struct mdp5_global_state *state; 127 127 struct mdp5_hw_pipe_state *new_state; 128 128 129 129 if (!hwpipe) 130 130 return 0; 131 131 132 + state = mdp5_get_global_state(s); 132 133 if (IS_ERR(state)) 133 134 return PTR_ERR(state); 134 135
-120
drivers/gpu/drm/msm/dp/dp_clk_util.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. 3 - * All rights reserved. 4 - */ 5 - 6 - #include <linux/clk.h> 7 - #include <linux/clk/clk-conf.h> 8 - #include <linux/err.h> 9 - #include <linux/delay.h> 10 - #include <linux/of.h> 11 - 12 - #include <drm/drm_print.h> 13 - 14 - #include "dp_clk_util.h" 15 - 16 - void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk) 17 - { 18 - int i; 19 - 20 - for (i = num_clk - 1; i >= 0; i--) { 21 - if (clk_arry[i].clk) 22 - clk_put(clk_arry[i].clk); 23 - clk_arry[i].clk = NULL; 24 - } 25 - } 26 - 27 - int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk) 28 - { 29 - int i, rc = 0; 30 - 31 - for (i = 0; i < num_clk; i++) { 32 - clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name); 33 - rc = PTR_ERR_OR_ZERO(clk_arry[i].clk); 34 - if (rc) { 35 - DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n", 36 - __builtin_return_address(0), __func__, 37 - clk_arry[i].clk_name, rc); 38 - goto error; 39 - } 40 - } 41 - 42 - return rc; 43 - 44 - error: 45 - for (i--; i >= 0; i--) { 46 - if (clk_arry[i].clk) 47 - clk_put(clk_arry[i].clk); 48 - clk_arry[i].clk = NULL; 49 - } 50 - 51 - return rc; 52 - } 53 - 54 - int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk) 55 - { 56 - int i, rc = 0; 57 - 58 - for (i = 0; i < num_clk; i++) { 59 - if (clk_arry[i].clk) { 60 - if (clk_arry[i].type != DSS_CLK_AHB) { 61 - DEV_DBG("%pS->%s: '%s' rate %ld\n", 62 - __builtin_return_address(0), __func__, 63 - clk_arry[i].clk_name, 64 - clk_arry[i].rate); 65 - rc = clk_set_rate(clk_arry[i].clk, 66 - clk_arry[i].rate); 67 - if (rc) { 68 - DEV_ERR("%pS->%s: %s failed. rc=%d\n", 69 - __builtin_return_address(0), 70 - __func__, 71 - clk_arry[i].clk_name, rc); 72 - break; 73 - } 74 - } 75 - } else { 76 - DEV_ERR("%pS->%s: '%s' is not available\n", 77 - __builtin_return_address(0), __func__, 78 - clk_arry[i].clk_name); 79 - rc = -EPERM; 80 - break; 81 - } 82 - } 83 - 84 - return rc; 85 - } 86 - 87 - int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable) 88 - { 89 - int i, rc = 0; 90 - 91 - if (enable) { 92 - for (i = 0; i < num_clk; i++) { 93 - DEV_DBG("%pS->%s: enable '%s'\n", 94 - __builtin_return_address(0), __func__, 95 - clk_arry[i].clk_name); 96 - rc = clk_prepare_enable(clk_arry[i].clk); 97 - if (rc) 98 - DEV_ERR("%pS->%s: %s en fail. rc=%d\n", 99 - __builtin_return_address(0), 100 - __func__, 101 - clk_arry[i].clk_name, rc); 102 - 103 - if (rc && i) { 104 - msm_dss_enable_clk(&clk_arry[i - 1], 105 - i - 1, false); 106 - break; 107 - } 108 - } 109 - } else { 110 - for (i = num_clk - 1; i >= 0; i--) { 111 - DEV_DBG("%pS->%s: disable '%s'\n", 112 - __builtin_return_address(0), __func__, 113 - clk_arry[i].clk_name); 114 - 115 - clk_disable_unprepare(clk_arry[i].clk); 116 - } 117 - } 118 - 119 - return rc; 120 - }
-38
drivers/gpu/drm/msm/dp/dp_clk_util.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved. 3 - */ 4 - 5 - #ifndef __DP_CLK_UTIL_H__ 6 - #define __DP_CLK_UTIL_H__ 7 - 8 - #include <linux/platform_device.h> 9 - #include <linux/types.h> 10 - 11 - #define DEV_DBG(fmt, args...) pr_debug(fmt, ##args) 12 - #define DEV_INFO(fmt, args...) pr_info(fmt, ##args) 13 - #define DEV_WARN(fmt, args...) pr_warn(fmt, ##args) 14 - #define DEV_ERR(fmt, args...) pr_err(fmt, ##args) 15 - 16 - enum dss_clk_type { 17 - DSS_CLK_AHB, /* no set rate. rate controlled through rpm */ 18 - DSS_CLK_PCLK, 19 - }; 20 - 21 - struct dss_clk { 22 - struct clk *clk; /* clk handle */ 23 - char clk_name[32]; 24 - enum dss_clk_type type; 25 - unsigned long rate; 26 - unsigned long max_rate; 27 - }; 28 - 29 - struct dss_module_power { 30 - unsigned int num_clk; 31 - struct dss_clk *clk_config; 32 - }; 33 - 34 - int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk); 35 - void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk); 36 - int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk); 37 - int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable); 38 - #endif /* __DP_CLK_UTIL_H__ */
+8 -5
drivers/gpu/drm/msm/dp/dp_ctrl.c
··· 1321 1321 enum dp_pm_type module, char *name, unsigned long rate) 1322 1322 { 1323 1323 u32 num = ctrl->parser->mp[module].num_clk; 1324 - struct dss_clk *cfg = ctrl->parser->mp[module].clk_config; 1324 + struct clk_bulk_data *cfg = ctrl->parser->mp[module].clocks; 1325 1325 1326 - while (num && strcmp(cfg->clk_name, name)) { 1326 + while (num && strcmp(cfg->id, name)) { 1327 1327 num--; 1328 1328 cfg++; 1329 1329 } ··· 1332 1332 rate, name); 1333 1333 1334 1334 if (num) 1335 - cfg->rate = rate; 1335 + clk_set_rate(cfg->clk, rate); 1336 1336 else 1337 1337 DRM_ERROR("%s clock doesn't exit to set rate %lu\n", 1338 1338 name, rate); ··· 1349 1349 opts_dp->lanes = ctrl->link->link_params.num_lanes; 1350 1350 opts_dp->link_rate = ctrl->link->link_params.rate / 100; 1351 1351 opts_dp->ssc = drm_dp_max_downspread(dpcd); 1352 - dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link", 1353 - ctrl->link->link_params.rate * 1000); 1354 1352 1355 1353 phy_configure(phy, &dp_io->phy_opts); 1356 1354 phy_power_on(phy); 1357 1355 1356 + dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000); 1358 1357 ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true); 1359 1358 if (ret) 1360 1359 DRM_ERROR("Unable to start link clocks. ret=%d\n", ret); ··· 1461 1462 * link clock might have been adjusted as part of the 1462 1463 * link maintenance. 1463 1464 */ 1465 + dev_pm_opp_set_rate(ctrl->dev, 0); 1464 1466 ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false); 1465 1467 if (ret) { 1466 1468 DRM_ERROR("Failed to disable clocks. ret=%d\n", ret); ··· 1493 1493 1494 1494 dp_catalog_ctrl_reset(ctrl->catalog); 1495 1495 1496 + dev_pm_opp_set_rate(ctrl->dev, 0); 1496 1497 ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false); 1497 1498 if (ret) { 1498 1499 DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret); ··· 1930 1929 } 1931 1930 } 1932 1931 1932 + dev_pm_opp_set_rate(ctrl->dev, 0); 1933 1933 ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false); 1934 1934 if (ret) { 1935 1935 DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret); ··· 1999 1997 if (ret) 2000 1998 DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret); 2001 1999 2000 + dev_pm_opp_set_rate(ctrl->dev, 0); 2002 2001 ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false); 2003 2002 if (ret) { 2004 2003 DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
+34 -66
drivers/gpu/drm/msm/dp/dp_display.c
··· 131 131 size_t num_descs; 132 132 }; 133 133 134 + static const struct msm_dp_desc sc7180_dp_descs[] = { 135 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 136 + }; 137 + 134 138 static const struct msm_dp_config sc7180_dp_cfg = { 135 - .descs = (const struct msm_dp_desc[]) { 136 - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 137 - }, 138 - .num_descs = 1, 139 + .descs = sc7180_dp_descs, 140 + .num_descs = ARRAY_SIZE(sc7180_dp_descs), 141 + }; 142 + 143 + static const struct msm_dp_desc sc7280_dp_descs[] = { 144 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, 145 + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, 139 146 }; 140 147 141 148 static const struct msm_dp_config sc7280_dp_cfg = { 142 - .descs = (const struct msm_dp_desc[]) { 143 - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, 144 - [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, 145 - }, 146 - .num_descs = 2, 149 + .descs = sc7280_dp_descs, 150 + .num_descs = ARRAY_SIZE(sc7280_dp_descs), 151 + }; 152 + 153 + static const struct msm_dp_desc sc8180x_dp_descs[] = { 154 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 155 + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 156 + [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, 147 157 }; 148 158 149 159 static const struct msm_dp_config sc8180x_dp_cfg = { 150 - .descs = (const struct msm_dp_desc[]) { 151 - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 152 - [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 153 - [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, 154 - }, 155 - .num_descs = 3, 160 + .descs = sc8180x_dp_descs, 161 + .num_descs = ARRAY_SIZE(sc8180x_dp_descs), 162 + }; 163 + 164 + static const struct msm_dp_desc sm8350_dp_descs[] = { 165 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 156 166 }; 157 167 158 168 static const struct msm_dp_config sm8350_dp_cfg = { 159 - .descs = (const struct msm_dp_desc[]) { 160 - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 161 - }, 162 - .num_descs = 1, 169 + .descs = sm8350_dp_descs, 170 + .num_descs = ARRAY_SIZE(sm8350_dp_descs), 163 171 }; 164 172 165 173 static const struct of_device_id dp_dt_match[] = { ··· 618 610 return 0; 619 611 }; 620 612 621 - static int dp_display_enable(struct dp_display_private *dp, u32 data); 622 - static int dp_display_disable(struct dp_display_private *dp, u32 data); 623 - 624 613 static void dp_display_handle_plugged_change(struct msm_dp *dp_display, 625 614 bool plugged) 626 615 { ··· 864 859 return 0; 865 860 } 866 861 867 - static int dp_display_prepare(struct msm_dp *dp_display) 868 - { 869 - return 0; 870 - } 871 - 872 - static int dp_display_enable(struct dp_display_private *dp, u32 data) 862 + static int dp_display_enable(struct dp_display_private *dp, bool force_link_train) 873 863 { 874 864 int rc = 0; 875 865 struct msm_dp *dp_display = &dp->dp_display; ··· 875 875 return 0; 876 876 } 877 877 878 - rc = dp_ctrl_on_stream(dp->ctrl, data); 878 + rc = dp_ctrl_on_stream(dp->ctrl, force_link_train); 879 879 if (!rc) 880 880 dp_display->power_on = true; 881 881 ··· 901 901 return 0; 902 902 } 903 903 904 - static int dp_display_disable(struct dp_display_private *dp, u32 data) 904 + static int dp_display_disable(struct dp_display_private *dp) 905 905 { 906 906 struct msm_dp *dp_display = &dp->dp_display; 907 907 ··· 937 937 dp_display->power_on = false; 938 938 939 939 drm_dbg_dp(dp->drm_dev, "sink count: %d\n", dp->link->sink_count); 940 - return 0; 941 - } 942 - 943 - static int dp_display_unprepare(struct msm_dp *dp_display) 944 - { 945 940 return 0; 946 941 } 947 942 ··· 987 992 return MODE_OK; 988 993 989 994 if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) 990 - return MODE_BAD; 995 + return MODE_CLOCK_HIGH; 991 996 992 997 dp_display = container_of(dp, struct dp_display_private, dp_display); 993 998 link_info = &dp_display->panel->link_info; ··· 1455 1460 return 0; 1456 1461 } 1457 1462 1458 - static int dp_pm_prepare(struct device *dev) 1459 - { 1460 - return 0; 1461 - } 1462 - 1463 - static void dp_pm_complete(struct device *dev) 1464 - { 1465 - 1466 - } 1467 - 1468 1463 static const struct dev_pm_ops dp_pm_ops = { 1469 1464 .suspend = dp_pm_suspend, 1470 1465 .resume = dp_pm_resume, 1471 - .prepare = dp_pm_prepare, 1472 - .complete = dp_pm_complete, 1473 1466 }; 1474 1467 1475 1468 static struct platform_driver dp_display_driver = { ··· 1607 1624 return ret; 1608 1625 } 1609 1626 1610 - dp_display->encoder = encoder; 1611 - 1612 1627 ret = dp_display_get_next_bridge(dp_display); 1613 1628 if (ret) 1614 1629 return ret; ··· 1622 1641 1623 1642 priv->bridges[priv->num_bridges++] = dp_display->bridge; 1624 1643 1625 - dp_display->connector = dp_drm_connector_init(dp_display); 1644 + dp_display->connector = dp_drm_connector_init(dp_display, encoder); 1626 1645 if (IS_ERR(dp_display->connector)) { 1627 1646 ret = PTR_ERR(dp_display->connector); 1628 1647 DRM_DEV_ERROR(dev->dev, ··· 1669 1688 return; 1670 1689 } 1671 1690 1672 - rc = dp_display_prepare(dp); 1673 - if (rc) { 1674 - DRM_ERROR("DP display prepare failed, rc=%d\n", rc); 1675 - mutex_unlock(&dp_display->event_mutex); 1676 - return; 1677 - } 1678 - 1679 1691 state = dp_display->hpd_state; 1680 1692 1681 1693 if (state == ST_DISPLAY_OFF) { ··· 1681 1707 rc = dp_display_post_enable(dp); 1682 1708 if (rc) { 1683 1709 DRM_ERROR("DP display post enable failed, rc=%d\n", rc); 1684 - dp_display_disable(dp_display, 0); 1685 - dp_display_unprepare(dp); 1710 + dp_display_disable(dp_display); 1686 1711 } 1687 1712 1688 1713 /* completed connection */ ··· 1706 1733 { 1707 1734 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); 1708 1735 struct msm_dp *dp = dp_bridge->dp_display; 1709 - int rc = 0; 1710 1736 u32 state; 1711 1737 struct dp_display_private *dp_display; 1712 1738 ··· 1722 1750 return; 1723 1751 } 1724 1752 1725 - dp_display_disable(dp_display, 0); 1726 - 1727 - rc = dp_display_unprepare(dp); 1728 - if (rc) 1729 - DRM_ERROR("DP display unprepare failed, rc=%d\n", rc); 1753 + dp_display_disable(dp_display); 1730 1754 1731 1755 state = dp_display->hpd_state; 1732 1756 if (state == ST_DISCONNECT_PENDING) {
-1
drivers/gpu/drm/msm/dp/dp_display.h
··· 15 15 struct device *codec_dev; 16 16 struct drm_bridge *bridge; 17 17 struct drm_connector *connector; 18 - struct drm_encoder *encoder; 19 18 struct drm_bridge *next_bridge; 20 19 bool is_connected; 21 20 bool audio_enabled;
+4 -4
drivers/gpu/drm/msm/dp/dp_drm.c
··· 116 116 } 117 117 118 118 if (dp_display->next_bridge) { 119 - rc = drm_bridge_attach(dp_display->encoder, 119 + rc = drm_bridge_attach(encoder, 120 120 dp_display->next_bridge, bridge, 121 121 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 122 122 if (rc < 0) { ··· 130 130 } 131 131 132 132 /* connector initialization */ 133 - struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display) 133 + struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder) 134 134 { 135 135 struct drm_connector *connector = NULL; 136 136 137 - connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder); 137 + connector = drm_bridge_connector_init(dp_display->drm_dev, encoder); 138 138 if (IS_ERR(connector)) 139 139 return connector; 140 140 141 - drm_connector_attach_encoder(connector, dp_display->encoder); 141 + drm_connector_attach_encoder(connector, encoder); 142 142 143 143 return connector; 144 144 }
+1 -1
drivers/gpu/drm/msm/dp/dp_drm.h
··· 19 19 20 20 #define to_dp_bridge(x) container_of((x), struct msm_dp_bridge, bridge) 21 21 22 - struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display); 22 + struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder); 23 23 struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, 24 24 struct drm_encoder *encoder); 25 25
+15 -28
drivers/gpu/drm/msm/dp/dp_parser.c
··· 160 160 } 161 161 162 162 core_power->num_clk = core_clk_count; 163 - core_power->clk_config = devm_kzalloc(dev, 164 - sizeof(struct dss_clk) * core_power->num_clk, 163 + core_power->clocks = devm_kcalloc(dev, 164 + core_power->num_clk, sizeof(struct clk_bulk_data), 165 165 GFP_KERNEL); 166 - if (!core_power->clk_config) 167 - return -EINVAL; 166 + if (!core_power->clocks) 167 + return -ENOMEM; 168 168 169 169 /* Initialize the CTRL power module */ 170 170 if (ctrl_clk_count == 0) { ··· 173 173 } 174 174 175 175 ctrl_power->num_clk = ctrl_clk_count; 176 - ctrl_power->clk_config = devm_kzalloc(dev, 177 - sizeof(struct dss_clk) * ctrl_power->num_clk, 176 + ctrl_power->clocks = devm_kcalloc(dev, 177 + ctrl_power->num_clk, sizeof(struct clk_bulk_data), 178 178 GFP_KERNEL); 179 - if (!ctrl_power->clk_config) { 179 + if (!ctrl_power->clocks) { 180 180 ctrl_power->num_clk = 0; 181 - return -EINVAL; 181 + return -ENOMEM; 182 182 } 183 183 184 184 /* Initialize the STREAM power module */ ··· 188 188 } 189 189 190 190 stream_power->num_clk = stream_clk_count; 191 - stream_power->clk_config = devm_kzalloc(dev, 192 - sizeof(struct dss_clk) * stream_power->num_clk, 191 + stream_power->clocks = devm_kcalloc(dev, 192 + stream_power->num_clk, sizeof(struct clk_bulk_data), 193 193 GFP_KERNEL); 194 - if (!stream_power->clk_config) { 194 + if (!stream_power->clocks) { 195 195 stream_power->num_clk = 0; 196 - return -EINVAL; 196 + return -ENOMEM; 197 197 } 198 198 199 199 return 0; ··· 232 232 } 233 233 if (dp_parser_check_prefix("core", clk_name) && 234 234 core_clk_index < core_clk_count) { 235 - struct dss_clk *clk = 236 - &core_power->clk_config[core_clk_index]; 237 - strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 238 - clk->type = DSS_CLK_AHB; 235 + core_power->clocks[core_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL); 239 236 core_clk_index++; 240 237 } else if (dp_parser_check_prefix("stream", clk_name) && 241 238 stream_clk_index < stream_clk_count) { 242 - struct dss_clk *clk = 243 - &stream_power->clk_config[stream_clk_index]; 244 - strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 245 - clk->type = DSS_CLK_PCLK; 239 + stream_power->clocks[stream_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL); 246 240 stream_clk_index++; 247 241 } else if (dp_parser_check_prefix("ctrl", clk_name) && 248 242 ctrl_clk_index < ctrl_clk_count) { 249 - struct dss_clk *clk = 250 - &ctrl_power->clk_config[ctrl_clk_index]; 251 - strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 243 + ctrl_power->clocks[ctrl_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL); 252 244 ctrl_clk_index++; 253 - if (dp_parser_check_prefix("ctrl_link", clk_name) || 254 - dp_parser_check_prefix("stream_pixel", clk_name)) 255 - clk->type = DSS_CLK_PCLK; 256 - else 257 - clk->type = DSS_CLK_AHB; 258 245 } 259 246 } 260 247
+5 -1
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 "dp_clk_util.h" 14 13 #include "msm_drv.h" 15 14 16 15 #define DP_LABEL "MDSS DP DISPLAY" ··· 103 104 struct dp_regulator_cfg { 104 105 int num; 105 106 struct dp_reg_entry regs[DP_DEV_REGULATOR_MAX]; 107 + }; 108 + 109 + struct dss_module_power { 110 + unsigned int num_clk; 111 + struct clk_bulk_data *clocks; 106 112 }; 107 113 108 114 /**
+15 -89
drivers/gpu/drm/msm/dp/dp_power.c
··· 106 106 ctrl = &power->parser->mp[DP_CTRL_PM]; 107 107 stream = &power->parser->mp[DP_STREAM_PM]; 108 108 109 - rc = msm_dss_get_clk(dev, core->clk_config, core->num_clk); 109 + rc = devm_clk_bulk_get(dev, core->num_clk, core->clocks); 110 110 if (rc) { 111 111 DRM_ERROR("failed to get %s clk. err=%d\n", 112 112 dp_parser_pm_name(DP_CORE_PM), rc); 113 113 return rc; 114 114 } 115 115 116 - rc = msm_dss_get_clk(dev, ctrl->clk_config, ctrl->num_clk); 116 + rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks); 117 117 if (rc) { 118 118 DRM_ERROR("failed to get %s clk. err=%d\n", 119 119 dp_parser_pm_name(DP_CTRL_PM), rc); 120 - msm_dss_put_clk(core->clk_config, core->num_clk); 121 120 return -ENODEV; 122 121 } 123 122 124 - rc = msm_dss_get_clk(dev, stream->clk_config, stream->num_clk); 123 + rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks); 125 124 if (rc) { 126 125 DRM_ERROR("failed to get %s clk. err=%d\n", 127 126 dp_parser_pm_name(DP_CTRL_PM), rc); 128 - msm_dss_put_clk(core->clk_config, core->num_clk); 129 127 return -ENODEV; 130 - } 131 - 132 - return 0; 133 - } 134 - 135 - static int dp_power_clk_deinit(struct dp_power_private *power) 136 - { 137 - struct dss_module_power *core, *ctrl, *stream; 138 - 139 - core = &power->parser->mp[DP_CORE_PM]; 140 - ctrl = &power->parser->mp[DP_CTRL_PM]; 141 - stream = &power->parser->mp[DP_STREAM_PM]; 142 - 143 - if (!core || !ctrl || !stream) { 144 - DRM_ERROR("invalid power_data\n"); 145 - return -EINVAL; 146 - } 147 - 148 - msm_dss_put_clk(ctrl->clk_config, ctrl->num_clk); 149 - msm_dss_put_clk(core->clk_config, core->num_clk); 150 - msm_dss_put_clk(stream->clk_config, stream->num_clk); 151 - return 0; 152 - } 153 - 154 - static int dp_power_clk_set_link_rate(struct dp_power_private *power, 155 - struct dss_clk *clk_arry, int num_clk, int enable) 156 - { 157 - u32 rate; 158 - int i, rc = 0; 159 - 160 - for (i = 0; i < num_clk; i++) { 161 - if (clk_arry[i].clk) { 162 - if (clk_arry[i].type == DSS_CLK_PCLK) { 163 - if (enable) 164 - rate = clk_arry[i].rate; 165 - else 166 - rate = 0; 167 - 168 - rc = dev_pm_opp_set_rate(power->dev, rate); 169 - if (rc) 170 - break; 171 - } 172 - 173 - } 174 - } 175 - return rc; 176 - } 177 - 178 - static int dp_power_clk_set_rate(struct dp_power_private *power, 179 - enum dp_pm_type module, bool enable) 180 - { 181 - int rc = 0; 182 - struct dss_module_power *mp = &power->parser->mp[module]; 183 - 184 - if (module == DP_CTRL_PM) { 185 - rc = dp_power_clk_set_link_rate(power, mp->clk_config, mp->num_clk, enable); 186 - if (rc) { 187 - DRM_ERROR("failed to set link clks rate\n"); 188 - return rc; 189 - } 190 - } else { 191 - 192 - if (enable) { 193 - rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); 194 - if (rc) { 195 - DRM_ERROR("failed to set clks rate\n"); 196 - return rc; 197 - } 198 - } 199 - } 200 - 201 - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable); 202 - if (rc) { 203 - DRM_ERROR("failed to %d clks, err: %d\n", enable, rc); 204 - return rc; 205 128 } 206 129 207 130 return 0; ··· 157 234 { 158 235 int rc = 0; 159 236 struct dp_power_private *power; 237 + struct dss_module_power *mp; 160 238 161 239 power = container_of(dp_power, struct dp_power_private, dp_power); 162 240 ··· 190 266 if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) { 191 267 drm_dbg_dp(power->drm_dev, 192 268 "Enable core clks before link clks\n"); 269 + mp = &power->parser->mp[DP_CORE_PM]; 193 270 194 - rc = dp_power_clk_set_rate(power, DP_CORE_PM, enable); 271 + rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); 195 272 if (rc) { 196 273 DRM_ERROR("fail to enable clks: %s. err=%d\n", 197 274 dp_parser_pm_name(DP_CORE_PM), rc); ··· 202 277 } 203 278 } 204 279 205 - rc = dp_power_clk_set_rate(power, pm_type, enable); 206 - if (rc) { 207 - DRM_ERROR("failed to '%s' clks for: %s. err=%d\n", 208 - enable ? "enable" : "disable", 209 - dp_parser_pm_name(pm_type), rc); 210 - return rc; 280 + mp = &power->parser->mp[pm_type]; 281 + if (enable) { 282 + rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); 283 + if (rc) { 284 + DRM_ERROR("failed to enable clks, err: %d\n", rc); 285 + return rc; 286 + } 287 + } else { 288 + clk_bulk_disable_unprepare(mp->num_clk, mp->clocks); 211 289 } 212 290 213 291 if (pm_type == DP_CORE_PM) ··· 275 347 276 348 power = container_of(dp_power, struct dp_power_private, dp_power); 277 349 278 - dp_power_clk_deinit(power); 279 350 pm_runtime_disable(&power->pdev->dev); 280 - 281 351 } 282 352 283 353 int dp_power_init(struct dp_power *dp_power, bool flip)
+21 -27
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 1082 1082 1083 1083 static void dsi_sw_reset(struct msm_dsi_host *msm_host) 1084 1084 { 1085 + u32 ctrl; 1086 + 1087 + ctrl = dsi_read(msm_host, REG_DSI_CTRL); 1088 + 1089 + if (ctrl & DSI_CTRL_ENABLE) { 1090 + dsi_write(msm_host, REG_DSI_CTRL, ctrl & ~DSI_CTRL_ENABLE); 1091 + /* 1092 + * dsi controller need to be disabled before 1093 + * clocks turned on 1094 + */ 1095 + wmb(); 1096 + } 1097 + 1085 1098 dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS); 1086 1099 wmb(); /* clocks need to be enabled before reset */ 1087 1100 1101 + /* dsi controller can only be reset while clocks are running */ 1088 1102 dsi_write(msm_host, REG_DSI_RESET, 1); 1089 1103 msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ 1090 1104 dsi_write(msm_host, REG_DSI_RESET, 0); 1105 + wmb(); /* controller out of reset */ 1106 + 1107 + if (ctrl & DSI_CTRL_ENABLE) { 1108 + dsi_write(msm_host, REG_DSI_CTRL, ctrl); 1109 + wmb(); /* make sure dsi controller enabled again */ 1110 + } 1091 1111 } 1092 1112 1093 1113 static void dsi_op_mode_config(struct msm_dsi_host *msm_host, ··· 1500 1480 return len; 1501 1481 } 1502 1482 1503 - static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) 1504 - { 1505 - u32 data0, data1; 1506 - 1507 - data0 = dsi_read(msm_host, REG_DSI_CTRL); 1508 - data1 = data0; 1509 - data1 &= ~DSI_CTRL_ENABLE; 1510 - dsi_write(msm_host, REG_DSI_CTRL, data1); 1511 - /* 1512 - * dsi controller need to be disabled before 1513 - * clocks turned on 1514 - */ 1515 - wmb(); 1516 - 1517 - dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS); 1518 - wmb(); /* make sure clocks enabled */ 1519 - 1520 - /* dsi controller can only be reset while clocks are running */ 1521 - dsi_write(msm_host, REG_DSI_RESET, 1); 1522 - msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ 1523 - dsi_write(msm_host, REG_DSI_RESET, 0); 1524 - wmb(); /* controller out of reset */ 1525 - dsi_write(msm_host, REG_DSI_CTRL, data0); 1526 - wmb(); /* make sure dsi controller enabled again */ 1527 - } 1528 - 1529 1483 static void dsi_hpd_worker(struct work_struct *work) 1530 1484 { 1531 1485 struct msm_dsi_host *msm_host = ··· 1516 1522 1517 1523 pr_err_ratelimited("%s: status=%x\n", __func__, status); 1518 1524 if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW) 1519 - dsi_sw_reset_restore(msm_host); 1525 + dsi_sw_reset(msm_host); 1520 1526 1521 1527 /* It is safe to clear here because error irq is disabled. */ 1522 1528 msm_host->err_work_state = 0;
+37 -89
drivers/gpu/drm/msm/hdmi/hdmi.c
··· 9 9 #include <linux/of_gpio.h> 10 10 11 11 #include <drm/drm_bridge_connector.h> 12 + #include <drm/drm_of.h> 12 13 13 14 #include <sound/hdmi-codec.h> 14 15 #include "hdmi.h" ··· 134 133 hdmi->config = config; 135 134 spin_lock_init(&hdmi->reg_lock); 136 135 136 + ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, &hdmi->next_bridge); 137 + if (ret && ret != -ENODEV) 138 + goto fail; 139 + 137 140 hdmi->mmio = msm_ioremap(pdev, config->mmio_name); 138 141 if (IS_ERR(hdmi->mmio)) { 139 142 ret = PTR_ERR(hdmi->mmio); ··· 184 179 ret = -ENOMEM; 185 180 goto fail; 186 181 } 182 + 183 + for (i = 0; i < config->pwr_reg_cnt; i++) 184 + hdmi->pwr_regs[i].supply = config->pwr_reg_names[i]; 187 185 188 186 ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs); 189 187 if (ret) { ··· 237 229 238 230 hdmi->pwr_clks[i] = clk; 239 231 } 232 + 233 + hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN); 234 + /* This will catch e.g. -EPROBE_DEFER */ 235 + if (IS_ERR(hdmi->hpd_gpiod)) { 236 + ret = PTR_ERR(hdmi->hpd_gpiod); 237 + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd gpio: (%d)\n", ret); 238 + goto fail; 239 + } 240 + 241 + if (!hdmi->hpd_gpiod) 242 + DBG("failed to get HPD gpio"); 243 + 244 + if (hdmi->hpd_gpiod) 245 + gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD"); 240 246 241 247 pm_runtime_enable(&pdev->dev); 242 248 ··· 311 289 DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret); 312 290 hdmi->bridge = NULL; 313 291 goto fail; 292 + } 293 + 294 + if (hdmi->next_bridge) { 295 + ret = drm_bridge_attach(hdmi->encoder, hdmi->next_bridge, hdmi->bridge, 296 + DRM_BRIDGE_ATTACH_NO_CONNECTOR); 297 + if (ret) { 298 + DRM_DEV_ERROR(dev->dev, "failed to attach next HDMI bridge: %d\n", ret); 299 + goto fail; 300 + } 314 301 } 315 302 316 303 hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder); ··· 384 353 .item ## _names = item ##_names_ ## entry, \ 385 354 .item ## _cnt = ARRAY_SIZE(item ## _names_ ## entry) 386 355 387 - static const char *pwr_reg_names_none[] = {}; 388 - static const char *hpd_reg_names_none[] = {}; 389 - 390 - static struct hdmi_platform_config hdmi_tx_8660_config; 391 - 392 - static const char *hpd_reg_names_8960[] = {"core-vdda", "hdmi-mux"}; 356 + static const char *hpd_reg_names_8960[] = {"core-vdda"}; 393 357 static const char *hpd_clk_names_8960[] = {"core", "master_iface", "slave_iface"}; 394 358 395 359 static struct hdmi_platform_config hdmi_tx_8960_config = { ··· 393 367 }; 394 368 395 369 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; 396 - static const char *hpd_reg_names_8x74[] = {"hpd-gdsc", "hpd-5v"}; 397 370 static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"}; 398 371 static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"}; 399 372 static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; 400 373 401 374 static struct hdmi_platform_config hdmi_tx_8974_config = { 402 375 HDMI_CFG(pwr_reg, 8x74), 403 - HDMI_CFG(hpd_reg, 8x74), 404 376 HDMI_CFG(pwr_clk, 8x74), 405 377 HDMI_CFG(hpd_clk, 8x74), 406 378 .hpd_freq = hpd_clk_freq_8x74, 407 - }; 408 - 409 - static const char *hpd_reg_names_8084[] = {"hpd-gdsc", "hpd-5v", "hpd-5v-en"}; 410 - 411 - static struct hdmi_platform_config hdmi_tx_8084_config = { 412 - HDMI_CFG(pwr_reg, 8x74), 413 - HDMI_CFG(hpd_reg, 8084), 414 - HDMI_CFG(pwr_clk, 8x74), 415 - HDMI_CFG(hpd_clk, 8x74), 416 - .hpd_freq = hpd_clk_freq_8x74, 417 - }; 418 - 419 - static struct hdmi_platform_config hdmi_tx_8994_config = { 420 - HDMI_CFG(pwr_reg, 8x74), 421 - HDMI_CFG(hpd_reg, none), 422 - HDMI_CFG(pwr_clk, 8x74), 423 - HDMI_CFG(hpd_clk, 8x74), 424 - .hpd_freq = hpd_clk_freq_8x74, 425 - }; 426 - 427 - static struct hdmi_platform_config hdmi_tx_8996_config = { 428 - HDMI_CFG(pwr_reg, none), 429 - HDMI_CFG(hpd_reg, none), 430 - HDMI_CFG(pwr_clk, 8x74), 431 - HDMI_CFG(hpd_clk, 8x74), 432 - .hpd_freq = hpd_clk_freq_8x74, 433 - }; 434 - 435 - static const struct { 436 - const char *name; 437 - const bool output; 438 - const int value; 439 - const char *label; 440 - } msm_hdmi_gpio_pdata[] = { 441 - { "qcom,hdmi-tx-ddc-clk", true, 1, "HDMI_DDC_CLK" }, 442 - { "qcom,hdmi-tx-ddc-data", true, 1, "HDMI_DDC_DATA" }, 443 - { "qcom,hdmi-tx-hpd", false, 1, "HDMI_HPD" }, 444 - { "qcom,hdmi-tx-mux-en", true, 1, "HDMI_MUX_EN" }, 445 - { "qcom,hdmi-tx-mux-sel", true, 0, "HDMI_MUX_SEL" }, 446 - { "qcom,hdmi-tx-mux-lpm", true, 1, "HDMI_MUX_LPM" }, 447 379 }; 448 380 449 381 /* ··· 515 531 struct hdmi_platform_config *hdmi_cfg; 516 532 struct hdmi *hdmi; 517 533 struct device_node *of_node = dev->of_node; 518 - int i, err; 534 + int err; 519 535 520 536 hdmi_cfg = (struct hdmi_platform_config *) 521 537 of_device_get_match_data(dev); ··· 526 542 527 543 hdmi_cfg->mmio_name = "core_physical"; 528 544 hdmi_cfg->qfprom_mmio_name = "qfprom_physical"; 529 - 530 - for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { 531 - const char *name = msm_hdmi_gpio_pdata[i].name; 532 - struct gpio_desc *gpiod; 533 - 534 - /* 535 - * We are fetching the GPIO lines "as is" since the connector 536 - * code is enabling and disabling the lines. Until that point 537 - * the power-on default value will be kept. 538 - */ 539 - gpiod = devm_gpiod_get_optional(dev, name, GPIOD_ASIS); 540 - /* This will catch e.g. -PROBE_DEFER */ 541 - if (IS_ERR(gpiod)) 542 - return PTR_ERR(gpiod); 543 - if (!gpiod) { 544 - /* Try a second time, stripping down the name */ 545 - char name3[32]; 546 - 547 - /* 548 - * Try again after stripping out the "qcom,hdmi-tx" 549 - * prefix. This is mainly to match "hpd-gpios" used 550 - * in the upstream bindings. 551 - */ 552 - if (sscanf(name, "qcom,hdmi-tx-%s", name3)) 553 - gpiod = devm_gpiod_get_optional(dev, name3, GPIOD_ASIS); 554 - if (IS_ERR(gpiod)) 555 - return PTR_ERR(gpiod); 556 - if (!gpiod) 557 - DBG("failed to get gpio: %s", name); 558 - } 559 - hdmi_cfg->gpios[i].gpiod = gpiod; 560 - if (gpiod) 561 - gpiod_set_consumer_name(gpiod, msm_hdmi_gpio_pdata[i].label); 562 - hdmi_cfg->gpios[i].output = msm_hdmi_gpio_pdata[i].output; 563 - hdmi_cfg->gpios[i].value = msm_hdmi_gpio_pdata[i].value; 564 - } 565 545 566 546 dev->platform_data = hdmi_cfg; 567 547 ··· 574 626 } 575 627 576 628 static const struct of_device_id msm_hdmi_dt_match[] = { 577 - { .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8996_config }, 578 - { .compatible = "qcom,hdmi-tx-8994", .data = &hdmi_tx_8994_config }, 579 - { .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8084_config }, 629 + { .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8974_config }, 630 + { .compatible = "qcom,hdmi-tx-8994", .data = &hdmi_tx_8974_config }, 631 + { .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8974_config }, 580 632 { .compatible = "qcom,hdmi-tx-8974", .data = &hdmi_tx_8974_config }, 581 633 { .compatible = "qcom,hdmi-tx-8960", .data = &hdmi_tx_8960_config }, 582 - { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8660_config }, 634 + { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8960_config }, 583 635 {} 584 636 }; 585 637
+4 -11
drivers/gpu/drm/msm/hdmi/hdmi.h
··· 19 19 #include "msm_drv.h" 20 20 #include "hdmi.xml.h" 21 21 22 - #define HDMI_MAX_NUM_GPIO 6 23 - 24 22 struct hdmi_phy; 25 23 struct hdmi_platform_config; 26 - 27 - struct hdmi_gpio_data { 28 - struct gpio_desc *gpiod; 29 - bool output; 30 - int value; 31 - }; 32 24 33 25 struct hdmi_audio { 34 26 bool enabled; ··· 53 61 struct clk **hpd_clks; 54 62 struct clk **pwr_clks; 55 63 64 + struct gpio_desc *hpd_gpiod; 65 + 56 66 struct hdmi_phy *phy; 57 67 struct device *phy_dev; 58 68 59 69 struct i2c_adapter *i2c; 60 70 struct drm_connector *connector; 61 71 struct drm_bridge *bridge; 72 + 73 + struct drm_bridge *next_bridge; 62 74 63 75 /* the encoder we are hooked to (outside of hdmi block) */ 64 76 struct drm_encoder *encoder; ··· 105 109 /* clks that need to be on for screen pwr (ie pixel clk): */ 106 110 const char **pwr_clk_names; 107 111 int pwr_clk_cnt; 108 - 109 - /* gpio's: */ 110 - struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO]; 111 112 }; 112 113 113 114 struct hdmi_bridge {
-10
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
··· 160 160 msm_hdmi_hdcp_on(hdmi->hdcp_ctrl); 161 161 } 162 162 163 - static void msm_hdmi_bridge_enable(struct drm_bridge *bridge) 164 - { 165 - } 166 - 167 - static void msm_hdmi_bridge_disable(struct drm_bridge *bridge) 168 - { 169 - } 170 - 171 163 static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge) 172 164 { 173 165 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); ··· 299 307 300 308 static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { 301 309 .pre_enable = msm_hdmi_bridge_pre_enable, 302 - .enable = msm_hdmi_bridge_enable, 303 - .disable = msm_hdmi_bridge_disable, 304 310 .post_disable = msm_hdmi_bridge_post_disable, 305 311 .mode_set = msm_hdmi_bridge_mode_set, 306 312 .mode_valid = msm_hdmi_bridge_mode_valid,
+4 -58
drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
··· 60 60 } 61 61 } 62 62 63 - static int gpio_config(struct hdmi *hdmi, bool on) 64 - { 65 - const struct hdmi_platform_config *config = hdmi->config; 66 - int i; 67 - 68 - if (on) { 69 - for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { 70 - struct hdmi_gpio_data gpio = config->gpios[i]; 71 - 72 - if (gpio.gpiod) { 73 - if (gpio.output) { 74 - gpiod_direction_output(gpio.gpiod, 75 - gpio.value); 76 - } else { 77 - gpiod_direction_input(gpio.gpiod); 78 - gpiod_set_value_cansleep(gpio.gpiod, 79 - gpio.value); 80 - } 81 - } 82 - } 83 - 84 - DBG("gpio on"); 85 - } else { 86 - for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { 87 - struct hdmi_gpio_data gpio = config->gpios[i]; 88 - 89 - if (!gpio.gpiod) 90 - continue; 91 - 92 - if (gpio.output) { 93 - int value = gpio.value ? 0 : 1; 94 - 95 - gpiod_set_value_cansleep(gpio.gpiod, value); 96 - } 97 - } 98 - 99 - DBG("gpio off"); 100 - } 101 - 102 - return 0; 103 - } 104 - 105 63 static void enable_hpd_clocks(struct hdmi *hdmi, bool enable) 106 64 { 107 65 const struct hdmi_platform_config *config = hdmi->config; ··· 112 154 goto fail; 113 155 } 114 156 115 - ret = gpio_config(hdmi, true); 116 - if (ret) { 117 - DRM_DEV_ERROR(dev, "failed to configure GPIOs: %d\n", ret); 118 - goto fail; 119 - } 157 + if (hdmi->hpd_gpiod) 158 + gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1); 120 159 121 160 pm_runtime_get_sync(dev); 122 161 enable_hpd_clocks(hdmi, true); ··· 161 206 162 207 enable_hpd_clocks(hdmi, false); 163 208 pm_runtime_put(dev); 164 - 165 - ret = gpio_config(hdmi, false); 166 - if (ret) 167 - dev_warn(dev, "failed to unconfigure GPIOs: %d\n", ret); 168 209 169 210 ret = pinctrl_pm_select_sleep_state(dev); 170 211 if (ret) ··· 220 269 #define HPD_GPIO_INDEX 2 221 270 static enum drm_connector_status detect_gpio(struct hdmi *hdmi) 222 271 { 223 - const struct hdmi_platform_config *config = hdmi->config; 224 - struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX]; 225 - 226 - return gpiod_get_value(hpd_gpio.gpiod) ? 272 + return gpiod_get_value(hdmi->hpd_gpiod) ? 227 273 connector_status_connected : 228 274 connector_status_disconnected; 229 275 } ··· 230 282 { 231 283 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 232 284 struct hdmi *hdmi = hdmi_bridge->hdmi; 233 - const struct hdmi_platform_config *config = hdmi->config; 234 - struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX]; 235 285 enum drm_connector_status stat_gpio, stat_reg; 236 286 int retry = 20; 237 287 ··· 237 291 * some platforms may not have hpd gpio. Rely only on the status 238 292 * provided by REG_HDMI_HPD_INT_STATUS in this case. 239 293 */ 240 - if (!hpd_gpio.gpiod) 294 + if (!hdmi->hpd_gpiod) 241 295 return detect_reg(hdmi); 242 296 243 297 do {
+12
drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c
··· 122 122 HDMI_8x60_PHY_REG2_PD_DESER); 123 123 } 124 124 125 + static const char * const hdmi_phy_8x60_reg_names[] = { 126 + "core-vdda", 127 + }; 128 + 129 + static const char * const hdmi_phy_8x60_clk_names[] = { 130 + "slave_iface", 131 + }; 132 + 125 133 const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = { 126 134 .type = MSM_HDMI_PHY_8x60, 127 135 .powerup = hdmi_phy_8x60_powerup, 128 136 .powerdown = hdmi_phy_8x60_powerdown, 137 + .reg_names = hdmi_phy_8x60_reg_names, 138 + .num_regs = ARRAY_SIZE(hdmi_phy_8x60_reg_names), 139 + .clk_names = hdmi_phy_8x60_clk_names, 140 + .num_clks = ARRAY_SIZE(hdmi_phy_8x60_clk_names), 129 141 };
+78 -3
drivers/gpu/drm/msm/msm_drv.c
··· 26 26 #include "msm_gem.h" 27 27 #include "msm_gpu.h" 28 28 #include "msm_kms.h" 29 + #include "msm_mmu.h" 29 30 #include "adreno/adreno_gpu.h" 30 31 31 32 /* ··· 268 267 269 268 #include <linux/of_address.h> 270 269 270 + struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev) 271 + { 272 + struct iommu_domain *domain; 273 + struct msm_gem_address_space *aspace; 274 + struct msm_mmu *mmu; 275 + struct device *mdp_dev = dev->dev; 276 + struct device *mdss_dev = mdp_dev->parent; 277 + struct device *iommu_dev; 278 + 279 + /* 280 + * IOMMUs can be a part of MDSS device tree binding, or the 281 + * MDP/DPU device. 282 + */ 283 + if (device_iommu_mapped(mdp_dev)) 284 + iommu_dev = mdp_dev; 285 + else 286 + iommu_dev = mdss_dev; 287 + 288 + domain = iommu_domain_alloc(iommu_dev->bus); 289 + if (!domain) { 290 + drm_info(dev, "no IOMMU, fallback to phys contig buffers for scanout\n"); 291 + return NULL; 292 + } 293 + 294 + mmu = msm_iommu_new(iommu_dev, domain); 295 + if (IS_ERR(mmu)) { 296 + iommu_domain_free(domain); 297 + return ERR_CAST(mmu); 298 + } 299 + 300 + aspace = msm_gem_address_space_create(mmu, "mdp_kms", 301 + 0x1000, 0x100000000 - 0x1000); 302 + if (IS_ERR(aspace)) 303 + mmu->funcs->destroy(mmu); 304 + 305 + return aspace; 306 + } 307 + 271 308 bool msm_use_mmu(struct drm_device *dev) 272 309 { 273 310 struct msm_drm_private *priv = dev->dev_private; 274 311 275 - /* a2xx comes with its own MMU */ 276 - return priv->is_a2xx || iommu_present(&platform_bus_type); 312 + /* 313 + * a2xx comes with its own MMU 314 + * On other platforms IOMMU can be declared specified either for the 315 + * MDP/DPU device or for its parent, MDSS device. 316 + */ 317 + return priv->is_a2xx || 318 + device_iommu_mapped(dev->dev) || 319 + device_iommu_mapped(dev->dev->parent); 277 320 } 278 321 279 322 static int msm_init_vram(struct drm_device *dev) ··· 678 633 struct drm_file *file) 679 634 { 680 635 struct drm_msm_gem_new *args = data; 636 + uint32_t flags = args->flags; 681 637 682 638 if (args->flags & ~MSM_BO_FLAGS) { 683 639 DRM_ERROR("invalid flags: %08x\n", args->flags); 684 640 return -EINVAL; 641 + } 642 + 643 + /* 644 + * Uncached CPU mappings are deprecated, as of: 645 + * 646 + * 9ef364432db4 ("drm/msm: deprecate MSM_BO_UNCACHED (map as writecombine instead)") 647 + * 648 + * So promote them to WC. 649 + */ 650 + if (flags & MSM_BO_UNCACHED) { 651 + flags &= ~MSM_BO_CACHED; 652 + flags |= MSM_BO_WC; 685 653 } 686 654 687 655 return msm_gem_new_handle(dev, file, args->size, ··· 1006 948 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW), 1007 949 }; 1008 950 1009 - DEFINE_DRM_GEM_FOPS(fops); 951 + static void msm_fop_show_fdinfo(struct seq_file *m, struct file *f) 952 + { 953 + struct drm_file *file = f->private_data; 954 + struct drm_device *dev = file->minor->dev; 955 + struct msm_drm_private *priv = dev->dev_private; 956 + struct drm_printer p = drm_seq_file_printer(m); 957 + 958 + if (!priv->gpu) 959 + return; 960 + 961 + msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, &p); 962 + } 963 + 964 + static const struct file_operations fops = { 965 + .owner = THIS_MODULE, 966 + DRM_GEM_FOPS, 967 + .show_fdinfo = msm_fop_show_fdinfo, 968 + }; 1010 969 1011 970 static const struct drm_driver msm_driver = { 1012 971 .driver_features = DRIVER_GEM |
+1 -10
drivers/gpu/drm/msm/msm_drv.h
··· 62 62 #define MAX_H_TILES_PER_DISPLAY 2 63 63 64 64 /** 65 - * enum msm_display_caps - features/capabilities supported by displays 66 - * @MSM_DISPLAY_CAP_VID_MODE: Video or "active" mode supported 67 - * @MSM_DISPLAY_CAP_CMD_MODE: Command mode supported 68 - */ 69 - enum msm_display_caps { 70 - MSM_DISPLAY_CAP_VID_MODE = BIT(0), 71 - MSM_DISPLAY_CAP_CMD_MODE = BIT(1), 72 - }; 73 - 74 - /** 75 65 * enum msm_event_wait - type of HW events to wait for 76 66 * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW 77 67 * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel ··· 224 234 int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); 225 235 void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu); 226 236 237 + struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev); 227 238 bool msm_use_mmu(struct drm_device *dev); 228 239 229 240 int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+10 -1
drivers/gpu/drm/msm/msm_fence.c
··· 28 28 fctx->fenceptr = fenceptr; 29 29 spin_lock_init(&fctx->spinlock); 30 30 31 + /* 32 + * Start out close to the 32b fence rollover point, so we can 33 + * catch bugs with fence comparisons. 34 + */ 35 + fctx->last_fence = 0xffffff00; 36 + fctx->completed_fence = fctx->last_fence; 37 + *fctx->fenceptr = fctx->last_fence; 38 + 31 39 return fctx; 32 40 } 33 41 ··· 60 52 unsigned long flags; 61 53 62 54 spin_lock_irqsave(&fctx->spinlock, flags); 63 - fctx->completed_fence = max(fence, fctx->completed_fence); 55 + if (fence_after(fence, fctx->completed_fence)) 56 + fctx->completed_fence = fence; 64 57 spin_unlock_irqrestore(&fctx->spinlock, flags); 65 58 } 66 59
+7 -15
drivers/gpu/drm/msm/msm_gem.c
··· 129 129 /* For non-cached buffers, ensure the new pages are clean 130 130 * because display controller, GPU, etc. are not coherent: 131 131 */ 132 - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) 132 + if (msm_obj->flags & MSM_BO_WC) 133 133 sync_for_device(msm_obj); 134 134 135 135 update_inactive(msm_obj); ··· 160 160 * pages are clean because display controller, 161 161 * GPU, etc. are not coherent: 162 162 */ 163 - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) 163 + if (msm_obj->flags & MSM_BO_WC) 164 164 sync_for_cpu(msm_obj); 165 165 166 166 sg_free_table(msm_obj->sgt); ··· 213 213 214 214 static pgprot_t msm_gem_pgprot(struct msm_gem_object *msm_obj, pgprot_t prot) 215 215 { 216 - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) 216 + if (msm_obj->flags & MSM_BO_WC) 217 217 return pgprot_writecombine(prot); 218 218 return prot; 219 219 } ··· 259 259 VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address, 260 260 pfn, pfn << PAGE_SHIFT); 261 261 262 - ret = vmf_insert_mixed(vma, vmf->address, __pfn_to_pfn_t(pfn, PFN_DEV)); 262 + ret = vmf_insert_pfn(vma, vmf->address, pfn); 263 + 263 264 out_unlock: 264 265 msm_gem_unlock(obj); 265 266 out: ··· 1005 1004 #endif 1006 1005 1007 1006 /* don't call directly! Use drm_gem_object_put() */ 1008 - void msm_gem_free_object(struct drm_gem_object *obj) 1007 + static void msm_gem_free_object(struct drm_gem_object *obj) 1009 1008 { 1010 1009 struct msm_gem_object *msm_obj = to_msm_bo(obj); 1011 1010 struct drm_device *dev = obj->dev; ··· 1020 1019 mark_unpurgeable(msm_obj); 1021 1020 list_del(&msm_obj->mm_list); 1022 1021 mutex_unlock(&priv->mm_lock); 1023 - 1024 - msm_gem_lock(obj); 1025 1022 1026 1023 /* object should not be on active list: */ 1027 1024 GEM_WARN_ON(is_active(msm_obj)); ··· 1036 1037 1037 1038 put_iova_vmas(obj); 1038 1039 1039 - /* dma_buf_detach() grabs resv lock, so we need to unlock 1040 - * prior to drm_prime_gem_destroy 1041 - */ 1042 - msm_gem_unlock(obj); 1043 - 1044 1040 drm_prime_gem_destroy(obj, msm_obj->sgt); 1045 1041 } else { 1046 1042 msm_gem_vunmap(obj); 1047 1043 put_pages(obj); 1048 1044 put_iova_vmas(obj); 1049 - msm_gem_unlock(obj); 1050 1045 } 1051 1046 1052 1047 drm_gem_object_release(obj); ··· 1052 1059 { 1053 1060 struct msm_gem_object *msm_obj = to_msm_bo(obj); 1054 1061 1055 - vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP; 1062 + vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; 1056 1063 vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags)); 1057 1064 1058 1065 return 0; ··· 1107 1114 struct msm_gem_object *msm_obj; 1108 1115 1109 1116 switch (flags & MSM_BO_CACHE_MASK) { 1110 - case MSM_BO_UNCACHED: 1111 1117 case MSM_BO_CACHED: 1112 1118 case MSM_BO_WC: 1113 1119 break;
+13 -2
drivers/gpu/drm/msm/msm_gem.h
··· 175 175 void msm_gem_active_put(struct drm_gem_object *obj); 176 176 int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout); 177 177 int msm_gem_cpu_fini(struct drm_gem_object *obj); 178 - void msm_gem_free_object(struct drm_gem_object *obj); 179 178 int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, 180 179 uint32_t size, uint32_t flags, uint32_t *handle, char *name); 181 180 struct drm_gem_object *msm_gem_new(struct drm_device *dev, ··· 229 230 static inline bool 230 231 msm_gem_is_locked(struct drm_gem_object *obj) 231 232 { 232 - return dma_resv_is_locked(obj->resv); 233 + /* 234 + * Destroying the object is a special case.. msm_gem_free_object() 235 + * calls many things that WARN_ON if the obj lock is not held. But 236 + * acquiring the obj lock in msm_gem_free_object() can cause a 237 + * locking order inversion between reservation_ww_class_mutex and 238 + * fs_reclaim. 239 + * 240 + * This deadlock is not actually possible, because no one should 241 + * be already holding the lock when msm_gem_free_object() is called. 242 + * Unfortunately lockdep is not aware of this detail. So when the 243 + * refcount drops to zero, we pretend it is already locked. 244 + */ 245 + return dma_resv_is_locked(obj->resv) || (kref_read(&obj->refcount) == 0); 233 246 } 234 247 235 248 static inline bool is_active(struct msm_gem_object *msm_obj)
+1 -1
drivers/gpu/drm/msm/msm_gem_shrinker.c
··· 15 15 /* Default disabled for now until it has some more testing on the different 16 16 * iommu combinations that can be paired with the driver: 17 17 */ 18 - bool enable_eviction = false; 18 + static bool enable_eviction = false; 19 19 MODULE_PARM_DESC(enable_eviction, "Enable swappable GEM buffers"); 20 20 module_param(enable_eviction, bool, 0600); 21 21
+31 -30
drivers/gpu/drm/msm/msm_gpu.c
··· 4 4 * Author: Rob Clark <robdclark@gmail.com> 5 5 */ 6 6 7 + #include "drm/drm_drv.h" 8 + 7 9 #include "msm_gpu.h" 8 10 #include "msm_gem.h" 9 11 #include "msm_mmu.h" ··· 148 146 return 0; 149 147 } 150 148 149 + void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx, 150 + struct drm_printer *p) 151 + { 152 + drm_printf(p, "drm-driver:\t%s\n", gpu->dev->driver->name); 153 + drm_printf(p, "drm-client-id:\t%u\n", ctx->seqno); 154 + drm_printf(p, "drm-engine-gpu:\t%llu ns\n", ctx->elapsed_ns); 155 + drm_printf(p, "drm-cycles-gpu:\t%llu\n", ctx->cycles); 156 + drm_printf(p, "drm-maxfreq-gpu:\t%u Hz\n", gpu->fast_rate); 157 + } 158 + 151 159 int msm_gpu_hw_init(struct msm_gpu *gpu) 152 160 { 153 161 int ret; ··· 221 209 } 222 210 223 211 static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state, 224 - struct msm_gem_object *obj, u64 iova, u32 flags) 212 + struct msm_gem_object *obj, u64 iova, bool full) 225 213 { 226 214 struct msm_gpu_state_bo *state_bo = &state->bos[state->nr_bos]; 227 215 ··· 229 217 state_bo->size = obj->base.size; 230 218 state_bo->iova = iova; 231 219 232 - /* Only store data for non imported buffer objects marked for read */ 233 - if ((flags & MSM_SUBMIT_BO_READ) && !obj->base.import_attach) { 220 + BUILD_BUG_ON(sizeof(state_bo->name) != sizeof(obj->name)); 221 + 222 + memcpy(state_bo->name, obj->name, sizeof(state_bo->name)); 223 + 224 + if (full) { 234 225 void *ptr; 235 226 236 227 state_bo->data = kvmalloc(obj->base.size, GFP_KERNEL); ··· 279 264 state->fault_info = gpu->fault_info; 280 265 281 266 if (submit) { 282 - int i, nr = 0; 267 + int i; 283 268 284 - /* count # of buffers to dump: */ 285 - for (i = 0; i < submit->nr_bos; i++) 286 - if (should_dump(submit, i)) 287 - nr++; 288 - /* always dump cmd bo's, but don't double count them: */ 289 - for (i = 0; i < submit->nr_cmds; i++) 290 - if (!should_dump(submit, submit->cmd[i].idx)) 291 - nr++; 292 - 293 - state->bos = kcalloc(nr, 269 + state->bos = kcalloc(submit->nr_bos, 294 270 sizeof(struct msm_gpu_state_bo), GFP_KERNEL); 295 271 296 272 for (i = 0; state->bos && i < submit->nr_bos; i++) { 297 - if (should_dump(submit, i)) { 298 - msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, 299 - submit->bos[i].iova, submit->bos[i].flags); 300 - } 301 - } 302 - 303 - for (i = 0; state->bos && i < submit->nr_cmds; i++) { 304 - int idx = submit->cmd[i].idx; 305 - 306 - if (!should_dump(submit, submit->cmd[i].idx)) { 307 - msm_gpu_crashstate_get_bo(state, submit->bos[idx].obj, 308 - submit->bos[idx].iova, submit->bos[idx].flags); 309 - } 273 + msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, 274 + submit->bos[i].iova, 275 + should_dump(submit, i)); 310 276 } 311 277 } 312 278 ··· 630 634 { 631 635 int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; 632 636 volatile struct msm_gpu_submit_stats *stats; 633 - u64 elapsed, clock = 0; 637 + u64 elapsed, clock = 0, cycles; 634 638 unsigned long flags; 635 639 636 640 stats = &ring->memptrs->stats[index]; ··· 638 642 elapsed = (stats->alwayson_end - stats->alwayson_start) * 10000; 639 643 do_div(elapsed, 192); 640 644 645 + cycles = stats->cpcycles_end - stats->cpcycles_start; 646 + 641 647 /* Calculate the clock frequency from the number of CP cycles */ 642 648 if (elapsed) { 643 - clock = (stats->cpcycles_end - stats->cpcycles_start) * 1000; 649 + clock = cycles * 1000; 644 650 do_div(clock, elapsed); 645 651 } 652 + 653 + submit->queue->ctx->elapsed_ns += elapsed; 654 + submit->queue->ctx->cycles += cycles; 646 655 647 656 trace_msm_gpu_submit_retired(submit, elapsed, clock, 648 657 stats->alwayson_start, stats->alwayson_end); ··· 918 917 919 918 memptrs = msm_gem_kernel_new(drm, 920 919 sizeof(struct msm_rbmemptrs) * nr_rings, 921 - check_apriv(gpu, MSM_BO_UNCACHED), gpu->aspace, &gpu->memptrs_bo, 920 + check_apriv(gpu, MSM_BO_WC), gpu->aspace, &gpu->memptrs_bo, 922 921 &memptrs_iova); 923 922 924 923 if (IS_ERR(memptrs)) {
+30 -1
drivers/gpu/drm/msm/msm_gpu.h
··· 64 64 /* for generation specific debugfs: */ 65 65 void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); 66 66 #endif 67 + /* note: gpu_busy() can assume that we have been pm_resumed */ 67 68 u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate); 68 69 struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu); 69 70 int (*gpu_state_put)(struct msm_gpu_state *state); 70 71 unsigned long (*gpu_get_freq)(struct msm_gpu *gpu); 71 - void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp); 72 + /* note: gpu_set_freq() can assume that we have been pm_resumed */ 73 + void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp, 74 + bool suspended); 72 75 struct msm_gem_address_space *(*create_address_space) 73 76 (struct msm_gpu *gpu, struct platform_device *pdev); 74 77 struct msm_gem_address_space *(*create_private_address_space) ··· 94 91 struct msm_gpu_devfreq { 95 92 /** devfreq: devfreq instance */ 96 93 struct devfreq *devfreq; 94 + 95 + /** lock: lock for "suspended", "busy_cycles", and "time" */ 96 + struct mutex lock; 97 97 98 98 /** 99 99 * idle_constraint: ··· 141 135 * elapsed 142 136 */ 143 137 struct msm_hrtimer_work boost_work; 138 + 139 + /** suspended: tracks if we're suspended */ 140 + bool suspended; 144 141 }; 145 142 146 143 struct msm_gpu { ··· 371 362 char *cmdline; 372 363 373 364 /** 365 + * elapsed: 366 + * 367 + * The total (cumulative) elapsed time GPU was busy with rendering 368 + * from this context in ns. 369 + */ 370 + uint64_t elapsed_ns; 371 + 372 + /** 373 + * cycles: 374 + * 375 + * The total (cumulative) GPU cycles elapsed attributed to this 376 + * context. 377 + */ 378 + uint64_t cycles; 379 + 380 + /** 374 381 * entities: 375 382 * 376 383 * Table of per-priority-level sched entities used by submitqueues ··· 489 464 size_t size; 490 465 void *data; 491 466 bool encoded; 467 + char name[32]; 492 468 }; 493 469 494 470 struct msm_gpu_state { ··· 569 543 570 544 int msm_gpu_pm_suspend(struct msm_gpu *gpu); 571 545 int msm_gpu_pm_resume(struct msm_gpu *gpu); 546 + 547 + void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx, 548 + struct drm_printer *p); 572 549 573 550 int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx); 574 551 struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
+33 -10
drivers/gpu/drm/msm/msm_gpu_devfreq.c
··· 20 20 u32 flags) 21 21 { 22 22 struct msm_gpu *gpu = dev_to_gpu(dev); 23 + struct msm_gpu_devfreq *df = &gpu->devfreq; 23 24 struct dev_pm_opp *opp; 24 25 25 26 /* ··· 33 32 34 33 trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp)); 35 34 36 - if (gpu->funcs->gpu_set_freq) 37 - gpu->funcs->gpu_set_freq(gpu, opp); 38 - else 35 + if (gpu->funcs->gpu_set_freq) { 36 + mutex_lock(&df->lock); 37 + gpu->funcs->gpu_set_freq(gpu, opp, df->suspended); 38 + mutex_unlock(&df->lock); 39 + } else { 39 40 clk_set_rate(gpu->core_clk, *freq); 41 + } 40 42 41 43 dev_pm_opp_put(opp); 42 44 ··· 62 58 unsigned long sample_rate; 63 59 ktime_t time; 64 60 61 + mutex_lock(&df->lock); 62 + 65 63 status->current_frequency = get_freq(gpu); 66 - busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); 67 64 time = ktime_get(); 68 - 69 - busy_time = busy_cycles - df->busy_cycles; 70 65 status->total_time = ktime_us_delta(time, df->time); 71 - 72 - df->busy_cycles = busy_cycles; 73 66 df->time = time; 74 67 68 + if (df->suspended) { 69 + mutex_unlock(&df->lock); 70 + status->busy_time = 0; 71 + return; 72 + } 73 + 74 + busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); 75 + busy_time = busy_cycles - df->busy_cycles; 76 + df->busy_cycles = busy_cycles; 77 + 78 + mutex_unlock(&df->lock); 79 + 75 80 busy_time *= USEC_PER_SEC; 76 - do_div(busy_time, sample_rate); 81 + busy_time = div64_ul(busy_time, sample_rate); 77 82 if (WARN_ON(busy_time > ~0LU)) 78 83 busy_time = ~0LU; 79 84 ··· 188 175 if (!gpu->funcs->gpu_busy) 189 176 return; 190 177 178 + mutex_init(&df->lock); 179 + 191 180 dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq, 192 181 DEV_PM_QOS_MAX_FREQUENCY, 193 182 PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); ··· 259 244 void msm_devfreq_resume(struct msm_gpu *gpu) 260 245 { 261 246 struct msm_gpu_devfreq *df = &gpu->devfreq; 247 + unsigned long sample_rate; 262 248 263 249 if (!has_devfreq(gpu)) 264 250 return; 265 251 266 - df->busy_cycles = 0; 252 + mutex_lock(&df->lock); 253 + df->busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); 267 254 df->time = ktime_get(); 255 + df->suspended = false; 256 + mutex_unlock(&df->lock); 268 257 269 258 devfreq_resume_device(df->devfreq); 270 259 } ··· 279 260 280 261 if (!has_devfreq(gpu)) 281 262 return; 263 + 264 + mutex_lock(&df->lock); 265 + df->suspended = true; 266 + mutex_unlock(&df->lock); 282 267 283 268 devfreq_suspend_device(df->devfreq); 284 269
+18 -8
include/drm/drm_gem.h
··· 315 315 }; 316 316 317 317 /** 318 + * DRM_GEM_FOPS - Default drm GEM file operations 319 + * 320 + * This macro provides a shorthand for setting the GEM file ops in the 321 + * &file_operations structure. If all you need are the default ops, use 322 + * DEFINE_DRM_GEM_FOPS instead. 323 + */ 324 + #define DRM_GEM_FOPS \ 325 + .open = drm_open,\ 326 + .release = drm_release,\ 327 + .unlocked_ioctl = drm_ioctl,\ 328 + .compat_ioctl = drm_compat_ioctl,\ 329 + .poll = drm_poll,\ 330 + .read = drm_read,\ 331 + .llseek = noop_llseek,\ 332 + .mmap = drm_gem_mmap 333 + 334 + /** 318 335 * DEFINE_DRM_GEM_FOPS() - macro to generate file operations for GEM drivers 319 336 * @name: name for the generated structure 320 337 * ··· 347 330 #define DEFINE_DRM_GEM_FOPS(name) \ 348 331 static const struct file_operations name = {\ 349 332 .owner = THIS_MODULE,\ 350 - .open = drm_open,\ 351 - .release = drm_release,\ 352 - .unlocked_ioctl = drm_ioctl,\ 353 - .compat_ioctl = drm_compat_ioctl,\ 354 - .poll = drm_poll,\ 355 - .read = drm_read,\ 356 - .llseek = noop_llseek,\ 357 - .mmap = drm_gem_mmap,\ 333 + DRM_GEM_FOPS,\ 358 334 } 359 335 360 336 void drm_gem_object_release(struct drm_gem_object *obj);