aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-04-23 21:54:26 -0400
committerDave Airlie <airlied@redhat.com>2019-04-23 21:56:32 -0400
commit70b5f09e4389c789263c6d79c539b8378e3af3bc (patch)
tree0c1efa5d6b1c0a0f5984c08a724f83a931d08482
parent42f1a013300dca601d779b02ed6d41f7b2cea362 (diff)
parentb02872df58aca66d0e7af3ec5065dbc6f0630dd1 (diff)
Merge tag 'drm-msm-next-2019-04-21' of https://gitlab.freedesktop.org/drm/msm into drm-next
This time around it is a bunch of cleanup and fixes, expanding gpu "zap" shader support (so we can take the GPU out of secure mode on boot) to a6xx, and small UABI extension to support robustness (see mesa MR 673). Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <robdclark@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGsHwsEfi4y2LYKSqeqDEYvffwVgKhiP8jHcHpxp13J5LQ@mail.gmail.com
-rw-r--r--Documentation/devicetree/bindings/display/msm/gmu.txt10
-rw-r--r--Documentation/devicetree/bindings/display/msm/gpu.txt11
-rw-r--r--drivers/gpu/drm/msm/Kconfig5
-rw-r--r--drivers/gpu/drm/msm/Makefile3
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c109
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c216
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.h9
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c62
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.h3
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c141
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h6
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c69
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c119
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h15
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c5
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c177
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c4
-rw-r--r--drivers/gpu/drm/msm/msm_debugfs.c2
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c14
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h7
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c42
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h8
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c44
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c2
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c17
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h3
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c13
-rw-r--r--drivers/gpu/drm/msm/msm_submitqueue.c41
-rw-r--r--include/uapi/drm/msm_drm.h14
32 files changed, 665 insertions, 513 deletions
diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt
index 3439b38e60f2..90af5b0a56a9 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.txt
+++ b/Documentation/devicetree/bindings/display/msm/gmu.txt
@@ -24,7 +24,10 @@ Required properties:
24 * "cxo" 24 * "cxo"
25 * "axi" 25 * "axi"
26 * "mnoc" 26 * "mnoc"
27- power-domains: should be <&clock_gpucc GPU_CX_GDSC> 27- power-domains: should be:
28 <&clock_gpucc GPU_CX_GDSC>
29 <&clock_gpucc GPU_GX_GDSC>
30- power-domain-names: Matching names for the power domains
28- iommus: phandle to the adreno iommu 31- iommus: phandle to the adreno iommu
29- operating-points-v2: phandle to the OPP operating points 32- operating-points-v2: phandle to the OPP operating points
30 33
@@ -51,7 +54,10 @@ Example:
51 <&gcc GCC_GPU_MEMNOC_GFX_CLK>; 54 <&gcc GCC_GPU_MEMNOC_GFX_CLK>;
52 clock-names = "gmu", "cxo", "axi", "memnoc"; 55 clock-names = "gmu", "cxo", "axi", "memnoc";
53 56
54 power-domains = <&gpucc GPU_CX_GDSC>; 57 power-domains = <&gpucc GPU_CX_GDSC>,
58 <&gpucc GPU_GX_GDSC>;
59 power-domain-names = "cx", "gx";
60
55 iommus = <&adreno_smmu 5>; 61 iommus = <&adreno_smmu 5>;
56 62
57 operating-points-v2 = <&gmu_opp_table>; 63 operating-points-v2 = <&gmu_opp_table>;
diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt
index aad1aef682f7..2b8fd26c43b0 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.txt
+++ b/Documentation/devicetree/bindings/display/msm/gpu.txt
@@ -22,9 +22,14 @@ Required properties:
22 - qcom,adreno-630.2 22 - qcom,adreno-630.2
23- iommus: optional phandle to an adreno iommu instance 23- iommus: optional phandle to an adreno iommu instance
24- operating-points-v2: optional phandle to the OPP operating points 24- operating-points-v2: optional phandle to the OPP operating points
25- interconnects: optional phandle to an interconnect provider. See
26 ../interconnect/interconnect.txt for details.
25- qcom,gmu: For GMU attached devices a phandle to the GMU device that will 27- qcom,gmu: For GMU attached devices a phandle to the GMU device that will
26 control the power for the GPU. Applicable targets: 28 control the power for the GPU. Applicable targets:
27 - qcom,adreno-630.2 29 - qcom,adreno-630.2
30- zap-shader: For a5xx and a6xx devices this node contains a memory-region that
31 points to reserved memory to store the zap shader that can be used to help
32 bring the GPU out of secure mode.
28 33
29Example 3xx/4xx/a5xx: 34Example 3xx/4xx/a5xx:
30 35
@@ -70,6 +75,12 @@ Example a6xx (with GMU):
70 75
71 operating-points-v2 = <&gpu_opp_table>; 76 operating-points-v2 = <&gpu_opp_table>;
72 77
78 interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>;
79
73 qcom,gmu = <&gmu>; 80 qcom,gmu = <&gmu>;
81
82 zap-shader {
83 memory-region = <&zap_shader_region>;
84 };
74 }; 85 };
75}; 86};
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 78c9e5a5e793..9f2029eca39f 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -21,6 +21,11 @@ config DRM_MSM
21 help 21 help
22 DRM/KMS driver for MSM/snapdragon. 22 DRM/KMS driver for MSM/snapdragon.
23 23
24config DRM_MSM_GPU_STATE
25 bool
26 depends on DRM_MSM && (DEBUG_FS || DEV_COREDUMP)
27 default y
28
24config DRM_MSM_REGISTER_LOGGING 29config DRM_MSM_REGISTER_LOGGING
25 bool "MSM DRM register logging" 30 bool "MSM DRM register logging"
26 depends on DRM_MSM 31 depends on DRM_MSM
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 56a70c74af4e..72d1bfcaab7a 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -15,7 +15,6 @@ msm-y := \
15 adreno/a6xx_gpu.o \ 15 adreno/a6xx_gpu.o \
16 adreno/a6xx_gmu.o \ 16 adreno/a6xx_gmu.o \
17 adreno/a6xx_hfi.o \ 17 adreno/a6xx_hfi.o \
18 adreno/a6xx_gpu_state.o \
19 hdmi/hdmi.o \ 18 hdmi/hdmi.o \
20 hdmi/hdmi_audio.o \ 19 hdmi/hdmi_audio.o \
21 hdmi/hdmi_bridge.o \ 20 hdmi/hdmi_bridge.o \
@@ -96,6 +95,8 @@ msm-y := \
96 95
97msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o 96msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o
98 97
98msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o
99
99msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o 100msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
100msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o 101msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
101msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o 102msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index d5f5e56422f5..e5fcefa49f19 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -15,9 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/cpumask.h> 16#include <linux/cpumask.h>
17#include <linux/qcom_scm.h> 17#include <linux/qcom_scm.h>
18#include <linux/dma-mapping.h>
19#include <linux/of_address.h>
20#include <linux/soc/qcom/mdt_loader.h>
21#include <linux/pm_opp.h> 18#include <linux/pm_opp.h>
22#include <linux/nvmem-consumer.h> 19#include <linux/nvmem-consumer.h>
23#include <linux/slab.h> 20#include <linux/slab.h>
@@ -30,94 +27,6 @@ static void a5xx_dump(struct msm_gpu *gpu);
30 27
31#define GPU_PAS_ID 13 28#define GPU_PAS_ID 13
32 29
33static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
34{
35 struct device *dev = &gpu->pdev->dev;
36 const struct firmware *fw;
37 struct device_node *np;
38 struct resource r;
39 phys_addr_t mem_phys;
40 ssize_t mem_size;
41 void *mem_region = NULL;
42 int ret;
43
44 if (!IS_ENABLED(CONFIG_ARCH_QCOM))
45 return -EINVAL;
46
47 np = of_get_child_by_name(dev->of_node, "zap-shader");
48 if (!np)
49 return -ENODEV;
50
51 np = of_parse_phandle(np, "memory-region", 0);
52 if (!np)
53 return -EINVAL;
54
55 ret = of_address_to_resource(np, 0, &r);
56 if (ret)
57 return ret;
58
59 mem_phys = r.start;
60 mem_size = resource_size(&r);
61
62 /* Request the MDT file for the firmware */
63 fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
64 if (IS_ERR(fw)) {
65 DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
66 return PTR_ERR(fw);
67 }
68
69 /* Figure out how much memory we need */
70 mem_size = qcom_mdt_get_size(fw);
71 if (mem_size < 0) {
72 ret = mem_size;
73 goto out;
74 }
75
76 /* Allocate memory for the firmware image */
77 mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
78 if (!mem_region) {
79 ret = -ENOMEM;
80 goto out;
81 }
82
83 /*
84 * Load the rest of the MDT
85 *
86 * Note that we could be dealing with two different paths, since
87 * with upstream linux-firmware it would be in a qcom/ subdir..
88 * adreno_request_fw() handles this, but qcom_mdt_load() does
89 * not. But since we've already gotten thru adreno_request_fw()
90 * we know which of the two cases it is:
91 */
92 if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
93 ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID,
94 mem_region, mem_phys, mem_size, NULL);
95 } else {
96 char *newname;
97
98 newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
99
100 ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID,
101 mem_region, mem_phys, mem_size, NULL);
102 kfree(newname);
103 }
104 if (ret)
105 goto out;
106
107 /* Send the image to the secure world */
108 ret = qcom_scm_pas_auth_and_reset(GPU_PAS_ID);
109 if (ret)
110 DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
111
112out:
113 if (mem_region)
114 memunmap(mem_region);
115
116 release_firmware(fw);
117
118 return ret;
119}
120
121static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) 30static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
122{ 31{
123 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 32 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -563,8 +472,6 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
563static int a5xx_zap_shader_init(struct msm_gpu *gpu) 472static int a5xx_zap_shader_init(struct msm_gpu *gpu)
564{ 473{
565 static bool loaded; 474 static bool loaded;
566 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
567 struct platform_device *pdev = gpu->pdev;
568 int ret; 475 int ret;
569 476
570 /* 477 /*
@@ -574,23 +481,9 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
574 if (loaded) 481 if (loaded)
575 return a5xx_zap_shader_resume(gpu); 482 return a5xx_zap_shader_resume(gpu);
576 483
577 /* We need SCM to be able to load the firmware */ 484 ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
578 if (!qcom_scm_is_available()) {
579 DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
580 return -EPROBE_DEFER;
581 }
582
583 /* Each GPU has a target specific zap shader firmware name to use */
584 if (!adreno_gpu->info->zapfw) {
585 DRM_DEV_ERROR(&pdev->dev,
586 "Zap shader firmware file not specified for this target\n");
587 return -ENODEV;
588 }
589
590 ret = zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw);
591 485
592 loaded = !ret; 486 loaded = !ret;
593
594 return ret; 487 return ret;
595} 488}
596 489
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index d1662a75c7ec..9155dafae2a9 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -3,12 +3,31 @@
3 3
4#include <linux/clk.h> 4#include <linux/clk.h>
5#include <linux/interconnect.h> 5#include <linux/interconnect.h>
6#include <linux/pm_domain.h>
6#include <linux/pm_opp.h> 7#include <linux/pm_opp.h>
7#include <soc/qcom/cmd-db.h> 8#include <soc/qcom/cmd-db.h>
8 9
9#include "a6xx_gpu.h" 10#include "a6xx_gpu.h"
10#include "a6xx_gmu.xml.h" 11#include "a6xx_gmu.xml.h"
11 12
13static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
14{
15 struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
16 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
17 struct msm_gpu *gpu = &adreno_gpu->base;
18 struct drm_device *dev = gpu->dev;
19 struct msm_drm_private *priv = dev->dev_private;
20
21 /* FIXME: add a banner here */
22 gmu->hung = true;
23
24 /* Turn off the hangcheck timer while we are resetting */
25 del_timer(&gpu->hangcheck_timer);
26
27 /* Queue the GPU handler because we need to treat this as a recovery */
28 queue_work(priv->wq, &gpu->recover_work);
29}
30
12static irqreturn_t a6xx_gmu_irq(int irq, void *data) 31static irqreturn_t a6xx_gmu_irq(int irq, void *data)
13{ 32{
14 struct a6xx_gmu *gmu = data; 33 struct a6xx_gmu *gmu = data;
@@ -20,8 +39,7 @@ static irqreturn_t a6xx_gmu_irq(int irq, void *data)
20 if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) { 39 if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) {
21 dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n"); 40 dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n");
22 41
23 /* Temporary until we can recover safely */ 42 a6xx_gmu_fault(gmu);
24 BUG();
25 } 43 }
26 44
27 if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR) 45 if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR)
@@ -45,8 +63,7 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data)
45 if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) { 63 if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) {
46 dev_err_ratelimited(gmu->dev, "GMU firmware fault\n"); 64 dev_err_ratelimited(gmu->dev, "GMU firmware fault\n");
47 65
48 /* Temporary until we can recover safely */ 66 a6xx_gmu_fault(gmu);
49 BUG();
50 } 67 }
51 68
52 return IRQ_HANDLED; 69 return IRQ_HANDLED;
@@ -165,10 +182,8 @@ static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
165} 182}
166 183
167/* Wait for the GMU to get to its most idle state */ 184/* Wait for the GMU to get to its most idle state */
168int a6xx_gmu_wait_for_idle(struct a6xx_gpu *a6xx_gpu) 185int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu)
169{ 186{
170 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
171
172 return spin_until(a6xx_gmu_check_idle_level(gmu)); 187 return spin_until(a6xx_gmu_check_idle_level(gmu));
173} 188}
174 189
@@ -567,7 +582,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
567 if (!rpmh_init) { 582 if (!rpmh_init) {
568 a6xx_gmu_rpmh_init(gmu); 583 a6xx_gmu_rpmh_init(gmu);
569 rpmh_init = true; 584 rpmh_init = true;
570 } else if (state != GMU_RESET) { 585 } else {
571 ret = a6xx_rpmh_start(gmu); 586 ret = a6xx_rpmh_start(gmu);
572 if (ret) 587 if (ret)
573 return ret; 588 return ret;
@@ -633,20 +648,6 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
633 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR | \ 648 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR | \
634 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR) 649 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)
635 650
636static void a6xx_gmu_irq_enable(struct a6xx_gmu *gmu)
637{
638 gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0);
639 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0);
640
641 gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK,
642 ~A6XX_GMU_IRQ_MASK);
643 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK,
644 ~A6XX_HFI_IRQ_MASK);
645
646 enable_irq(gmu->gmu_irq);
647 enable_irq(gmu->hfi_irq);
648}
649
650static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu) 651static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu)
651{ 652{
652 disable_irq(gmu->gmu_irq); 653 disable_irq(gmu->gmu_irq);
@@ -656,21 +657,10 @@ static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu)
656 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0); 657 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0);
657} 658}
658 659
659int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu) 660static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
660{ 661{
661 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
662 int ret;
663 u32 val; 662 u32 val;
664 663
665 /* Flush all the queues */
666 a6xx_hfi_stop(gmu);
667
668 /* Stop the interrupts */
669 a6xx_gmu_irq_disable(gmu);
670
671 /* Force off SPTP in case the GMU is managing it */
672 a6xx_sptprac_disable(gmu);
673
674 /* Make sure there are no outstanding RPMh votes */ 664 /* Make sure there are no outstanding RPMh votes */
675 gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val, 665 gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val,
676 (val & 1), 100, 10000); 666 (val & 1), 100, 10000);
@@ -680,37 +670,22 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu)
680 (val & 1), 100, 10000); 670 (val & 1), 100, 10000);
681 gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, 671 gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val,
682 (val & 1), 100, 1000); 672 (val & 1), 100, 1000);
673}
683 674
684 /* Force off the GX GSDC */ 675/* Force the GMU off in case it isn't responsive */
685 regulator_force_disable(gmu->gx); 676static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
686 677{
687 /* Disable the resources */ 678 /* Flush all the queues */
688 clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); 679 a6xx_hfi_stop(gmu);
689 pm_runtime_put_sync(gmu->dev);
690
691 /* Re-enable the resources */
692 pm_runtime_get_sync(gmu->dev);
693
694 /* Use a known rate to bring up the GMU */
695 clk_set_rate(gmu->core_clk, 200000000);
696 ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks);
697 if (ret)
698 goto out;
699
700 a6xx_gmu_irq_enable(gmu);
701
702 ret = a6xx_gmu_fw_start(gmu, GMU_RESET);
703 if (!ret)
704 ret = a6xx_hfi_start(gmu, GMU_COLD_BOOT);
705 680
706 /* Set the GPU back to the highest power frequency */ 681 /* Stop the interrupts */
707 __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); 682 a6xx_gmu_irq_disable(gmu);
708 683
709out: 684 /* Force off SPTP in case the GMU is managing it */
710 if (ret) 685 a6xx_sptprac_disable(gmu);
711 a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER);
712 686
713 return ret; 687 /* Make sure there are no outstanding RPMh votes */
688 a6xx_gmu_rpmh_off(gmu);
714} 689}
715 690
716int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) 691int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
@@ -723,19 +698,26 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
723 if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) 698 if (WARN(!gmu->mmio, "The GMU is not set up yet\n"))
724 return 0; 699 return 0;
725 700
701 gmu->hung = false;
702
726 /* Turn on the resources */ 703 /* Turn on the resources */
727 pm_runtime_get_sync(gmu->dev); 704 pm_runtime_get_sync(gmu->dev);
728 705
729 /* Use a known rate to bring up the GMU */ 706 /* Use a known rate to bring up the GMU */
730 clk_set_rate(gmu->core_clk, 200000000); 707 clk_set_rate(gmu->core_clk, 200000000);
731 ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); 708 ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks);
732 if (ret) 709 if (ret) {
733 goto out; 710 pm_runtime_put(gmu->dev);
711 return ret;
712 }
734 713
735 /* Set the bus quota to a reasonable value for boot */ 714 /* Set the bus quota to a reasonable value for boot */
736 icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072)); 715 icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072));
737 716
738 a6xx_gmu_irq_enable(gmu); 717 /* Enable the GMU interrupt */
718 gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0);
719 gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~A6XX_GMU_IRQ_MASK);
720 enable_irq(gmu->gmu_irq);
739 721
740 /* Check to see if we are doing a cold or warm boot */ 722 /* Check to see if we are doing a cold or warm boot */
741 status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ? 723 status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
@@ -746,14 +728,35 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
746 goto out; 728 goto out;
747 729
748 ret = a6xx_hfi_start(gmu, status); 730 ret = a6xx_hfi_start(gmu, status);
731 if (ret)
732 goto out;
733
734 /*
735 * Turn on the GMU firmware fault interrupt after we know the boot
736 * sequence is successful
737 */
738 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0);
739 gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~A6XX_HFI_IRQ_MASK);
740 enable_irq(gmu->hfi_irq);
749 741
750 /* Set the GPU to the highest power frequency */ 742 /* Set the GPU to the highest power frequency */
751 __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); 743 __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
752 744
745 /*
746 * "enable" the GX power domain which won't actually do anything but it
747 * will make sure that the refcounting is correct in case we need to
748 * bring down the GX after a GMU failure
749 */
750 if (!IS_ERR(gmu->gxpd))
751 pm_runtime_get(gmu->gxpd);
752
753out: 753out:
754 /* Make sure to turn off the boot OOB request on error */ 754 /* On failure, shut down the GMU to leave it in a good state */
755 if (ret) 755 if (ret) {
756 a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER); 756 disable_irq(gmu->gmu_irq);
757 a6xx_rpmh_stop(gmu);
758 pm_runtime_put(gmu->dev);
759 }
757 760
758 return ret; 761 return ret;
759} 762}
@@ -773,11 +776,12 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu)
773 return true; 776 return true;
774} 777}
775 778
776int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) 779/* Gracefully try to shut down the GMU and by extension the GPU */
780static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)
777{ 781{
782 struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
778 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; 783 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
779 struct msm_gpu *gpu = &adreno_gpu->base; 784 struct msm_gpu *gpu = &adreno_gpu->base;
780 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
781 u32 val; 785 u32 val;
782 786
783 /* 787 /*
@@ -787,10 +791,19 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
787 val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE); 791 val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE);
788 792
789 if (val != 0xf) { 793 if (val != 0xf) {
790 int ret = a6xx_gmu_wait_for_idle(a6xx_gpu); 794 int ret = a6xx_gmu_wait_for_idle(gmu);
791 795
792 /* Temporary until we can recover safely */ 796 /* If the GMU isn't responding assume it is hung */
793 BUG_ON(ret); 797 if (ret) {
798 a6xx_gmu_force_off(gmu);
799 return;
800 }
801
802 /* Clear the VBIF pipe before shutting down */
803 gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf);
804 spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & 0xf)
805 == 0xf);
806 gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0);
794 807
795 /* tell the GMU we want to slumber */ 808 /* tell the GMU we want to slumber */
796 a6xx_gmu_notify_slumber(gmu); 809 a6xx_gmu_notify_slumber(gmu);
@@ -822,10 +835,37 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
822 835
823 /* Tell RPMh to power off the GPU */ 836 /* Tell RPMh to power off the GPU */
824 a6xx_rpmh_stop(gmu); 837 a6xx_rpmh_stop(gmu);
838}
839
840
841int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
842{
843 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
844 struct msm_gpu *gpu = &a6xx_gpu->base.base;
845
846 if (!pm_runtime_active(gmu->dev))
847 return 0;
848
849 /*
850 * Force the GMU off if we detected a hang, otherwise try to shut it
851 * down gracefully
852 */
853 if (gmu->hung)
854 a6xx_gmu_force_off(gmu);
855 else
856 a6xx_gmu_shutdown(gmu);
825 857
826 /* Remove the bus vote */ 858 /* Remove the bus vote */
827 icc_set_bw(gpu->icc_path, 0, 0); 859 icc_set_bw(gpu->icc_path, 0, 0);
828 860
861 /*
862 * Make sure the GX domain is off before turning off the GMU (CX)
863 * domain. Usually the GMU does this but only if the shutdown sequence
864 * was successful
865 */
866 if (!IS_ERR(gmu->gxpd))
867 pm_runtime_put_sync(gmu->gxpd);
868
829 clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); 869 clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
830 870
831 pm_runtime_put_sync(gmu->dev); 871 pm_runtime_put_sync(gmu->dev);
@@ -948,25 +988,20 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
948} 988}
949 989
950/* Return the 'arc-level' for the given frequency */ 990/* Return the 'arc-level' for the given frequency */
951static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq) 991static unsigned int a6xx_gmu_get_arc_level(struct device *dev,
992 unsigned long freq)
952{ 993{
953 struct dev_pm_opp *opp; 994 struct dev_pm_opp *opp;
954 struct device_node *np; 995 unsigned int val;
955 u32 val = 0;
956 996
957 if (!freq) 997 if (!freq)
958 return 0; 998 return 0;
959 999
960 opp = dev_pm_opp_find_freq_exact(dev, freq, true); 1000 opp = dev_pm_opp_find_freq_exact(dev, freq, true);
961 if (IS_ERR(opp)) 1001 if (IS_ERR(opp))
962 return 0; 1002 return 0;
963 1003
964 np = dev_pm_opp_get_of_node(opp); 1004 val = dev_pm_opp_get_level(opp);
965
966 if (np) {
967 of_property_read_u32(np, "opp-level", &val);
968 of_node_put(np);
969 }
970 1005
971 dev_pm_opp_put(opp); 1006 dev_pm_opp_put(opp);
972 1007
@@ -1002,7 +1037,7 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
1002 /* Construct a vote for each frequency */ 1037 /* Construct a vote for each frequency */
1003 for (i = 0; i < freqs_count; i++) { 1038 for (i = 0; i < freqs_count; i++) {
1004 u8 pindex = 0, sindex = 0; 1039 u8 pindex = 0, sindex = 0;
1005 u32 level = a6xx_gmu_get_arc_level(dev, freqs[i]); 1040 unsigned int level = a6xx_gmu_get_arc_level(dev, freqs[i]);
1006 1041
1007 /* Get the primary index that matches the arc level */ 1042 /* Get the primary index that matches the arc level */
1008 for (j = 0; j < pri_count; j++) { 1043 for (j = 0; j < pri_count; j++) {
@@ -1195,9 +1230,15 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
1195 if (IS_ERR_OR_NULL(gmu->mmio)) 1230 if (IS_ERR_OR_NULL(gmu->mmio))
1196 return; 1231 return;
1197 1232
1198 pm_runtime_disable(gmu->dev);
1199 a6xx_gmu_stop(a6xx_gpu); 1233 a6xx_gmu_stop(a6xx_gpu);
1200 1234
1235 pm_runtime_disable(gmu->dev);
1236
1237 if (!IS_ERR(gmu->gxpd)) {
1238 pm_runtime_disable(gmu->gxpd);
1239 dev_pm_domain_detach(gmu->gxpd, false);
1240 }
1241
1201 a6xx_gmu_irq_disable(gmu); 1242 a6xx_gmu_irq_disable(gmu);
1202 a6xx_gmu_memory_free(gmu, gmu->hfi); 1243 a6xx_gmu_memory_free(gmu, gmu->hfi);
1203 1244
@@ -1223,7 +1264,6 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
1223 gmu->idle_level = GMU_IDLE_STATE_ACTIVE; 1264 gmu->idle_level = GMU_IDLE_STATE_ACTIVE;
1224 1265
1225 pm_runtime_enable(gmu->dev); 1266 pm_runtime_enable(gmu->dev);
1226 gmu->gx = devm_regulator_get(gmu->dev, "vdd");
1227 1267
1228 /* Get the list of clocks */ 1268 /* Get the list of clocks */
1229 ret = a6xx_gmu_clocks_probe(gmu); 1269 ret = a6xx_gmu_clocks_probe(gmu);
@@ -1257,6 +1297,12 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
1257 if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0) 1297 if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0)
1258 goto err; 1298 goto err;
1259 1299
1300 /*
1301 * Get a link to the GX power domain to reset the GPU in case of GMU
1302 * crash
1303 */
1304 gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");
1305
1260 /* Get the power levels for the GMU and GPU */ 1306 /* Get the power levels for the GMU and GPU */
1261 a6xx_gmu_pwrlevels_probe(gmu); 1307 a6xx_gmu_pwrlevels_probe(gmu);
1262 1308
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index c721d9165d8e..bedd8e6a63aa 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -27,9 +27,6 @@ struct a6xx_gmu_bo {
27/* the GMU is coming up for the first time or back from a power collapse */ 27/* the GMU is coming up for the first time or back from a power collapse */
28#define GMU_COLD_BOOT 1 28#define GMU_COLD_BOOT 1
29 29
30/* The GMU is being soft reset after a fault */
31#define GMU_RESET 2
32
33/* 30/*
34 * These define the level of control that the GMU has - the higher the number 31 * These define the level of control that the GMU has - the higher the number
35 * the more things that the GMU hardware controls on its own. 32 * the more things that the GMU hardware controls on its own.
@@ -52,11 +49,11 @@ struct a6xx_gmu {
52 int hfi_irq; 49 int hfi_irq;
53 int gmu_irq; 50 int gmu_irq;
54 51
55 struct regulator *gx;
56
57 struct iommu_domain *domain; 52 struct iommu_domain *domain;
58 u64 uncached_iova_base; 53 u64 uncached_iova_base;
59 54
55 struct device *gxpd;
56
60 int idle_level; 57 int idle_level;
61 58
62 struct a6xx_gmu_bo *hfi; 59 struct a6xx_gmu_bo *hfi;
@@ -78,7 +75,7 @@ struct a6xx_gmu {
78 75
79 struct a6xx_hfi_queue queues[2]; 76 struct a6xx_hfi_queue queues[2];
80 77
81 struct tasklet_struct hfi_tasklet; 78 bool hung;
82}; 79};
83 80
84static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) 81static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index fefe773c989e..ec24508b9d68 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -10,6 +10,8 @@
10 10
11#include <linux/devfreq.h> 11#include <linux/devfreq.h>
12 12
13#define GPU_PAS_ID 13
14
13static inline bool _a6xx_check_idle(struct msm_gpu *gpu) 15static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
14{ 16{
15 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 17 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -343,6 +345,20 @@ static int a6xx_ucode_init(struct msm_gpu *gpu)
343 return 0; 345 return 0;
344} 346}
345 347
348static int a6xx_zap_shader_init(struct msm_gpu *gpu)
349{
350 static bool loaded;
351 int ret;
352
353 if (loaded)
354 return 0;
355
356 ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
357
358 loaded = !ret;
359 return ret;
360}
361
346#define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \ 362#define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
347 A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \ 363 A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
348 A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \ 364 A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
@@ -491,7 +507,27 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
491 if (ret) 507 if (ret)
492 goto out; 508 goto out;
493 509
494 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0); 510 /*
511 * Try to load a zap shader into the secure world. If successful
512 * we can use the CP to switch out of secure mode. If not then we
513 * have no resource but to try to switch ourselves out manually. If we
514 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
515 * be blocked and a permissions violation will soon follow.
516 */
517 ret = a6xx_zap_shader_init(gpu);
518 if (!ret) {
519 OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
520 OUT_RING(gpu->rb[0], 0x00000000);
521
522 a6xx_flush(gpu, gpu->rb[0]);
523 if (!a6xx_idle(gpu, gpu->rb[0]))
524 return -EINVAL;
525 } else {
526 /* Print a warning so if we die, we know why */
527 dev_warn_once(gpu->dev->dev,
528 "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
529 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
530 }
495 531
496out: 532out:
497 /* 533 /*
@@ -678,13 +714,15 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
678 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 714 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
679 int ret; 715 int ret;
680 716
681 ret = a6xx_gmu_resume(a6xx_gpu);
682
683 gpu->needs_hw_init = true; 717 gpu->needs_hw_init = true;
684 718
719 ret = a6xx_gmu_resume(a6xx_gpu);
720 if (ret)
721 return ret;
722
685 msm_gpu_resume_devfreq(gpu); 723 msm_gpu_resume_devfreq(gpu);
686 724
687 return ret; 725 return 0;
688} 726}
689 727
690static int a6xx_pm_suspend(struct msm_gpu *gpu) 728static int a6xx_pm_suspend(struct msm_gpu *gpu)
@@ -694,18 +732,6 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
694 732
695 devfreq_suspend_device(gpu->devfreq.devfreq); 733 devfreq_suspend_device(gpu->devfreq.devfreq);
696 734
697 /*
698 * Make sure the GMU is idle before continuing (because some transitions
699 * may use VBIF
700 */
701 a6xx_gmu_wait_for_idle(a6xx_gpu);
702
703 /* Clear the VBIF pipe before shutting down */
704 /* FIXME: This accesses the GPU - do we need to make sure it is on? */
705 gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf);
706 spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & 0xf) == 0xf);
707 gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0);
708
709 return a6xx_gmu_stop(a6xx_gpu); 735 return a6xx_gmu_stop(a6xx_gpu);
710} 736}
711 737
@@ -781,14 +807,16 @@ static const struct adreno_gpu_funcs funcs = {
781 .active_ring = a6xx_active_ring, 807 .active_ring = a6xx_active_ring,
782 .irq = a6xx_irq, 808 .irq = a6xx_irq,
783 .destroy = a6xx_destroy, 809 .destroy = a6xx_destroy,
784#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) 810#if defined(CONFIG_DRM_MSM_GPU_STATE)
785 .show = a6xx_show, 811 .show = a6xx_show,
786#endif 812#endif
787 .gpu_busy = a6xx_gpu_busy, 813 .gpu_busy = a6xx_gpu_busy,
788 .gpu_get_freq = a6xx_gmu_get_freq, 814 .gpu_get_freq = a6xx_gmu_get_freq,
789 .gpu_set_freq = a6xx_gmu_set_freq, 815 .gpu_set_freq = a6xx_gmu_set_freq,
816#if defined(CONFIG_DRM_MSM_GPU_STATE)
790 .gpu_state_get = a6xx_gpu_state_get, 817 .gpu_state_get = a6xx_gpu_state_get,
791 .gpu_state_put = a6xx_gpu_state_put, 818 .gpu_state_put = a6xx_gpu_state_put,
819#endif
792 }, 820 },
793 .get_timestamp = a6xx_get_timestamp, 821 .get_timestamp = a6xx_get_timestamp,
794}; 822};
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index 528a4cfe07cd..b46279eb18c5 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -46,9 +46,8 @@ struct a6xx_gpu {
46int a6xx_gmu_resume(struct a6xx_gpu *gpu); 46int a6xx_gmu_resume(struct a6xx_gpu *gpu);
47int a6xx_gmu_stop(struct a6xx_gpu *gpu); 47int a6xx_gmu_stop(struct a6xx_gpu *gpu);
48 48
49int a6xx_gmu_wait_for_idle(struct a6xx_gpu *gpu); 49int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu);
50 50
51int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu);
52bool a6xx_gmu_isidle(struct a6xx_gmu *gmu); 51bool a6xx_gmu_isidle(struct a6xx_gmu *gmu);
53 52
54int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); 53int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 714ed6505e47..b907245d3d96 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -155,6 +155,7 @@ static const struct adreno_info gpulist[] = {
155 .gmem = SZ_1M, 155 .gmem = SZ_1M,
156 .inactive_period = DRM_MSM_INACTIVE_PERIOD, 156 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
157 .init = a6xx_gpu_init, 157 .init = a6xx_gpu_init,
158 .zapfw = "a630_zap.mdt",
158 }, 159 },
159}; 160};
160 161
@@ -229,6 +230,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
229 230
230 ret = pm_runtime_get_sync(&pdev->dev); 231 ret = pm_runtime_get_sync(&pdev->dev);
231 if (ret < 0) { 232 if (ret < 0) {
233 pm_runtime_put_sync(&pdev->dev);
232 DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret); 234 DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
233 return NULL; 235 return NULL;
234 } 236 }
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 27898475cdf4..6f7f4114afcf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -19,13 +19,148 @@
19 19
20#include <linux/ascii85.h> 20#include <linux/ascii85.h>
21#include <linux/interconnect.h> 21#include <linux/interconnect.h>
22#include <linux/qcom_scm.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/of_address.h>
23#include <linux/pm_opp.h> 25#include <linux/pm_opp.h>
24#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/soc/qcom/mdt_loader.h>
25#include "adreno_gpu.h" 28#include "adreno_gpu.h"
26#include "msm_gem.h" 29#include "msm_gem.h"
27#include "msm_mmu.h" 30#include "msm_mmu.h"
28 31
32static bool zap_available = true;
33
34static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
35 u32 pasid)
36{
37 struct device *dev = &gpu->pdev->dev;
38 const struct firmware *fw;
39 struct device_node *np, *mem_np;
40 struct resource r;
41 phys_addr_t mem_phys;
42 ssize_t mem_size;
43 void *mem_region = NULL;
44 int ret;
45
46 if (!IS_ENABLED(CONFIG_ARCH_QCOM)) {
47 zap_available = false;
48 return -EINVAL;
49 }
50
51 np = of_get_child_by_name(dev->of_node, "zap-shader");
52 if (!np) {
53 zap_available = false;
54 return -ENODEV;
55 }
56
57 mem_np = of_parse_phandle(np, "memory-region", 0);
58 of_node_put(np);
59 if (!mem_np) {
60 zap_available = false;
61 return -EINVAL;
62 }
63
64 ret = of_address_to_resource(mem_np, 0, &r);
65 of_node_put(mem_np);
66 if (ret)
67 return ret;
68
69 mem_phys = r.start;
70 mem_size = resource_size(&r);
71
72 /* Request the MDT file for the firmware */
73 fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
74 if (IS_ERR(fw)) {
75 DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
76 return PTR_ERR(fw);
77 }
78
79 /* Figure out how much memory we need */
80 mem_size = qcom_mdt_get_size(fw);
81 if (mem_size < 0) {
82 ret = mem_size;
83 goto out;
84 }
85
86 /* Allocate memory for the firmware image */
87 mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
88 if (!mem_region) {
89 ret = -ENOMEM;
90 goto out;
91 }
92
93 /*
94 * Load the rest of the MDT
95 *
96 * Note that we could be dealing with two different paths, since
97 * with upstream linux-firmware it would be in a qcom/ subdir..
98 * adreno_request_fw() handles this, but qcom_mdt_load() does
99 * not. But since we've already gotten through adreno_request_fw()
100 * we know which of the two cases it is:
101 */
102 if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
103 ret = qcom_mdt_load(dev, fw, fwname, pasid,
104 mem_region, mem_phys, mem_size, NULL);
105 } else {
106 char *newname;
107
108 newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
109
110 ret = qcom_mdt_load(dev, fw, newname, pasid,
111 mem_region, mem_phys, mem_size, NULL);
112 kfree(newname);
113 }
114 if (ret)
115 goto out;
116
117 /* Send the image to the secure world */
118 ret = qcom_scm_pas_auth_and_reset(pasid);
119
120 /*
121 * If the scm call returns -EOPNOTSUPP we assume that this target
122 * doesn't need/support the zap shader so quietly fail
123 */
124 if (ret == -EOPNOTSUPP)
125 zap_available = false;
126 else if (ret)
127 DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
128
129out:
130 if (mem_region)
131 memunmap(mem_region);
132
133 release_firmware(fw);
134
135 return ret;
136}
137
138int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
139{
140 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
141 struct platform_device *pdev = gpu->pdev;
142
143 /* Short cut if we determine the zap shader isn't available/needed */
144 if (!zap_available)
145 return -ENODEV;
146
147 /* We need SCM to be able to load the firmware */
148 if (!qcom_scm_is_available()) {
149 DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
150 return -EPROBE_DEFER;
151 }
152
153 /* Each GPU has a target specific zap shader firmware name to use */
154 if (!adreno_gpu->info->zapfw) {
155 zap_available = false;
156 DRM_DEV_ERROR(&pdev->dev,
157 "Zap shader firmware file not specified for this target\n");
158 return -ENODEV;
159 }
160
161 return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
162}
163
29int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) 164int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
30{ 165{
31 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 166 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -63,6 +198,12 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
63 case MSM_PARAM_NR_RINGS: 198 case MSM_PARAM_NR_RINGS:
64 *value = gpu->nr_rings; 199 *value = gpu->nr_rings;
65 return 0; 200 return 0;
201 case MSM_PARAM_PP_PGTABLE:
202 *value = 0;
203 return 0;
204 case MSM_PARAM_FAULTS:
205 *value = gpu->global_faults;
206 return 0;
66 default: 207 default:
67 DBG("%s: invalid param: %u", gpu->name, param); 208 DBG("%s: invalid param: %u", gpu->name, param);
68 return -EINVAL; 209 return -EINVAL;
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 5db459bc28a7..0925606ec9b5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -252,6 +252,12 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state);
252int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state); 252int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
253int adreno_gpu_state_put(struct msm_gpu_state *state); 253int adreno_gpu_state_put(struct msm_gpu_state *state);
254 254
255/*
256 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
257 * out of secure mode
258 */
259int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid);
260
255/* ringbuffer helpers (the parts that are adreno specific) */ 261/* ringbuffer helpers (the parts that are adreno specific) */
256 262
257static inline void 263static inline void
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b776fca571f3..dfdfa766da8f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -46,6 +46,9 @@
46#define LEFT_MIXER 0 46#define LEFT_MIXER 0
47#define RIGHT_MIXER 1 47#define RIGHT_MIXER 1
48 48
49/* timeout in ms waiting for frame done */
50#define DPU_CRTC_FRAME_DONE_TIMEOUT_MS 60
51
49static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) 52static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
50{ 53{
51 struct msm_drm_private *priv = crtc->dev->dev_private; 54 struct msm_drm_private *priv = crtc->dev->dev_private;
@@ -425,65 +428,6 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc,
425 trace_dpu_crtc_complete_commit(DRMID(crtc)); 428 trace_dpu_crtc_complete_commit(DRMID(crtc));
426} 429}
427 430
428static void _dpu_crtc_setup_mixer_for_encoder(
429 struct drm_crtc *crtc,
430 struct drm_encoder *enc)
431{
432 struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
433 struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
434 struct dpu_rm *rm = &dpu_kms->rm;
435 struct dpu_crtc_mixer *mixer;
436 struct dpu_hw_ctl *last_valid_ctl = NULL;
437 int i;
438 struct dpu_rm_hw_iter lm_iter, ctl_iter;
439
440 dpu_rm_init_hw_iter(&lm_iter, enc->base.id, DPU_HW_BLK_LM);
441 dpu_rm_init_hw_iter(&ctl_iter, enc->base.id, DPU_HW_BLK_CTL);
442
443 /* Set up all the mixers and ctls reserved by this encoder */
444 for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++) {
445 mixer = &cstate->mixers[i];
446
447 if (!dpu_rm_get_hw(rm, &lm_iter))
448 break;
449 mixer->hw_lm = (struct dpu_hw_mixer *)lm_iter.hw;
450
451 /* CTL may be <= LMs, if <, multiple LMs controlled by 1 CTL */
452 if (!dpu_rm_get_hw(rm, &ctl_iter)) {
453 DPU_DEBUG("no ctl assigned to lm %d, using previous\n",
454 mixer->hw_lm->idx - LM_0);
455 mixer->lm_ctl = last_valid_ctl;
456 } else {
457 mixer->lm_ctl = (struct dpu_hw_ctl *)ctl_iter.hw;
458 last_valid_ctl = mixer->lm_ctl;
459 }
460
461 /* Shouldn't happen, mixers are always >= ctls */
462 if (!mixer->lm_ctl) {
463 DPU_ERROR("no valid ctls found for lm %d\n",
464 mixer->hw_lm->idx - LM_0);
465 return;
466 }
467
468 cstate->num_mixers++;
469 DPU_DEBUG("setup mixer %d: lm %d\n",
470 i, mixer->hw_lm->idx - LM_0);
471 DPU_DEBUG("setup mixer %d: ctl %d\n",
472 i, mixer->lm_ctl->idx - CTL_0);
473 }
474}
475
476static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
477{
478 struct drm_encoder *enc;
479
480 WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
481
482 /* Check for mixers on all encoders attached to this crtc */
483 drm_for_each_encoder_mask(enc, crtc->dev, crtc->state->encoder_mask)
484 _dpu_crtc_setup_mixer_for_encoder(crtc, enc);
485}
486
487static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, 431static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
488 struct drm_crtc_state *state) 432 struct drm_crtc_state *state)
489{ 433{
@@ -533,10 +477,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
533 dev = crtc->dev; 477 dev = crtc->dev;
534 smmu_state = &dpu_crtc->smmu_state; 478 smmu_state = &dpu_crtc->smmu_state;
535 479
536 if (!cstate->num_mixers) { 480 _dpu_crtc_setup_lm_bounds(crtc, crtc->state);
537 _dpu_crtc_setup_mixers(crtc);
538 _dpu_crtc_setup_lm_bounds(crtc, crtc->state);
539 }
540 481
541 if (dpu_crtc->event) { 482 if (dpu_crtc->event) {
542 WARN_ON(dpu_crtc->event); 483 WARN_ON(dpu_crtc->event);
@@ -683,7 +624,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc)
683 624
684 DPU_ATRACE_BEGIN("frame done completion wait"); 625 DPU_ATRACE_BEGIN("frame done completion wait");
685 ret = wait_for_completion_timeout(&dpu_crtc->frame_done_comp, 626 ret = wait_for_completion_timeout(&dpu_crtc->frame_done_comp,
686 msecs_to_jiffies(DPU_FRAME_DONE_TIMEOUT)); 627 msecs_to_jiffies(DPU_CRTC_FRAME_DONE_TIMEOUT_MS));
687 if (!ret) { 628 if (!ret) {
688 DRM_ERROR("frame done wait timed out, ret:%d\n", ret); 629 DRM_ERROR("frame done wait timed out, ret:%d\n", ret);
689 rc = -ETIMEDOUT; 630 rc = -ETIMEDOUT;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 5aa3307f3f0c..82bf16d61a45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -69,6 +69,9 @@
69 69
70#define MAX_VDISPLAY_SPLIT 1080 70#define MAX_VDISPLAY_SPLIT 1080
71 71
72/* timeout in frames waiting for frame done */
73#define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
74
72/** 75/**
73 * enum dpu_enc_rc_events - events for resource control state machine 76 * enum dpu_enc_rc_events - events for resource control state machine
74 * @DPU_ENC_RC_EVENT_KICKOFF: 77 * @DPU_ENC_RC_EVENT_KICKOFF:
@@ -158,7 +161,7 @@ enum dpu_enc_rc_states {
158 * Bit0 = phys_encs[0] etc. 161 * Bit0 = phys_encs[0] etc.
159 * @crtc_frame_event_cb: callback handler for frame event 162 * @crtc_frame_event_cb: callback handler for frame event
160 * @crtc_frame_event_cb_data: callback handler private data 163 * @crtc_frame_event_cb_data: callback handler private data
161 * @frame_done_timeout: frame done timeout in Hz 164 * @frame_done_timeout_ms: frame done timeout in ms
162 * @frame_done_timer: watchdog timer for frame done event 165 * @frame_done_timer: watchdog timer for frame done event
163 * @vsync_event_timer: vsync timer 166 * @vsync_event_timer: vsync timer
164 * @disp_info: local copy of msm_display_info struct 167 * @disp_info: local copy of msm_display_info struct
@@ -196,7 +199,7 @@ struct dpu_encoder_virt {
196 void (*crtc_frame_event_cb)(void *, u32 event); 199 void (*crtc_frame_event_cb)(void *, u32 event);
197 void *crtc_frame_event_cb_data; 200 void *crtc_frame_event_cb_data;
198 201
199 atomic_t frame_done_timeout; 202 atomic_t frame_done_timeout_ms;
200 struct timer_list frame_done_timer; 203 struct timer_list frame_done_timer;
201 struct timer_list vsync_event_timer; 204 struct timer_list vsync_event_timer;
202 205
@@ -520,8 +523,8 @@ static void _dpu_encoder_adjust_mode(struct drm_connector *connector,
520 523
521 list_for_each_entry(cur_mode, &connector->modes, head) { 524 list_for_each_entry(cur_mode, &connector->modes, head) {
522 if (cur_mode->vdisplay == adj_mode->vdisplay && 525 if (cur_mode->vdisplay == adj_mode->vdisplay &&
523 cur_mode->hdisplay == adj_mode->hdisplay && 526 cur_mode->hdisplay == adj_mode->hdisplay &&
524 cur_mode->vrefresh == adj_mode->vrefresh) { 527 drm_mode_vrefresh(cur_mode) == drm_mode_vrefresh(adj_mode)) {
525 adj_mode->private = cur_mode->private; 528 adj_mode->private = cur_mode->private;
526 adj_mode->private_flags |= cur_mode->private_flags; 529 adj_mode->private_flags |= cur_mode->private_flags;
527 } 530 }
@@ -959,10 +962,14 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
959 struct dpu_kms *dpu_kms; 962 struct dpu_kms *dpu_kms;
960 struct list_head *connector_list; 963 struct list_head *connector_list;
961 struct drm_connector *conn = NULL, *conn_iter; 964 struct drm_connector *conn = NULL, *conn_iter;
962 struct dpu_rm_hw_iter pp_iter, ctl_iter; 965 struct drm_crtc *drm_crtc;
966 struct dpu_crtc_state *cstate;
967 struct dpu_rm_hw_iter hw_iter;
963 struct msm_display_topology topology; 968 struct msm_display_topology topology;
964 struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; 969 struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL };
965 int i = 0, ret; 970 struct dpu_hw_mixer *hw_lm[MAX_CHANNELS_PER_ENC] = { NULL };
971 int num_lm = 0, num_ctl = 0;
972 int i, j, ret;
966 973
967 if (!drm_enc) { 974 if (!drm_enc) {
968 DPU_ERROR("invalid encoder\n"); 975 DPU_ERROR("invalid encoder\n");
@@ -990,10 +997,14 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
990 return; 997 return;
991 } 998 }
992 999
1000 drm_for_each_crtc(drm_crtc, drm_enc->dev)
1001 if (drm_crtc->state->encoder_mask & drm_encoder_mask(drm_enc))
1002 break;
1003
993 topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); 1004 topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
994 1005
995 /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ 1006 /* Reserve dynamic resources now. Indicating non-AtomicTest phase */
996 ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_enc->crtc->state, 1007 ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_crtc->state,
997 topology, false); 1008 topology, false);
998 if (ret) { 1009 if (ret) {
999 DPU_ERROR_ENC(dpu_enc, 1010 DPU_ERROR_ENC(dpu_enc,
@@ -1001,21 +1012,41 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
1001 return; 1012 return;
1002 } 1013 }
1003 1014
1004 dpu_rm_init_hw_iter(&pp_iter, drm_enc->base.id, DPU_HW_BLK_PINGPONG); 1015 dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_PINGPONG);
1005 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { 1016 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1006 dpu_enc->hw_pp[i] = NULL; 1017 dpu_enc->hw_pp[i] = NULL;
1007 if (!dpu_rm_get_hw(&dpu_kms->rm, &pp_iter)) 1018 if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter))
1019 break;
1020 dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) hw_iter.hw;
1021 }
1022
1023 dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_CTL);
1024 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1025 if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter))
1008 break; 1026 break;
1009 dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) pp_iter.hw; 1027 hw_ctl[i] = (struct dpu_hw_ctl *)hw_iter.hw;
1028 num_ctl++;
1010 } 1029 }
1011 1030
1012 dpu_rm_init_hw_iter(&ctl_iter, drm_enc->base.id, DPU_HW_BLK_CTL); 1031 dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_LM);
1013 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { 1032 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1014 if (!dpu_rm_get_hw(&dpu_kms->rm, &ctl_iter)) 1033 if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter))
1015 break; 1034 break;
1016 hw_ctl[i] = (struct dpu_hw_ctl *)ctl_iter.hw; 1035 hw_lm[i] = (struct dpu_hw_mixer *)hw_iter.hw;
1036 num_lm++;
1017 } 1037 }
1018 1038
1039 cstate = to_dpu_crtc_state(drm_crtc->state);
1040
1041 for (i = 0; i < num_lm; i++) {
1042 int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
1043
1044 cstate->mixers[i].hw_lm = hw_lm[i];
1045 cstate->mixers[i].lm_ctl = hw_ctl[ctl_idx];
1046 }
1047
1048 cstate->num_mixers = num_lm;
1049
1019 for (i = 0; i < dpu_enc->num_phys_encs; i++) { 1050 for (i = 0; i < dpu_enc->num_phys_encs; i++) {
1020 struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; 1051 struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
1021 1052
@@ -1023,18 +1054,38 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
1023 if (!dpu_enc->hw_pp[i]) { 1054 if (!dpu_enc->hw_pp[i]) {
1024 DPU_ERROR_ENC(dpu_enc, "no pp block assigned" 1055 DPU_ERROR_ENC(dpu_enc, "no pp block assigned"
1025 "at idx: %d\n", i); 1056 "at idx: %d\n", i);
1026 return; 1057 goto error;
1027 } 1058 }
1028 1059
1029 if (!hw_ctl[i]) { 1060 if (!hw_ctl[i]) {
1030 DPU_ERROR_ENC(dpu_enc, "no ctl block assigned" 1061 DPU_ERROR_ENC(dpu_enc, "no ctl block assigned"
1031 "at idx: %d\n", i); 1062 "at idx: %d\n", i);
1032 return; 1063 goto error;
1033 } 1064 }
1034 1065
1035 phys->hw_pp = dpu_enc->hw_pp[i]; 1066 phys->hw_pp = dpu_enc->hw_pp[i];
1036 phys->hw_ctl = hw_ctl[i]; 1067 phys->hw_ctl = hw_ctl[i];
1037 1068
1069 dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id,
1070 DPU_HW_BLK_INTF);
1071 for (j = 0; j < MAX_CHANNELS_PER_ENC; j++) {
1072 struct dpu_hw_intf *hw_intf;
1073
1074 if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter))
1075 break;
1076
1077 hw_intf = (struct dpu_hw_intf *)hw_iter.hw;
1078 if (hw_intf->idx == phys->intf_idx)
1079 phys->hw_intf = hw_intf;
1080 }
1081
1082 if (!phys->hw_intf) {
1083 DPU_ERROR_ENC(dpu_enc,
1084 "no intf block assigned at idx: %d\n",
1085 i);
1086 goto error;
1087 }
1088
1038 phys->connector = conn->state->connector; 1089 phys->connector = conn->state->connector;
1039 if (phys->ops.mode_set) 1090 if (phys->ops.mode_set)
1040 phys->ops.mode_set(phys, mode, adj_mode); 1091 phys->ops.mode_set(phys, mode, adj_mode);
@@ -1042,6 +1093,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
1042 } 1093 }
1043 1094
1044 dpu_enc->mode_set_complete = true; 1095 dpu_enc->mode_set_complete = true;
1096
1097error:
1098 dpu_rm_release(&dpu_kms->rm, drm_enc);
1045} 1099}
1046 1100
1047static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) 1101static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
@@ -1182,7 +1236,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
1182 } 1236 }
1183 1237
1184 /* after phys waits for frame-done, should be no more frames pending */ 1238 /* after phys waits for frame-done, should be no more frames pending */
1185 if (atomic_xchg(&dpu_enc->frame_done_timeout, 0)) { 1239 if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
1186 DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id); 1240 DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id);
1187 del_timer_sync(&dpu_enc->frame_done_timer); 1241 del_timer_sync(&dpu_enc->frame_done_timer);
1188 } 1242 }
@@ -1339,7 +1393,7 @@ static void dpu_encoder_frame_done_callback(
1339 } 1393 }
1340 1394
1341 if (!dpu_enc->frame_busy_mask[0]) { 1395 if (!dpu_enc->frame_busy_mask[0]) {
1342 atomic_set(&dpu_enc->frame_done_timeout, 0); 1396 atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
1343 del_timer(&dpu_enc->frame_done_timer); 1397 del_timer(&dpu_enc->frame_done_timer);
1344 1398
1345 dpu_encoder_resource_control(drm_enc, 1399 dpu_encoder_resource_control(drm_enc,
@@ -1547,8 +1601,14 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc,
1547 if (!ctl) 1601 if (!ctl)
1548 continue; 1602 continue;
1549 1603
1550 if (phys->split_role != ENC_ROLE_SLAVE) 1604 /*
1605 * This is cleared in frame_done worker, which isn't invoked
1606 * for async commits. So don't set this for async, since it'll
1607 * roll over to the next commit.
1608 */
1609 if (!async && phys->split_role != ENC_ROLE_SLAVE)
1551 set_bit(i, dpu_enc->frame_busy_mask); 1610 set_bit(i, dpu_enc->frame_busy_mask);
1611
1552 if (!phys->ops.needs_single_flush || 1612 if (!phys->ops.needs_single_flush ||
1553 !phys->ops.needs_single_flush(phys)) 1613 !phys->ops.needs_single_flush(phys))
1554 _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0, 1614 _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0,
@@ -1800,11 +1860,20 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async)
1800 1860
1801 trace_dpu_enc_kickoff(DRMID(drm_enc)); 1861 trace_dpu_enc_kickoff(DRMID(drm_enc));
1802 1862
1803 atomic_set(&dpu_enc->frame_done_timeout, 1863 /*
1804 DPU_FRAME_DONE_TIMEOUT * 1000 / 1864 * Asynchronous frames don't handle FRAME_DONE events. As such, they
1805 drm_enc->crtc->state->adjusted_mode.vrefresh); 1865 * shouldn't enable the frame_done watchdog since it will always time
1806 mod_timer(&dpu_enc->frame_done_timer, jiffies + 1866 * out.
1807 ((atomic_read(&dpu_enc->frame_done_timeout) * HZ) / 1000)); 1867 */
1868 if (!async) {
1869 unsigned long timeout_ms;
1870 timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 /
1871 drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode);
1872
1873 atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms);
1874 mod_timer(&dpu_enc->frame_done_timer,
1875 jiffies + msecs_to_jiffies(timeout_ms));
1876 }
1808 1877
1809 /* All phys encs are ready to go, trigger the kickoff */ 1878 /* All phys encs are ready to go, trigger the kickoff */
1810 _dpu_encoder_kickoff_phys(dpu_enc, async); 1879 _dpu_encoder_kickoff_phys(dpu_enc, async);
@@ -2124,7 +2193,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
2124 DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n", 2193 DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
2125 DRMID(drm_enc), dpu_enc->frame_busy_mask[0]); 2194 DRMID(drm_enc), dpu_enc->frame_busy_mask[0]);
2126 return; 2195 return;
2127 } else if (!atomic_xchg(&dpu_enc->frame_done_timeout, 0)) { 2196 } else if (!atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
2128 DRM_DEBUG_KMS("id:%u invalid timeout\n", DRMID(drm_enc)); 2197 DRM_DEBUG_KMS("id:%u invalid timeout\n", DRMID(drm_enc));
2129 return; 2198 return;
2130 } 2199 }
@@ -2170,7 +2239,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
2170 2239
2171 spin_lock_init(&dpu_enc->enc_spinlock); 2240 spin_lock_init(&dpu_enc->enc_spinlock);
2172 2241
2173 atomic_set(&dpu_enc->frame_done_timeout, 0); 2242 atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
2174 timer_setup(&dpu_enc->frame_done_timer, 2243 timer_setup(&dpu_enc->frame_done_timer,
2175 dpu_encoder_frame_done_timeout, 0); 2244 dpu_encoder_frame_done_timeout, 0);
2176 2245
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index db94f3d3bea3..97fb868a4ef6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -200,6 +200,7 @@ struct dpu_encoder_irq {
200 * @hw_mdptop: Hardware interface to the top registers 200 * @hw_mdptop: Hardware interface to the top registers
201 * @hw_ctl: Hardware interface to the ctl registers 201 * @hw_ctl: Hardware interface to the ctl registers
202 * @hw_pp: Hardware interface to the ping pong registers 202 * @hw_pp: Hardware interface to the ping pong registers
203 * @hw_intf: Hardware interface to the intf registers
203 * @dpu_kms: Pointer to the dpu_kms top level 204 * @dpu_kms: Pointer to the dpu_kms top level
204 * @cached_mode: DRM mode cached at mode_set time, acted on in enable 205 * @cached_mode: DRM mode cached at mode_set time, acted on in enable
205 * @enabled: Whether the encoder has enabled and running a mode 206 * @enabled: Whether the encoder has enabled and running a mode
@@ -228,6 +229,7 @@ struct dpu_encoder_phys {
228 struct dpu_hw_mdp *hw_mdptop; 229 struct dpu_hw_mdp *hw_mdptop;
229 struct dpu_hw_ctl *hw_ctl; 230 struct dpu_hw_ctl *hw_ctl;
230 struct dpu_hw_pingpong *hw_pp; 231 struct dpu_hw_pingpong *hw_pp;
232 struct dpu_hw_intf *hw_intf;
231 struct dpu_kms *dpu_kms; 233 struct dpu_kms *dpu_kms;
232 struct drm_display_mode cached_mode; 234 struct drm_display_mode cached_mode;
233 enum dpu_enc_split_role split_role; 235 enum dpu_enc_split_role split_role;
@@ -251,19 +253,6 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
251} 253}
252 254
253/** 255/**
254 * struct dpu_encoder_phys_vid - sub-class of dpu_encoder_phys to handle video
255 * mode specific operations
256 * @base: Baseclass physical encoder structure
257 * @hw_intf: Hardware interface to the intf registers
258 * @timing_params: Current timing parameter
259 */
260struct dpu_encoder_phys_vid {
261 struct dpu_encoder_phys base;
262 struct dpu_hw_intf *hw_intf;
263 struct intf_timing_params timing_params;
264};
265
266/**
267 * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command 256 * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command
268 * mode specific operations 257 * mode specific operations
269 * @base: Baseclass physical encoder structure 258 * @base: Baseclass physical encoder structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index a399e1edd313..973737fb5c9f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -404,7 +404,8 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
404 return; 404 return;
405 } 405 }
406 406
407 tc_cfg.vsync_count = vsync_hz / (mode->vtotal * mode->vrefresh); 407 tc_cfg.vsync_count = vsync_hz /
408 (mode->vtotal * drm_mode_vrefresh(mode));
408 409
409 /* enable external TE after kickoff to avoid premature autorefresh */ 410 /* enable external TE after kickoff to avoid premature autorefresh */
410 tc_cfg.hw_vsync_mode = 0; 411 tc_cfg.hw_vsync_mode = 0;
@@ -424,7 +425,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
424 DPU_DEBUG_CMDENC(cmd_enc, 425 DPU_DEBUG_CMDENC(cmd_enc,
425 "tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", 426 "tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n",
426 phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz, 427 phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz,
427 mode->vtotal, mode->vrefresh); 428 mode->vtotal, drm_mode_vrefresh(mode));
428 DPU_DEBUG_CMDENC(cmd_enc, 429 DPU_DEBUG_CMDENC(cmd_enc,
429 "tc %d enable %u start_pos %u rd_ptr_irq %u\n", 430 "tc %d enable %u start_pos %u rd_ptr_irq %u\n",
430 phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos, 431 phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 3c4eb470a82c..1b7a335a6140 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -18,14 +18,14 @@
18#include "dpu_trace.h" 18#include "dpu_trace.h"
19 19
20#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ 20#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
21 (e) && (e)->base.parent ? \ 21 (e) && (e)->parent ? \
22 (e)->base.parent->base.id : -1, \ 22 (e)->parent->base.id : -1, \
23 (e) && (e)->hw_intf ? \ 23 (e) && (e)->hw_intf ? \
24 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) 24 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
25 25
26#define DPU_ERROR_VIDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \ 26#define DPU_ERROR_VIDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \
27 (e) && (e)->base.parent ? \ 27 (e) && (e)->parent ? \
28 (e)->base.parent->base.id : -1, \ 28 (e)->parent->base.id : -1, \
29 (e) && (e)->hw_intf ? \ 29 (e) && (e)->hw_intf ? \
30 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) 30 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
31 31
@@ -44,7 +44,7 @@ static bool dpu_encoder_phys_vid_is_master(
44} 44}
45 45
46static void drm_mode_to_intf_timing_params( 46static void drm_mode_to_intf_timing_params(
47 const struct dpu_encoder_phys_vid *vid_enc, 47 const struct dpu_encoder_phys *phys_enc,
48 const struct drm_display_mode *mode, 48 const struct drm_display_mode *mode,
49 struct intf_timing_params *timing) 49 struct intf_timing_params *timing)
50{ 50{
@@ -92,7 +92,7 @@ static void drm_mode_to_intf_timing_params(
92 timing->hsync_skew = mode->hskew; 92 timing->hsync_skew = mode->hskew;
93 93
94 /* DSI controller cannot handle active-low sync signals. */ 94 /* DSI controller cannot handle active-low sync signals. */
95 if (vid_enc->hw_intf->cap->type == INTF_DSI) { 95 if (phys_enc->hw_intf->cap->type == INTF_DSI) {
96 timing->hsync_polarity = 0; 96 timing->hsync_polarity = 0;
97 timing->vsync_polarity = 0; 97 timing->vsync_polarity = 0;
98 } 98 }
@@ -143,11 +143,11 @@ static u32 get_vertical_total(const struct intf_timing_params *timing)
143 * lines based on the chip worst case latencies. 143 * lines based on the chip worst case latencies.
144 */ 144 */
145static u32 programmable_fetch_get_num_lines( 145static u32 programmable_fetch_get_num_lines(
146 struct dpu_encoder_phys_vid *vid_enc, 146 struct dpu_encoder_phys *phys_enc,
147 const struct intf_timing_params *timing) 147 const struct intf_timing_params *timing)
148{ 148{
149 u32 worst_case_needed_lines = 149 u32 worst_case_needed_lines =
150 vid_enc->hw_intf->cap->prog_fetch_lines_worst_case; 150 phys_enc->hw_intf->cap->prog_fetch_lines_worst_case;
151 u32 start_of_frame_lines = 151 u32 start_of_frame_lines =
152 timing->v_back_porch + timing->vsync_pulse_width; 152 timing->v_back_porch + timing->vsync_pulse_width;
153 u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines; 153 u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines;
@@ -155,26 +155,26 @@ static u32 programmable_fetch_get_num_lines(
155 155
156 /* Fetch must be outside active lines, otherwise undefined. */ 156 /* Fetch must be outside active lines, otherwise undefined. */
157 if (start_of_frame_lines >= worst_case_needed_lines) { 157 if (start_of_frame_lines >= worst_case_needed_lines) {
158 DPU_DEBUG_VIDENC(vid_enc, 158 DPU_DEBUG_VIDENC(phys_enc,
159 "prog fetch is not needed, large vbp+vsw\n"); 159 "prog fetch is not needed, large vbp+vsw\n");
160 actual_vfp_lines = 0; 160 actual_vfp_lines = 0;
161 } else if (timing->v_front_porch < needed_vfp_lines) { 161 } else if (timing->v_front_porch < needed_vfp_lines) {
162 /* Warn fetch needed, but not enough porch in panel config */ 162 /* Warn fetch needed, but not enough porch in panel config */
163 pr_warn_once 163 pr_warn_once
164 ("low vbp+vfp may lead to perf issues in some cases\n"); 164 ("low vbp+vfp may lead to perf issues in some cases\n");
165 DPU_DEBUG_VIDENC(vid_enc, 165 DPU_DEBUG_VIDENC(phys_enc,
166 "less vfp than fetch req, using entire vfp\n"); 166 "less vfp than fetch req, using entire vfp\n");
167 actual_vfp_lines = timing->v_front_porch; 167 actual_vfp_lines = timing->v_front_porch;
168 } else { 168 } else {
169 DPU_DEBUG_VIDENC(vid_enc, "room in vfp for needed prefetch\n"); 169 DPU_DEBUG_VIDENC(phys_enc, "room in vfp for needed prefetch\n");
170 actual_vfp_lines = needed_vfp_lines; 170 actual_vfp_lines = needed_vfp_lines;
171 } 171 }
172 172
173 DPU_DEBUG_VIDENC(vid_enc, 173 DPU_DEBUG_VIDENC(phys_enc,
174 "v_front_porch %u v_back_porch %u vsync_pulse_width %u\n", 174 "v_front_porch %u v_back_porch %u vsync_pulse_width %u\n",
175 timing->v_front_porch, timing->v_back_porch, 175 timing->v_front_porch, timing->v_back_porch,
176 timing->vsync_pulse_width); 176 timing->vsync_pulse_width);
177 DPU_DEBUG_VIDENC(vid_enc, 177 DPU_DEBUG_VIDENC(phys_enc,
178 "wc_lines %u needed_vfp_lines %u actual_vfp_lines %u\n", 178 "wc_lines %u needed_vfp_lines %u actual_vfp_lines %u\n",
179 worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines); 179 worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines);
180 180
@@ -194,8 +194,6 @@ static u32 programmable_fetch_get_num_lines(
194static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, 194static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc,
195 const struct intf_timing_params *timing) 195 const struct intf_timing_params *timing)
196{ 196{
197 struct dpu_encoder_phys_vid *vid_enc =
198 to_dpu_encoder_phys_vid(phys_enc);
199 struct intf_prog_fetch f = { 0 }; 197 struct intf_prog_fetch f = { 0 };
200 u32 vfp_fetch_lines = 0; 198 u32 vfp_fetch_lines = 0;
201 u32 horiz_total = 0; 199 u32 horiz_total = 0;
@@ -203,10 +201,10 @@ static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc,
203 u32 vfp_fetch_start_vsync_counter = 0; 201 u32 vfp_fetch_start_vsync_counter = 0;
204 unsigned long lock_flags; 202 unsigned long lock_flags;
205 203
206 if (WARN_ON_ONCE(!vid_enc->hw_intf->ops.setup_prg_fetch)) 204 if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch))
207 return; 205 return;
208 206
209 vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing); 207 vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing);
210 if (vfp_fetch_lines) { 208 if (vfp_fetch_lines) {
211 vert_total = get_vertical_total(timing); 209 vert_total = get_vertical_total(timing);
212 horiz_total = get_horizontal_total(timing); 210 horiz_total = get_horizontal_total(timing);
@@ -216,12 +214,12 @@ static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc,
216 f.fetch_start = vfp_fetch_start_vsync_counter; 214 f.fetch_start = vfp_fetch_start_vsync_counter;
217 } 215 }
218 216
219 DPU_DEBUG_VIDENC(vid_enc, 217 DPU_DEBUG_VIDENC(phys_enc,
220 "vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u\n", 218 "vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u\n",
221 vfp_fetch_lines, vfp_fetch_start_vsync_counter); 219 vfp_fetch_lines, vfp_fetch_start_vsync_counter);
222 220
223 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 221 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
224 vid_enc->hw_intf->ops.setup_prg_fetch(vid_enc->hw_intf, &f); 222 phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f);
225 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 223 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
226} 224}
227 225
@@ -231,7 +229,7 @@ static bool dpu_encoder_phys_vid_mode_fixup(
231 struct drm_display_mode *adj_mode) 229 struct drm_display_mode *adj_mode)
232{ 230{
233 if (phys_enc) 231 if (phys_enc)
234 DPU_DEBUG_VIDENC(to_dpu_encoder_phys_vid(phys_enc), "\n"); 232 DPU_DEBUG_VIDENC(phys_enc, "\n");
235 233
236 /* 234 /*
237 * Modifying mode has consequences when the mode comes back to us 235 * Modifying mode has consequences when the mode comes back to us
@@ -242,7 +240,6 @@ static bool dpu_encoder_phys_vid_mode_fixup(
242static void dpu_encoder_phys_vid_setup_timing_engine( 240static void dpu_encoder_phys_vid_setup_timing_engine(
243 struct dpu_encoder_phys *phys_enc) 241 struct dpu_encoder_phys *phys_enc)
244{ 242{
245 struct dpu_encoder_phys_vid *vid_enc;
246 struct drm_display_mode mode; 243 struct drm_display_mode mode;
247 struct intf_timing_params timing_params = { 0 }; 244 struct intf_timing_params timing_params = { 0 };
248 const struct dpu_format *fmt = NULL; 245 const struct dpu_format *fmt = NULL;
@@ -256,13 +253,12 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
256 } 253 }
257 254
258 mode = phys_enc->cached_mode; 255 mode = phys_enc->cached_mode;
259 vid_enc = to_dpu_encoder_phys_vid(phys_enc); 256 if (!phys_enc->hw_intf->ops.setup_timing_gen) {
260 if (!vid_enc->hw_intf->ops.setup_timing_gen) {
261 DPU_ERROR("timing engine setup is not supported\n"); 257 DPU_ERROR("timing engine setup is not supported\n");
262 return; 258 return;
263 } 259 }
264 260
265 DPU_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); 261 DPU_DEBUG_VIDENC(phys_enc, "enabling mode:\n");
266 drm_mode_debug_printmodeline(&mode); 262 drm_mode_debug_printmodeline(&mode);
267 263
268 if (phys_enc->split_role != ENC_ROLE_SOLO) { 264 if (phys_enc->split_role != ENC_ROLE_SOLO) {
@@ -271,32 +267,30 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
271 mode.hsync_start >>= 1; 267 mode.hsync_start >>= 1;
272 mode.hsync_end >>= 1; 268 mode.hsync_end >>= 1;
273 269
274 DPU_DEBUG_VIDENC(vid_enc, 270 DPU_DEBUG_VIDENC(phys_enc,
275 "split_role %d, halve horizontal %d %d %d %d\n", 271 "split_role %d, halve horizontal %d %d %d %d\n",
276 phys_enc->split_role, 272 phys_enc->split_role,
277 mode.hdisplay, mode.htotal, 273 mode.hdisplay, mode.htotal,
278 mode.hsync_start, mode.hsync_end); 274 mode.hsync_start, mode.hsync_end);
279 } 275 }
280 276
281 drm_mode_to_intf_timing_params(vid_enc, &mode, &timing_params); 277 drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params);
282 278
283 fmt = dpu_get_dpu_format(fmt_fourcc); 279 fmt = dpu_get_dpu_format(fmt_fourcc);
284 DPU_DEBUG_VIDENC(vid_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); 280 DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc);
285 281
286 intf_cfg.intf = vid_enc->hw_intf->idx; 282 intf_cfg.intf = phys_enc->hw_intf->idx;
287 intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; 283 intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
288 intf_cfg.stream_sel = 0; /* Don't care value for video mode */ 284 intf_cfg.stream_sel = 0; /* Don't care value for video mode */
289 intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); 285 intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
290 286
291 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 287 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
292 vid_enc->hw_intf->ops.setup_timing_gen(vid_enc->hw_intf, 288 phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
293 &timing_params, fmt); 289 &timing_params, fmt);
294 phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); 290 phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
295 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 291 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
296 292
297 programmable_fetch_config(phys_enc, &timing_params); 293 programmable_fetch_config(phys_enc, &timing_params);
298
299 vid_enc->timing_params = timing_params;
300} 294}
301 295
302static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) 296static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
@@ -353,22 +347,10 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
353 phys_enc); 347 phys_enc);
354} 348}
355 349
356static bool _dpu_encoder_phys_is_dual_ctl(struct dpu_encoder_phys *phys_enc)
357{
358 struct dpu_crtc_state *dpu_cstate;
359
360 if (!phys_enc)
361 return false;
362
363 dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state);
364
365 return dpu_cstate->num_ctls > 1;
366}
367
368static bool dpu_encoder_phys_vid_needs_single_flush( 350static bool dpu_encoder_phys_vid_needs_single_flush(
369 struct dpu_encoder_phys *phys_enc) 351 struct dpu_encoder_phys *phys_enc)
370{ 352{
371 return (phys_enc && _dpu_encoder_phys_is_dual_ctl(phys_enc)); 353 return phys_enc->split_role != ENC_ROLE_SOLO;
372} 354}
373 355
374static void _dpu_encoder_phys_vid_setup_irq_hw_idx( 356static void _dpu_encoder_phys_vid_setup_irq_hw_idx(
@@ -396,19 +378,15 @@ static void dpu_encoder_phys_vid_mode_set(
396 struct drm_display_mode *mode, 378 struct drm_display_mode *mode,
397 struct drm_display_mode *adj_mode) 379 struct drm_display_mode *adj_mode)
398{ 380{
399 struct dpu_encoder_phys_vid *vid_enc;
400
401 if (!phys_enc || !phys_enc->dpu_kms) { 381 if (!phys_enc || !phys_enc->dpu_kms) {
402 DPU_ERROR("invalid encoder/kms\n"); 382 DPU_ERROR("invalid encoder/kms\n");
403 return; 383 return;
404 } 384 }
405 385
406 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
407
408 if (adj_mode) { 386 if (adj_mode) {
409 phys_enc->cached_mode = *adj_mode; 387 phys_enc->cached_mode = *adj_mode;
410 drm_mode_debug_printmodeline(adj_mode); 388 drm_mode_debug_printmodeline(adj_mode);
411 DPU_DEBUG_VIDENC(vid_enc, "caching mode:\n"); 389 DPU_DEBUG_VIDENC(phys_enc, "caching mode:\n");
412 } 390 }
413 391
414 _dpu_encoder_phys_vid_setup_irq_hw_idx(phys_enc); 392 _dpu_encoder_phys_vid_setup_irq_hw_idx(phys_enc);
@@ -419,7 +397,6 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
419 bool enable) 397 bool enable)
420{ 398{
421 int ret = 0; 399 int ret = 0;
422 struct dpu_encoder_phys_vid *vid_enc;
423 int refcount; 400 int refcount;
424 401
425 if (!phys_enc) { 402 if (!phys_enc) {
@@ -428,7 +405,6 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
428 } 405 }
429 406
430 refcount = atomic_read(&phys_enc->vblank_refcount); 407 refcount = atomic_read(&phys_enc->vblank_refcount);
431 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
432 408
433 /* Slave encoders don't report vblank */ 409 /* Slave encoders don't report vblank */
434 if (!dpu_encoder_phys_vid_is_master(phys_enc)) 410 if (!dpu_encoder_phys_vid_is_master(phys_enc))
@@ -453,7 +429,7 @@ end:
453 if (ret) { 429 if (ret) {
454 DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", 430 DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
455 DRMID(phys_enc->parent), 431 DRMID(phys_enc->parent),
456 vid_enc->hw_intf->idx - INTF_0, ret, enable, 432 phys_enc->hw_intf->idx - INTF_0, ret, enable,
457 refcount); 433 refcount);
458 } 434 }
459 return ret; 435 return ret;
@@ -461,43 +437,17 @@ end:
461 437
462static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) 438static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
463{ 439{
464 struct msm_drm_private *priv;
465 struct dpu_encoder_phys_vid *vid_enc;
466 struct dpu_rm_hw_iter iter;
467 struct dpu_hw_ctl *ctl; 440 struct dpu_hw_ctl *ctl;
468 u32 flush_mask = 0; 441 u32 flush_mask = 0;
469 442
470 if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev ||
471 !phys_enc->parent->dev->dev_private) {
472 DPU_ERROR("invalid encoder/device\n");
473 return;
474 }
475 priv = phys_enc->parent->dev->dev_private;
476
477 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
478 ctl = phys_enc->hw_ctl; 443 ctl = phys_enc->hw_ctl;
479 444
480 dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_INTF); 445 DPU_DEBUG_VIDENC(phys_enc, "\n");
481 while (dpu_rm_get_hw(&phys_enc->dpu_kms->rm, &iter)) {
482 struct dpu_hw_intf *hw_intf = (struct dpu_hw_intf *)iter.hw;
483
484 if (hw_intf->idx == phys_enc->intf_idx) {
485 vid_enc->hw_intf = hw_intf;
486 break;
487 }
488 }
489
490 if (!vid_enc->hw_intf) {
491 DPU_ERROR("hw_intf not assigned\n");
492 return;
493 }
494
495 DPU_DEBUG_VIDENC(vid_enc, "\n");
496 446
497 if (WARN_ON(!vid_enc->hw_intf->ops.enable_timing)) 447 if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
498 return; 448 return;
499 449
500 dpu_encoder_helper_split_config(phys_enc, vid_enc->hw_intf->idx); 450 dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx);
501 451
502 dpu_encoder_phys_vid_setup_timing_engine(phys_enc); 452 dpu_encoder_phys_vid_setup_timing_engine(phys_enc);
503 453
@@ -510,12 +460,13 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
510 !dpu_encoder_phys_vid_is_master(phys_enc)) 460 !dpu_encoder_phys_vid_is_master(phys_enc))
511 goto skip_flush; 461 goto skip_flush;
512 462
513 ctl->ops.get_bitmask_intf(ctl, &flush_mask, vid_enc->hw_intf->idx); 463 ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->hw_intf->idx);
514 ctl->ops.update_pending_flush(ctl, flush_mask); 464 ctl->ops.update_pending_flush(ctl, flush_mask);
515 465
516skip_flush: 466skip_flush:
517 DPU_DEBUG_VIDENC(vid_enc, "update pending flush ctl %d flush_mask %x\n", 467 DPU_DEBUG_VIDENC(phys_enc,
518 ctl->idx - CTL_0, flush_mask); 468 "update pending flush ctl %d flush_mask %x\n",
469 ctl->idx - CTL_0, flush_mask);
519 470
520 /* ctl_flush & timing engine enable will be triggered by framework */ 471 /* ctl_flush & timing engine enable will be triggered by framework */
521 if (phys_enc->enable_state == DPU_ENC_DISABLED) 472 if (phys_enc->enable_state == DPU_ENC_DISABLED)
@@ -524,16 +475,13 @@ skip_flush:
524 475
525static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) 476static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc)
526{ 477{
527 struct dpu_encoder_phys_vid *vid_enc;
528
529 if (!phys_enc) { 478 if (!phys_enc) {
530 DPU_ERROR("invalid encoder\n"); 479 DPU_ERROR("invalid encoder\n");
531 return; 480 return;
532 } 481 }
533 482
534 vid_enc = to_dpu_encoder_phys_vid(phys_enc); 483 DPU_DEBUG_VIDENC(phys_enc, "\n");
535 DPU_DEBUG_VIDENC(vid_enc, "\n"); 484 kfree(phys_enc);
536 kfree(vid_enc);
537} 485}
538 486
539static void dpu_encoder_phys_vid_get_hw_resources( 487static void dpu_encoder_phys_vid_get_hw_resources(
@@ -589,7 +537,6 @@ static int dpu_encoder_phys_vid_wait_for_vblank(
589static void dpu_encoder_phys_vid_prepare_for_kickoff( 537static void dpu_encoder_phys_vid_prepare_for_kickoff(
590 struct dpu_encoder_phys *phys_enc) 538 struct dpu_encoder_phys *phys_enc)
591{ 539{
592 struct dpu_encoder_phys_vid *vid_enc;
593 struct dpu_hw_ctl *ctl; 540 struct dpu_hw_ctl *ctl;
594 int rc; 541 int rc;
595 542
@@ -597,7 +544,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
597 DPU_ERROR("invalid encoder/parameters\n"); 544 DPU_ERROR("invalid encoder/parameters\n");
598 return; 545 return;
599 } 546 }
600 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
601 547
602 ctl = phys_enc->hw_ctl; 548 ctl = phys_enc->hw_ctl;
603 if (!ctl || !ctl->ops.wait_reset_status) 549 if (!ctl || !ctl->ops.wait_reset_status)
@@ -609,7 +555,7 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
609 */ 555 */
610 rc = ctl->ops.wait_reset_status(ctl); 556 rc = ctl->ops.wait_reset_status(ctl);
611 if (rc) { 557 if (rc) {
612 DPU_ERROR_VIDENC(vid_enc, "ctl %d reset failure: %d\n", 558 DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n",
613 ctl->idx, rc); 559 ctl->idx, rc);
614 dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC); 560 dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC);
615 } 561 }
@@ -618,7 +564,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
618static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) 564static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
619{ 565{
620 struct msm_drm_private *priv; 566 struct msm_drm_private *priv;
621 struct dpu_encoder_phys_vid *vid_enc;
622 unsigned long lock_flags; 567 unsigned long lock_flags;
623 int ret; 568 int ret;
624 569
@@ -629,16 +574,13 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
629 } 574 }
630 priv = phys_enc->parent->dev->dev_private; 575 priv = phys_enc->parent->dev->dev_private;
631 576
632 vid_enc = to_dpu_encoder_phys_vid(phys_enc); 577 if (!phys_enc->hw_intf || !phys_enc->hw_ctl) {
633 if (!vid_enc->hw_intf || !phys_enc->hw_ctl) {
634 DPU_ERROR("invalid hw_intf %d hw_ctl %d\n", 578 DPU_ERROR("invalid hw_intf %d hw_ctl %d\n",
635 vid_enc->hw_intf != 0, phys_enc->hw_ctl != 0); 579 phys_enc->hw_intf != 0, phys_enc->hw_ctl != 0);
636 return; 580 return;
637 } 581 }
638 582
639 DPU_DEBUG_VIDENC(vid_enc, "\n"); 583 if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
640
641 if (WARN_ON(!vid_enc->hw_intf->ops.enable_timing))
642 return; 584 return;
643 585
644 if (phys_enc->enable_state == DPU_ENC_DISABLED) { 586 if (phys_enc->enable_state == DPU_ENC_DISABLED) {
@@ -647,7 +589,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
647 } 589 }
648 590
649 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 591 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
650 vid_enc->hw_intf->ops.enable_timing(vid_enc->hw_intf, 0); 592 phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
651 if (dpu_encoder_phys_vid_is_master(phys_enc)) 593 if (dpu_encoder_phys_vid_is_master(phys_enc))
652 dpu_encoder_phys_inc_pending(phys_enc); 594 dpu_encoder_phys_inc_pending(phys_enc);
653 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 595 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
@@ -666,7 +608,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
666 atomic_set(&phys_enc->pending_kickoff_cnt, 0); 608 atomic_set(&phys_enc->pending_kickoff_cnt, 0);
667 DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", 609 DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
668 DRMID(phys_enc->parent), 610 DRMID(phys_enc->parent),
669 vid_enc->hw_intf->idx - INTF_0, ret); 611 phys_enc->hw_intf->idx - INTF_0, ret);
670 } 612 }
671 } 613 }
672 614
@@ -677,25 +619,21 @@ static void dpu_encoder_phys_vid_handle_post_kickoff(
677 struct dpu_encoder_phys *phys_enc) 619 struct dpu_encoder_phys *phys_enc)
678{ 620{
679 unsigned long lock_flags; 621 unsigned long lock_flags;
680 struct dpu_encoder_phys_vid *vid_enc;
681 622
682 if (!phys_enc) { 623 if (!phys_enc) {
683 DPU_ERROR("invalid encoder\n"); 624 DPU_ERROR("invalid encoder\n");
684 return; 625 return;
685 } 626 }
686 627
687 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
688 DPU_DEBUG_VIDENC(vid_enc, "enable_state %d\n", phys_enc->enable_state);
689
690 /* 628 /*
691 * Video mode must flush CTL before enabling timing engine 629 * Video mode must flush CTL before enabling timing engine
692 * Video encoders need to turn on their interfaces now 630 * Video encoders need to turn on their interfaces now
693 */ 631 */
694 if (phys_enc->enable_state == DPU_ENC_ENABLING) { 632 if (phys_enc->enable_state == DPU_ENC_ENABLING) {
695 trace_dpu_enc_phys_vid_post_kickoff(DRMID(phys_enc->parent), 633 trace_dpu_enc_phys_vid_post_kickoff(DRMID(phys_enc->parent),
696 vid_enc->hw_intf->idx - INTF_0); 634 phys_enc->hw_intf->idx - INTF_0);
697 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 635 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
698 vid_enc->hw_intf->ops.enable_timing(vid_enc->hw_intf, 1); 636 phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1);
699 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 637 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
700 phys_enc->enable_state = DPU_ENC_ENABLED; 638 phys_enc->enable_state = DPU_ENC_ENABLED;
701 } 639 }
@@ -704,16 +642,13 @@ static void dpu_encoder_phys_vid_handle_post_kickoff(
704static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, 642static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
705 bool enable) 643 bool enable)
706{ 644{
707 struct dpu_encoder_phys_vid *vid_enc;
708 int ret; 645 int ret;
709 646
710 if (!phys_enc) 647 if (!phys_enc)
711 return; 648 return;
712 649
713 vid_enc = to_dpu_encoder_phys_vid(phys_enc);
714
715 trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), 650 trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
716 vid_enc->hw_intf->idx - INTF_0, 651 phys_enc->hw_intf->idx - INTF_0,
717 enable, 652 enable,
718 atomic_read(&phys_enc->vblank_refcount)); 653 atomic_read(&phys_enc->vblank_refcount));
719 654
@@ -732,19 +667,16 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
732static int dpu_encoder_phys_vid_get_line_count( 667static int dpu_encoder_phys_vid_get_line_count(
733 struct dpu_encoder_phys *phys_enc) 668 struct dpu_encoder_phys *phys_enc)
734{ 669{
735 struct dpu_encoder_phys_vid *vid_enc;
736
737 if (!phys_enc) 670 if (!phys_enc)
738 return -EINVAL; 671 return -EINVAL;
739 672
740 if (!dpu_encoder_phys_vid_is_master(phys_enc)) 673 if (!dpu_encoder_phys_vid_is_master(phys_enc))
741 return -EINVAL; 674 return -EINVAL;
742 675
743 vid_enc = to_dpu_encoder_phys_vid(phys_enc); 676 if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_line_count)
744 if (!vid_enc->hw_intf || !vid_enc->hw_intf->ops.get_line_count)
745 return -EINVAL; 677 return -EINVAL;
746 678
747 return vid_enc->hw_intf->ops.get_line_count(vid_enc->hw_intf); 679 return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf);
748} 680}
749 681
750static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) 682static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops)
@@ -771,7 +703,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
771 struct dpu_enc_phys_init_params *p) 703 struct dpu_enc_phys_init_params *p)
772{ 704{
773 struct dpu_encoder_phys *phys_enc = NULL; 705 struct dpu_encoder_phys *phys_enc = NULL;
774 struct dpu_encoder_phys_vid *vid_enc = NULL;
775 struct dpu_encoder_irq *irq; 706 struct dpu_encoder_irq *irq;
776 int i, ret = 0; 707 int i, ret = 0;
777 708
@@ -780,18 +711,16 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
780 goto fail; 711 goto fail;
781 } 712 }
782 713
783 vid_enc = kzalloc(sizeof(*vid_enc), GFP_KERNEL); 714 phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL);
784 if (!vid_enc) { 715 if (!phys_enc) {
785 ret = -ENOMEM; 716 ret = -ENOMEM;
786 goto fail; 717 goto fail;
787 } 718 }
788 719
789 phys_enc = &vid_enc->base;
790
791 phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; 720 phys_enc->hw_mdptop = p->dpu_kms->hw_mdp;
792 phys_enc->intf_idx = p->intf_idx; 721 phys_enc->intf_idx = p->intf_idx;
793 722
794 DPU_DEBUG_VIDENC(vid_enc, "\n"); 723 DPU_DEBUG_VIDENC(phys_enc, "\n");
795 724
796 dpu_encoder_phys_vid_init_ops(&phys_enc->ops); 725 dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
797 phys_enc->parent = p->parent; 726 phys_enc->parent = p->parent;
@@ -825,13 +754,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
825 init_waitqueue_head(&phys_enc->pending_kickoff_wq); 754 init_waitqueue_head(&phys_enc->pending_kickoff_wq);
826 phys_enc->enable_state = DPU_ENC_DISABLED; 755 phys_enc->enable_state = DPU_ENC_DISABLED;
827 756
828 DPU_DEBUG_VIDENC(vid_enc, "created intf idx:%d\n", p->intf_idx); 757 DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->intf_idx);
829 758
830 return phys_enc; 759 return phys_enc;
831 760
832fail: 761fail:
833 DPU_ERROR("failed to create encoder\n"); 762 DPU_ERROR("failed to create encoder\n");
834 if (vid_enc) 763 if (phys_enc)
835 dpu_encoder_phys_vid_destroy(phys_enc); 764 dpu_encoder_phys_vid_destroy(phys_enc);
836 765
837 return ERR_PTR(ret); 766 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index ac75cfc267f4..31e9ef96ca5d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -73,9 +73,6 @@
73 73
74#define DPU_NAME_SIZE 12 74#define DPU_NAME_SIZE 12
75 75
76/* timeout in frames waiting for frame done */
77#define DPU_FRAME_DONE_TIMEOUT 60
78
79/* 76/*
80 * struct dpu_irq_callback - IRQ callback handlers 77 * struct dpu_irq_callback - IRQ callback handlers
81 * @list: list to callback 78 * @list: list to callback
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b01183b309b9..da1f727d7495 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -387,7 +387,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
387 ot_params.width = drm_rect_width(&pdpu->pipe_cfg.src_rect); 387 ot_params.width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
388 ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect); 388 ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
389 ot_params.is_wfd = !pdpu->is_rt_pipe; 389 ot_params.is_wfd = !pdpu->is_rt_pipe;
390 ot_params.frame_rate = crtc->mode.vrefresh; 390 ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
391 ot_params.vbif_idx = VBIF_RT; 391 ot_params.vbif_idx = VBIF_RT;
392 ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl; 392 ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
393 ot_params.rd = true; 393 ot_params.rd = true;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
index 9bf9d6065c55..7b9edc21bc2c 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
@@ -59,10 +59,10 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
59 return -EINVAL; 59 return -EINVAL;
60 } 60 }
61 61
62 total_lines_x100 = mode->vtotal * mode->vrefresh; 62 total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode);
63 if (!total_lines_x100) { 63 if (!total_lines_x100) {
64 DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", 64 DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
65 __func__, mode->vtotal, mode->vrefresh); 65 __func__, mode->vtotal, drm_mode_vrefresh(mode));
66 return -EINVAL; 66 return -EINVAL;
67 } 67 }
68 68
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
index fb423d309e91..67ef300559cf 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.c
+++ b/drivers/gpu/drm/msm/msm_debugfs.c
@@ -75,7 +75,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
75 struct msm_gpu_show_priv *show_priv; 75 struct msm_gpu_show_priv *show_priv;
76 int ret; 76 int ret;
77 77
78 if (!gpu) 78 if (!gpu || !gpu->funcs->gpu_state_get)
79 return -ENODEV; 79 return -ENODEV;
80 80
81 show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); 81 show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4697d854b827..31deb87abfc6 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -39,9 +39,10 @@
39 * MSM_GEM_INFO ioctl. 39 * MSM_GEM_INFO ioctl.
40 * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get 40 * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
41 * GEM object's debug name 41 * GEM object's debug name
42 * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
42 */ 43 */
43#define MSM_VERSION_MAJOR 1 44#define MSM_VERSION_MAJOR 1
44#define MSM_VERSION_MINOR 4 45#define MSM_VERSION_MINOR 5
45#define MSM_VERSION_PATCHLEVEL 0 46#define MSM_VERSION_PATCHLEVEL 0
46 47
47static const struct drm_mode_config_funcs mode_config_funcs = { 48static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -457,6 +458,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
457 458
458 priv->wq = alloc_ordered_workqueue("msm", 0); 459 priv->wq = alloc_ordered_workqueue("msm", 0);
459 460
461 INIT_WORK(&priv->free_work, msm_gem_free_work);
462 init_llist_head(&priv->free_list);
463
460 INIT_LIST_HEAD(&priv->inactive_list); 464 INIT_LIST_HEAD(&priv->inactive_list);
461 465
462 drm_mode_config_init(ddev); 466 drm_mode_config_init(ddev);
@@ -964,6 +968,11 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data,
964 args->flags, &args->id); 968 args->flags, &args->id);
965} 969}
966 970
971static int msm_ioctl_submitqueue_query(struct drm_device *dev, void *data,
972 struct drm_file *file)
973{
974 return msm_submitqueue_query(dev, file->driver_priv, data);
975}
967 976
968static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data, 977static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,
969 struct drm_file *file) 978 struct drm_file *file)
@@ -984,6 +993,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
984 DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE, msm_ioctl_gem_madvise, DRM_AUTH|DRM_RENDER_ALLOW), 993 DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE, msm_ioctl_gem_madvise, DRM_AUTH|DRM_RENDER_ALLOW),
985 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW, msm_ioctl_submitqueue_new, DRM_AUTH|DRM_RENDER_ALLOW), 994 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW, msm_ioctl_submitqueue_new, DRM_AUTH|DRM_RENDER_ALLOW),
986 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW), 995 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW),
996 DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_AUTH|DRM_RENDER_ALLOW),
987}; 997};
988 998
989static const struct vm_operations_struct vm_ops = { 999static const struct vm_operations_struct vm_ops = {
@@ -1019,7 +1029,7 @@ static struct drm_driver msm_driver = {
1019 .irq_uninstall = msm_irq_uninstall, 1029 .irq_uninstall = msm_irq_uninstall,
1020 .enable_vblank = msm_enable_vblank, 1030 .enable_vblank = msm_enable_vblank,
1021 .disable_vblank = msm_disable_vblank, 1031 .disable_vblank = msm_disable_vblank,
1022 .gem_free_object = msm_gem_free_object, 1032 .gem_free_object_unlocked = msm_gem_free_object,
1023 .gem_vm_ops = &vm_ops, 1033 .gem_vm_ops = &vm_ops,
1024 .dumb_create = msm_gem_dumb_create, 1034 .dumb_create = msm_gem_dumb_create,
1025 .dumb_map_offset = msm_gem_dumb_map_offset, 1035 .dumb_map_offset = msm_gem_dumb_map_offset,
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 163e24d2ab99..eb33d2d00d77 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -185,6 +185,10 @@ struct msm_drm_private {
185 /* list of GEM objects: */ 185 /* list of GEM objects: */
186 struct list_head inactive_list; 186 struct list_head inactive_list;
187 187
188 /* worker for delayed free of objects: */
189 struct work_struct free_work;
190 struct llist_head free_list;
191
188 struct workqueue_struct *wq; 192 struct workqueue_struct *wq;
189 193
190 unsigned int num_planes; 194 unsigned int num_planes;
@@ -324,6 +328,7 @@ void msm_gem_kernel_put(struct drm_gem_object *bo,
324 struct msm_gem_address_space *aspace, bool locked); 328 struct msm_gem_address_space *aspace, bool locked);
325struct drm_gem_object *msm_gem_import(struct drm_device *dev, 329struct drm_gem_object *msm_gem_import(struct drm_device *dev,
326 struct dma_buf *dmabuf, struct sg_table *sgt); 330 struct dma_buf *dmabuf, struct sg_table *sgt);
331void msm_gem_free_work(struct work_struct *work);
327 332
328__printf(2, 3) 333__printf(2, 3)
329void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...); 334void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
@@ -419,6 +424,8 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
419 u32 id); 424 u32 id);
420int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, 425int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
421 u32 prio, u32 flags, u32 *id); 426 u32 prio, u32 flags, u32 *id);
427int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
428 struct drm_msm_submitqueue_query *args);
422int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id); 429int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
423void msm_submitqueue_close(struct msm_file_private *ctx); 430void msm_submitqueue_close(struct msm_file_private *ctx);
424 431
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index a72c648ba6e7..31d5a744d84f 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -851,8 +851,18 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)
851/* don't call directly! Use drm_gem_object_put() and friends */ 851/* don't call directly! Use drm_gem_object_put() and friends */
852void msm_gem_free_object(struct drm_gem_object *obj) 852void msm_gem_free_object(struct drm_gem_object *obj)
853{ 853{
854 struct drm_device *dev = obj->dev;
855 struct msm_gem_object *msm_obj = to_msm_bo(obj); 854 struct msm_gem_object *msm_obj = to_msm_bo(obj);
855 struct drm_device *dev = obj->dev;
856 struct msm_drm_private *priv = dev->dev_private;
857
858 if (llist_add(&msm_obj->freed, &priv->free_list))
859 queue_work(priv->wq, &priv->free_work);
860}
861
862static void free_object(struct msm_gem_object *msm_obj)
863{
864 struct drm_gem_object *obj = &msm_obj->base;
865 struct drm_device *dev = obj->dev;
856 866
857 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 867 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
858 868
@@ -887,6 +897,29 @@ void msm_gem_free_object(struct drm_gem_object *obj)
887 kfree(msm_obj); 897 kfree(msm_obj);
888} 898}
889 899
900void msm_gem_free_work(struct work_struct *work)
901{
902 struct msm_drm_private *priv =
903 container_of(work, struct msm_drm_private, free_work);
904 struct drm_device *dev = priv->dev;
905 struct llist_node *freed;
906 struct msm_gem_object *msm_obj, *next;
907
908 while ((freed = llist_del_all(&priv->free_list))) {
909
910 mutex_lock(&dev->struct_mutex);
911
912 llist_for_each_entry_safe(msm_obj, next,
913 freed, freed)
914 free_object(msm_obj);
915
916 mutex_unlock(&dev->struct_mutex);
917
918 if (need_resched())
919 break;
920 }
921}
922
890/* convenience method to construct a GEM buffer object, and userspace handle */ 923/* convenience method to construct a GEM buffer object, and userspace handle */
891int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, 924int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
892 uint32_t size, uint32_t flags, uint32_t *handle, 925 uint32_t size, uint32_t flags, uint32_t *handle,
@@ -1017,6 +1050,13 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev,
1017 ret = drm_gem_object_init(dev, obj, size); 1050 ret = drm_gem_object_init(dev, obj, size);
1018 if (ret) 1051 if (ret)
1019 goto fail; 1052 goto fail;
1053 /*
1054 * Our buffers are kept pinned, so allocating them from the
1055 * MOVABLE zone is a really bad idea, and conflicts with CMA.
1056 * See comments above new_inode() why this is required _and_
1057 * expected if you're going to pin these pages.
1058 */
1059 mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);
1020 } 1060 }
1021 1061
1022 return obj; 1062 return obj;
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 2064fac871b8..c5ac781dffee 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -84,6 +84,8 @@ struct msm_gem_object {
84 84
85 struct list_head vmas; /* list of msm_gem_vma */ 85 struct list_head vmas; /* list of msm_gem_vma */
86 86
87 struct llist_node freed;
88
87 /* normally (resv == &_resv) except for imported bo's */ 89 /* normally (resv == &_resv) except for imported bo's */
88 struct reservation_object *resv; 90 struct reservation_object *resv;
89 struct reservation_object _resv; 91 struct reservation_object _resv;
@@ -133,6 +135,7 @@ enum msm_gem_lock {
133 135
134void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass); 136void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass);
135void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); 137void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass);
138void msm_gem_free_work(struct work_struct *work);
136 139
137/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, 140/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
138 * associated with the cmdstream submission for synchronization (and 141 * associated with the cmdstream submission for synchronization (and
@@ -163,7 +166,10 @@ struct msm_gem_submit {
163 } *cmd; /* array of size nr_cmds */ 166 } *cmd; /* array of size nr_cmds */
164 struct { 167 struct {
165 uint32_t flags; 168 uint32_t flags;
166 struct msm_gem_object *obj; 169 union {
170 struct msm_gem_object *obj;
171 uint32_t handle;
172 };
167 uint64_t iova; 173 uint64_t iova;
168 } bos[0]; 174 } bos[0];
169}; 175};
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index df302521ec74..1b681306aca3 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -74,27 +74,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit)
74 kfree(submit); 74 kfree(submit);
75} 75}
76 76
77static inline unsigned long __must_check
78copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
79{
80 if (access_ok(from, n))
81 return __copy_from_user_inatomic(to, from, n);
82 return -EFAULT;
83}
84
85static int submit_lookup_objects(struct msm_gem_submit *submit, 77static int submit_lookup_objects(struct msm_gem_submit *submit,
86 struct drm_msm_gem_submit *args, struct drm_file *file) 78 struct drm_msm_gem_submit *args, struct drm_file *file)
87{ 79{
88 unsigned i; 80 unsigned i;
89 int ret = 0; 81 int ret = 0;
90 82
91 spin_lock(&file->table_lock);
92 pagefault_disable();
93
94 for (i = 0; i < args->nr_bos; i++) { 83 for (i = 0; i < args->nr_bos; i++) {
95 struct drm_msm_gem_submit_bo submit_bo; 84 struct drm_msm_gem_submit_bo submit_bo;
96 struct drm_gem_object *obj;
97 struct msm_gem_object *msm_obj;
98 void __user *userptr = 85 void __user *userptr =
99 u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); 86 u64_to_user_ptr(args->bos + (i * sizeof(submit_bo)));
100 87
@@ -103,15 +90,10 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
103 */ 90 */
104 submit->bos[i].flags = 0; 91 submit->bos[i].flags = 0;
105 92
106 if (copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo))) { 93 if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) {
107 pagefault_enable(); 94 ret = -EFAULT;
108 spin_unlock(&file->table_lock); 95 i = 0;
109 if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) { 96 goto out;
110 ret = -EFAULT;
111 goto out;
112 }
113 spin_lock(&file->table_lock);
114 pagefault_disable();
115 } 97 }
116 98
117/* at least one of READ and/or WRITE flags should be set: */ 99/* at least one of READ and/or WRITE flags should be set: */
@@ -121,19 +103,28 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
121 !(submit_bo.flags & MANDATORY_FLAGS)) { 103 !(submit_bo.flags & MANDATORY_FLAGS)) {
122 DRM_ERROR("invalid flags: %x\n", submit_bo.flags); 104 DRM_ERROR("invalid flags: %x\n", submit_bo.flags);
123 ret = -EINVAL; 105 ret = -EINVAL;
124 goto out_unlock; 106 i = 0;
107 goto out;
125 } 108 }
126 109
110 submit->bos[i].handle = submit_bo.handle;
127 submit->bos[i].flags = submit_bo.flags; 111 submit->bos[i].flags = submit_bo.flags;
128 /* in validate_objects() we figure out if this is true: */ 112 /* in validate_objects() we figure out if this is true: */
129 submit->bos[i].iova = submit_bo.presumed; 113 submit->bos[i].iova = submit_bo.presumed;
114 }
115
116 spin_lock(&file->table_lock);
117
118 for (i = 0; i < args->nr_bos; i++) {
119 struct drm_gem_object *obj;
120 struct msm_gem_object *msm_obj;
130 121
131 /* normally use drm_gem_object_lookup(), but for bulk lookup 122 /* normally use drm_gem_object_lookup(), but for bulk lookup
132 * all under single table_lock just hit object_idr directly: 123 * all under single table_lock just hit object_idr directly:
133 */ 124 */
134 obj = idr_find(&file->object_idr, submit_bo.handle); 125 obj = idr_find(&file->object_idr, submit->bos[i].handle);
135 if (!obj) { 126 if (!obj) {
136 DRM_ERROR("invalid handle %u at index %u\n", submit_bo.handle, i); 127 DRM_ERROR("invalid handle %u at index %u\n", submit->bos[i].handle, i);
137 ret = -EINVAL; 128 ret = -EINVAL;
138 goto out_unlock; 129 goto out_unlock;
139 } 130 }
@@ -142,7 +133,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
142 133
143 if (!list_empty(&msm_obj->submit_entry)) { 134 if (!list_empty(&msm_obj->submit_entry)) {
144 DRM_ERROR("handle %u at index %u already on submit list\n", 135 DRM_ERROR("handle %u at index %u already on submit list\n",
145 submit_bo.handle, i); 136 submit->bos[i].handle, i);
146 ret = -EINVAL; 137 ret = -EINVAL;
147 goto out_unlock; 138 goto out_unlock;
148 } 139 }
@@ -155,7 +146,6 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
155 } 146 }
156 147
157out_unlock: 148out_unlock:
158 pagefault_enable();
159 spin_unlock(&file->table_lock); 149 spin_unlock(&file->table_lock);
160 150
161out: 151out:
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 49c04829cf34..fcf7a83f0e6f 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -85,7 +85,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
85 85
86 vma->mapped = true; 86 vma->mapped = true;
87 87
88 if (aspace->mmu) 88 if (aspace && aspace->mmu)
89 ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, 89 ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
90 size, prot); 90 size, prot);
91 91
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 10babd18e286..bf4ee2766431 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -443,24 +443,15 @@ static void recover_worker(struct work_struct *work)
443 if (submit) { 443 if (submit) {
444 struct task_struct *task; 444 struct task_struct *task;
445 445
446 /* Increment the fault counts */
447 gpu->global_faults++;
448 submit->queue->faults++;
449
446 task = get_pid_task(submit->pid, PIDTYPE_PID); 450 task = get_pid_task(submit->pid, PIDTYPE_PID);
447 if (task) { 451 if (task) {
448 comm = kstrdup(task->comm, GFP_KERNEL); 452 comm = kstrdup(task->comm, GFP_KERNEL);
449
450 /*
451 * So slightly annoying, in other paths like
452 * mmap'ing gem buffers, mmap_sem is acquired
453 * before struct_mutex, which means we can't
454 * hold struct_mutex across the call to
455 * get_cmdline(). But submits are retired
456 * from the same in-order workqueue, so we can
457 * safely drop the lock here without worrying
458 * about the submit going away.
459 */
460 mutex_unlock(&dev->struct_mutex);
461 cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); 453 cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
462 put_task_struct(task); 454 put_task_struct(task);
463 mutex_lock(&dev->struct_mutex);
464 } 455 }
465 456
466 if (comm && cmd) { 457 if (comm && cmd) {
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 6241986bab51..f2739cd97cea 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -104,6 +104,9 @@ struct msm_gpu {
104 /* does gpu need hw_init? */ 104 /* does gpu need hw_init? */
105 bool needs_hw_init; 105 bool needs_hw_init;
106 106
107 /* number of GPU hangs (for all contexts) */
108 int global_faults;
109
107 /* worker for handling active-list retiring: */ 110 /* worker for handling active-list retiring: */
108 struct work_struct retire_work; 111 struct work_struct retire_work;
109 112
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 4d62790cd425..12bb54cefd46 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -38,13 +38,8 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names,
38 int cnt) 38 int cnt)
39{ 39{
40 struct msm_iommu *iommu = to_msm_iommu(mmu); 40 struct msm_iommu *iommu = to_msm_iommu(mmu);
41 int ret;
42 41
43 pm_runtime_get_sync(mmu->dev); 42 return iommu_attach_device(iommu->domain, mmu->dev);
44 ret = iommu_attach_device(iommu->domain, mmu->dev);
45 pm_runtime_put_sync(mmu->dev);
46
47 return ret;
48} 43}
49 44
50static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, 45static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
@@ -52,9 +47,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
52{ 47{
53 struct msm_iommu *iommu = to_msm_iommu(mmu); 48 struct msm_iommu *iommu = to_msm_iommu(mmu);
54 49
55 pm_runtime_get_sync(mmu->dev);
56 iommu_detach_device(iommu->domain, mmu->dev); 50 iommu_detach_device(iommu->domain, mmu->dev);
57 pm_runtime_put_sync(mmu->dev);
58} 51}
59 52
60static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, 53static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
@@ -63,9 +56,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
63 struct msm_iommu *iommu = to_msm_iommu(mmu); 56 struct msm_iommu *iommu = to_msm_iommu(mmu);
64 size_t ret; 57 size_t ret;
65 58
66// pm_runtime_get_sync(mmu->dev);
67 ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); 59 ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
68// pm_runtime_put_sync(mmu->dev);
69 WARN_ON(!ret); 60 WARN_ON(!ret);
70 61
71 return (ret == len) ? 0 : -EINVAL; 62 return (ret == len) ? 0 : -EINVAL;
@@ -75,9 +66,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
75{ 66{
76 struct msm_iommu *iommu = to_msm_iommu(mmu); 67 struct msm_iommu *iommu = to_msm_iommu(mmu);
77 68
78 pm_runtime_get_sync(mmu->dev);
79 iommu_unmap(iommu->domain, iova, len); 69 iommu_unmap(iommu->domain, iova, len);
80 pm_runtime_put_sync(mmu->dev);
81 70
82 return 0; 71 return 0;
83} 72}
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c
index 5115f75b5b7f..f160ec40a39b 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -120,6 +120,47 @@ int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx)
120 return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL); 120 return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL);
121} 121}
122 122
123static int msm_submitqueue_query_faults(struct msm_gpu_submitqueue *queue,
124 struct drm_msm_submitqueue_query *args)
125{
126 size_t size = min_t(size_t, args->len, sizeof(queue->faults));
127 int ret;
128
129 /* If a zero length was passed in, return the data size we expect */
130 if (!args->len) {
131 args->len = sizeof(queue->faults);
132 return 0;
133 }
134
135 /* Set the length to the actual size of the data */
136 args->len = size;
137
138 ret = copy_to_user(u64_to_user_ptr(args->data), &queue->faults, size);
139
140 return ret ? -EFAULT : 0;
141}
142
143int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
144 struct drm_msm_submitqueue_query *args)
145{
146 struct msm_gpu_submitqueue *queue;
147 int ret = -EINVAL;
148
149 if (args->pad)
150 return -EINVAL;
151
152 queue = msm_submitqueue_get(ctx, args->id);
153 if (!queue)
154 return -ENOENT;
155
156 if (args->param == MSM_SUBMITQUEUE_PARAM_FAULTS)
157 ret = msm_submitqueue_query_faults(queue, args);
158
159 msm_submitqueue_put(queue);
160
161 return ret;
162}
163
123int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id) 164int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id)
124{ 165{
125 struct msm_gpu_submitqueue *entry; 166 struct msm_gpu_submitqueue *entry;
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 91a16b333c69..0b85ed6a3710 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -74,6 +74,8 @@ struct drm_msm_timespec {
74#define MSM_PARAM_TIMESTAMP 0x05 74#define MSM_PARAM_TIMESTAMP 0x05
75#define MSM_PARAM_GMEM_BASE 0x06 75#define MSM_PARAM_GMEM_BASE 0x06
76#define MSM_PARAM_NR_RINGS 0x07 76#define MSM_PARAM_NR_RINGS 0x07
77#define MSM_PARAM_PP_PGTABLE 0x08 /* => 1 for per-process pagetables, else 0 */
78#define MSM_PARAM_FAULTS 0x09
77 79
78struct drm_msm_param { 80struct drm_msm_param {
79 __u32 pipe; /* in, MSM_PIPE_x */ 81 __u32 pipe; /* in, MSM_PIPE_x */
@@ -286,6 +288,16 @@ struct drm_msm_submitqueue {
286 __u32 id; /* out, identifier */ 288 __u32 id; /* out, identifier */
287}; 289};
288 290
291#define MSM_SUBMITQUEUE_PARAM_FAULTS 0
292
293struct drm_msm_submitqueue_query {
294 __u64 data;
295 __u32 id;
296 __u32 param;
297 __u32 len;
298 __u32 pad;
299};
300
289#define DRM_MSM_GET_PARAM 0x00 301#define DRM_MSM_GET_PARAM 0x00
290/* placeholder: 302/* placeholder:
291#define DRM_MSM_SET_PARAM 0x01 303#define DRM_MSM_SET_PARAM 0x01
@@ -302,6 +314,7 @@ struct drm_msm_submitqueue {
302 */ 314 */
303#define DRM_MSM_SUBMITQUEUE_NEW 0x0A 315#define DRM_MSM_SUBMITQUEUE_NEW 0x0A
304#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B 316#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B
317#define DRM_MSM_SUBMITQUEUE_QUERY 0x0C
305 318
306#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) 319#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
307#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) 320#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -313,6 +326,7 @@ struct drm_msm_submitqueue {
313#define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) 326#define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
314#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) 327#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
315#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) 328#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
329#define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query)
316 330
317#if defined(__cplusplus) 331#if defined(__cplusplus)
318} 332}