From cd70d7ade43d7629edab206fedc686e2eb7257b9 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 19 Dec 2018 08:57:41 -0800 Subject: drm/msm: Unblock writer if reader closes file Prevents deadlock when fifo is full and reader closes file. Signed-off-by: Kristian H. Kristensen Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_rd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 90e9d0a48dc0..d21172933d92 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -115,7 +115,9 @@ static void rd_write(struct msm_rd_state *rd, const void *buf, int sz) char *fptr = &fifo->buf[fifo->head]; int n; - wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0); + wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0 || !rd->open); + if (!rd->open) + return; /* Note that smp_load_acquire() is not strictly required * as CIRC_SPACE_TO_END() does not access the tail more @@ -213,7 +215,10 @@ out: static int rd_release(struct inode *inode, struct file *file) { struct msm_rd_state *rd = inode->i_private; + rd->open = false; + wake_up_all(&rd->fifo_event); + return 0; } -- cgit v1.2.3 From d4df171418262d2e0291dcff14e40bcebe73af3c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 13 Aug 2018 23:23:44 +0200 Subject: drm/msm/gpu: fix building without debugfs When debugfs is disabled, but coredump is turned on, the adreno driver fails to build: drivers/gpu/drm/msm/adreno/a3xx_gpu.c:460:4: error: 'struct msm_gpu_funcs' has no member named 'show' .show = adreno_show, ^~~~ drivers/gpu/drm/msm/adreno/a3xx_gpu.c:460:11: note: (near initialization for 'funcs.base') drivers/gpu/drm/msm/adreno/a3xx_gpu.c:460:11: error: initialization of 'void (*)(struct msm_gpu *, struct msm_gem_submit *, struct msm_file_private *)' from incompatible pointer type 'void (*)(struct msm_gpu *, struct msm_gpu_state *, struct drm_printer *)' [-Werror=incompatible-pointer-types] drivers/gpu/drm/msm/adreno/a3xx_gpu.c:460:11: note: (near initialization for 'funcs.base.submit') drivers/gpu/drm/msm/adreno/a4xx_gpu.c:546:4: error: 'struct msm_gpu_funcs' has no member named 'show' drivers/gpu/drm/msm/adreno/a5xx_gpu.c:1460:4: error: 'struct msm_gpu_funcs' has no member named 'show' drivers/gpu/drm/msm/adreno/a6xx_gpu.c:769:4: error: 'struct msm_gpu_funcs' has no member named 'show' drivers/gpu/drm/msm/msm_gpu.c: In function 'msm_gpu_devcoredump_read': drivers/gpu/drm/msm/msm_gpu.c:289:12: error: 'const struct msm_gpu_funcs' has no member named 'show' Adjust the #ifdef to make it build again. Fixes: c0fec7f562ec ("drm/msm/gpu: Capture the GPU state on a GPU hang") Signed-off-by: Arnd Bergmann Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index efb49bb64191..95170dee9d7a 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -63,7 +63,7 @@ struct msm_gpu_funcs { struct msm_ringbuffer *(*active_ring)(struct msm_gpu *gpu); void (*recover)(struct msm_gpu *gpu); void (*destroy)(struct msm_gpu *gpu); -#ifdef CONFIG_DEBUG_FS +#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) /* show GPU status in debugfs: */ void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state, struct drm_printer *p); -- cgit v1.2.3 From 2255f244f92e651dbd410f92d2968c6dae4ead8e Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 18 Dec 2018 11:32:36 -0700 Subject: drm/msm/gpu: Remove hardcoded interrupt name Every GPU core only has one interrupt so there isn't any value in looking up the interrupt by name. Remove the name (which is legacy anyway) and use platform_get_irq() instead. Signed-off-by: Jordan Crouse Reviewed-by: Douglas Anderson Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 1 - drivers/gpu/drm/msm/msm_gpu.c | 2 +- drivers/gpu/drm/msm/msm_gpu.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 2e4372ef17a3..2cfee1a4fe0b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -765,7 +765,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu->rev = config->rev; adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; - adreno_gpu_config.irqname = "kgsl_3d0_irq"; adreno_gpu_config.va_start = SZ_16M; adreno_gpu_config.va_end = 0xffffffff; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 5f3eff304355..10babd18e286 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -900,7 +900,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, } /* Get Interrupt: */ - gpu->irq = platform_get_irq_byname(pdev, config->irqname); + gpu->irq = platform_get_irq(pdev, 0); if (gpu->irq < 0) { ret = gpu->irq; DRM_DEV_ERROR(drm->dev, "failed to get irq: %d\n", ret); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 95170dee9d7a..ca17086f72c9 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -31,7 +31,6 @@ struct msm_gpu_state; struct msm_gpu_config { const char *ioname; - const char *irqname; uint64_t va_start; uint64_t va_end; unsigned int nr_rings; -- cgit v1.2.3 From b8be1cd9b010da726907a38b7a43d7259db51081 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 18 Dec 2018 11:32:37 -0700 Subject: drm/msm: drop interrupt-names Each GPU core only uses one interrupt so we don't to look up an interrupt by name and thereby we don't need interrupt-names. Signed-off-by: Jordan Crouse Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- Documentation/devicetree/bindings/display/msm/gpu.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index ac8df3b871f9..f8759145ce1a 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -27,7 +27,6 @@ Example: reg = <0x04300000 0x20000>; reg-names = "kgsl_3d0_reg_memory"; interrupts = ; - interrupt-names = "kgsl_3d0_irq"; clock-names = "core", "iface", -- cgit v1.2.3 From 388a515f6add79305d9dc9a5d22543be5457fc55 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 9 Jan 2019 14:25:05 -0500 Subject: drm/msm: honor GPU_READONLY flag Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 3 ++- drivers/gpu/drm/msm/msm_gem.c | 8 ++++++-- drivers/gpu/drm/msm/msm_gem_vma.c | 5 +++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9cd6a96c6bf2..9f51be5a637c 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -250,7 +250,8 @@ void msm_gem_purge_vma(struct msm_gem_address_space *aspace, void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma); int msm_gem_map_vma(struct msm_gem_address_space *aspace, - struct msm_gem_vma *vma, struct sg_table *sgt, int npages); + struct msm_gem_vma *vma, int prot, + struct sg_table *sgt, int npages); void msm_gem_close_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 20c979a7fc9c..18ca651ab942 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -391,6 +391,10 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, struct msm_gem_object *msm_obj = to_msm_bo(obj); struct msm_gem_vma *vma; struct page **pages; + int prot = IOMMU_READ; + + if (!(msm_obj->flags & MSM_BO_GPU_READONLY)) + prot |= IOMMU_WRITE; WARN_ON(!mutex_is_locked(&msm_obj->lock)); @@ -405,8 +409,8 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, if (IS_ERR(pages)) return PTR_ERR(pages); - return msm_gem_map_vma(aspace, vma, msm_obj->sgt, - obj->size >> PAGE_SHIFT); + return msm_gem_map_vma(aspace, vma, prot, + msm_obj->sgt, obj->size >> PAGE_SHIFT); } /* get iova and pin it. Should have a matching put */ diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 557360788084..49c04829cf34 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -68,7 +68,8 @@ void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, int msm_gem_map_vma(struct msm_gem_address_space *aspace, - struct msm_gem_vma *vma, struct sg_table *sgt, int npages) + struct msm_gem_vma *vma, int prot, + struct sg_table *sgt, int npages) { unsigned size = npages << PAGE_SHIFT; int ret = 0; @@ -86,7 +87,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, if (aspace->mmu) ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, - size, IOMMU_READ | IOMMU_WRITE); + size, prot); if (ret) vma->mapped = false; -- cgit v1.2.3 From ac11c637f899b6e2dede05f41205fa4b8f82c241 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 16 Jan 2019 10:46:21 -0800 Subject: drm/msm: Fix A6XX support for opp-level The bindings for Qualcomm opp levels changed after being Acked but before landing. Thus the code in the GPU driver that was relying on the old bindings is now broken. Let's change the code to match the new bindings by adjusting the old string 'qcom,level' to the new string 'opp-level'. See the patch ("dt-bindings: opp: Introduce opp-level bindings"). NOTE: we will do additional cleanup to totally remove the string from the code and use the new dev_pm_opp_get_level() but we'll do it in a future patch. This will facilitate getting the important code fix in sooner without having to deal with cross-maintainer dependencies. This patch needs to land before the patch ("arm64: dts: sdm845: Add gpu and gmu device nodes") since if a tree contains the device tree patch but not this one you'll get a crash at bootup. Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support") Signed-off-by: Douglas Anderson Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 5beb83d1cf87..ce1b3cc4bf6d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -944,7 +944,7 @@ static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq) np = dev_pm_opp_get_of_node(opp); if (np) { - of_property_read_u32(np, "qcom,level", &val); + of_property_read_u32(np, "opp-level", &val); of_node_put(np); } -- cgit v1.2.3 From 19db132671e836a379acea5fd7378260842382af Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 17 Jan 2019 14:17:36 -0800 Subject: drm/msm: Add __printf verification Add a few __printf attribute specifiers to routines that could use them. Signed-off-by: Joe Perches Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9f51be5a637c..927e5d86f7c1 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -334,6 +334,7 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt); +__printf(2, 3) void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...); int msm_framebuffer_prepare(struct drm_framebuffer *fb, @@ -397,12 +398,14 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m); int msm_debugfs_late_init(struct drm_device *dev); int msm_rd_debugfs_init(struct drm_minor *minor); void msm_rd_debugfs_cleanup(struct msm_drm_private *priv); +__printf(3, 4) void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, const char *fmt, ...); int msm_perf_debugfs_init(struct drm_minor *minor); void msm_perf_debugfs_cleanup(struct msm_drm_private *priv); #else static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; } +__printf(3, 4) static inline void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, const char *fmt, ...) {} static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {} -- cgit v1.2.3 From 22bbd8ef647ea1fd98ca7505da2bc224805ce467 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 10 Jan 2019 15:14:03 +0100 Subject: drm/msm: avoid unused function warning drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c:368:13: error: 'dpu_plane_danger_signal_ctrl' defined but not used [-Werror=unused-function] Fixes: 7b2e7adea732 ("drm/msm/dpu: Make dpu_plane_danger_signal_ctrl void") Signed-off-by: Arnd Bergmann Signed-off-by: Anders Roxell Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index fd75870eb17f..6aefcd6db46b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -365,19 +365,6 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, &pdpu->pipe_qos_cfg); } -static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); - - if (!pdpu->is_rt_pipe) - return; - - pm_runtime_get_sync(&dpu_kms->pdev->dev); - _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL); - pm_runtime_put_sync(&dpu_kms->pdev->dev); -} - /** * _dpu_plane_set_ot_limit - set OT limit for the given plane * @plane: Pointer to drm plane @@ -1248,6 +1235,19 @@ static void dpu_plane_reset(struct drm_plane *plane) } #ifdef CONFIG_DEBUG_FS +static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) +{ + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); + + if (!pdpu->is_rt_pipe) + return; + + pm_runtime_get_sync(&dpu_kms->pdev->dev); + _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL); + pm_runtime_put_sync(&dpu_kms->pdev->dev); +} + static ssize_t _dpu_plane_danger_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { -- cgit v1.2.3 From 740f9433a85408039aac33eb7f62a6a8d552d983 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 18 Dec 2018 11:32:40 -0700 Subject: dt-bindings: drm/msm/a6xx: Document GMU and update GPU bindings Update the GPU bindings and document the new bindings for the GMU device found with Adreno a6xx targets. Signed-off-by: Jordan Crouse Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- .../devicetree/bindings/display/msm/gpu.txt | 42 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index f8759145ce1a..aad1aef682f7 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -10,14 +10,23 @@ Required properties: If "amd,imageon" is used, there should be no top level msm device. - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt signal from the gpu. -- clocks: device clocks +- clocks: device clocks (if applicable) See ../clocks/clock-bindings.txt for details. -- clock-names: the following clocks are required: +- clock-names: the following clocks are required by a3xx, a4xx and a5xx + cores: * "core" * "iface" * "mem_iface" + For GMU attached devices the GPU clocks are not used and are not required. The + following devices should not list clocks: + - qcom,adreno-630.2 +- iommus: optional phandle to an adreno iommu instance +- operating-points-v2: optional phandle to the OPP operating points +- qcom,gmu: For GMU attached devices a phandle to the GMU device that will + control the power for the GPU. Applicable targets: + - qcom,adreno-630.2 -Example: +Example 3xx/4xx/a5xx: / { ... @@ -37,3 +46,30 @@ Example: <&mmcc MMSS_IMEM_AHB_CLK>; }; }; + +Example a6xx (with GMU): + +/ { + ... + + gpu@5000000 { + compatible = "qcom,adreno-630.2", "qcom,adreno"; + #stream-id-cells = <16>; + + reg = <0x5000000 0x40000>, <0x509e000 0x10>; + reg-names = "kgsl_3d0_reg_memory", "cx_mem"; + + /* + * Look ma, no clocks! The GPU clocks and power are + * controlled entirely by the GMU + */ + + interrupts = ; + + iommus = <&adreno_smmu 0>; + + operating-points-v2 = <&gpu_opp_table>; + + qcom,gmu = <&gmu>; + }; +}; -- cgit v1.2.3 From 8aa82766de12d11a7e00d02b6d74349f57a8219e Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 16 Jan 2019 14:09:51 -0700 Subject: dt-bindings: drm/msm/a6xx: Document GMU bindings Commit 24937c540917 ("dt-bindings: drm/msm/a6xx: Document GMU and update GPU bindings") mistakenly omitted the GMU bindings as seen in [1]. Return them to their rightful place. [1] https://patchwork.freedesktop.org/patch/268679/ Signed-off-by: Jordan Crouse Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- .../devicetree/bindings/display/msm/gmu.txt | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/msm/gmu.txt diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt new file mode 100644 index 000000000000..3439b38e60f2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -0,0 +1,59 @@ +Qualcomm adreno/snapdragon GMU (Graphics management unit) + +The GMU is a programmable power controller for the GPU. the CPU controls the +GMU which in turn handles power controls for the GPU. + +Required properties: +- compatible: "qcom,adreno-gmu-XYZ.W", "qcom,adreno-gmu" + for example: "qcom,adreno-gmu-630.2", "qcom,adreno-gmu" + Note that you need to list the less specific "qcom,adreno-gmu" + for generic matches and the more specific identifier to identify + the specific device. +- reg: Physical base address and length of the GMU registers. +- reg-names: Matching names for the register regions + * "gmu" + * "gmu_pdc" + * "gmu_pdc_seg" +- interrupts: The interrupt signals from the GMU. +- interrupt-names: Matching names for the interrupts + * "hfi" + * "gmu" +- clocks: phandles to the device clocks +- clock-names: Matching names for the clocks + * "gmu" + * "cxo" + * "axi" + * "mnoc" +- power-domains: should be <&clock_gpucc GPU_CX_GDSC> +- iommus: phandle to the adreno iommu +- operating-points-v2: phandle to the OPP operating points + +Example: + +/ { + ... + + gmu: gmu@506a000 { + compatible="qcom,adreno-gmu-630.2", "qcom,adreno-gmu"; + + reg = <0x506a000 0x30000>, + <0xb280000 0x10000>, + <0xb480000 0x10000>; + reg-names = "gmu", "gmu_pdc", "gmu_pdc_seq"; + + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + + clocks = <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>; + clock-names = "gmu", "cxo", "axi", "memnoc"; + + power-domains = <&gpucc GPU_CX_GDSC>; + iommus = <&adreno_smmu 5>; + + operating-points-v2 = <&gmu_opp_table>; + }; +}; -- cgit v1.2.3 From 6de75d5567386a42b215a053d68db989691e91c6 Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 11 Dec 2018 10:42:20 -0800 Subject: drm/msm/dpu: Remove unused format tables. Signed-off-by: Fritz Koenig Signed-off-by: Sean Paul --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h | 73 ---------------------- 1 file changed, 73 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h index 3c9f028628ef..c37ba38ac83d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h @@ -93,76 +93,3 @@ static const struct dpu_format_extended plane_formats_yuv[] = { {DRM_FORMAT_YVU420, 0}, {0, 0}, }; - -static const struct dpu_format_extended cursor_formats[] = { - {DRM_FORMAT_ARGB8888, 0}, - {DRM_FORMAT_ABGR8888, 0}, - {DRM_FORMAT_RGBA8888, 0}, - {DRM_FORMAT_BGRA8888, 0}, - {DRM_FORMAT_XRGB8888, 0}, - {DRM_FORMAT_ARGB1555, 0}, - {DRM_FORMAT_ABGR1555, 0}, - {DRM_FORMAT_RGBA5551, 0}, - {DRM_FORMAT_BGRA5551, 0}, - {DRM_FORMAT_ARGB4444, 0}, - {DRM_FORMAT_ABGR4444, 0}, - {DRM_FORMAT_RGBA4444, 0}, - {DRM_FORMAT_BGRA4444, 0}, - {0, 0}, -}; - -static const struct dpu_format_extended wb2_formats[] = { - {DRM_FORMAT_RGB565, 0}, - {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_RGB888, 0}, - {DRM_FORMAT_ARGB8888, 0}, - {DRM_FORMAT_RGBA8888, 0}, - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_XRGB8888, 0}, - {DRM_FORMAT_RGBX8888, 0}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_ARGB1555, 0}, - {DRM_FORMAT_RGBA5551, 0}, - {DRM_FORMAT_XRGB1555, 0}, - {DRM_FORMAT_RGBX5551, 0}, - {DRM_FORMAT_ARGB4444, 0}, - {DRM_FORMAT_RGBA4444, 0}, - {DRM_FORMAT_RGBX4444, 0}, - {DRM_FORMAT_XRGB4444, 0}, - - {DRM_FORMAT_BGR565, 0}, - {DRM_FORMAT_BGR888, 0}, - {DRM_FORMAT_ABGR8888, 0}, - {DRM_FORMAT_BGRA8888, 0}, - {DRM_FORMAT_BGRX8888, 0}, - {DRM_FORMAT_XBGR8888, 0}, - {DRM_FORMAT_ABGR1555, 0}, - {DRM_FORMAT_BGRA5551, 0}, - {DRM_FORMAT_XBGR1555, 0}, - {DRM_FORMAT_BGRX5551, 0}, - {DRM_FORMAT_ABGR4444, 0}, - {DRM_FORMAT_BGRA4444, 0}, - {DRM_FORMAT_BGRX4444, 0}, - {DRM_FORMAT_XBGR4444, 0}, - - {DRM_FORMAT_YUV420, 0}, - {DRM_FORMAT_NV12, 0}, - {DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_NV16, 0}, - {DRM_FORMAT_YUYV, 0}, - - {0, 0}, -}; - -static const struct dpu_format_extended rgb_10bit_formats[] = { - {DRM_FORMAT_BGRA1010102, 0}, - {DRM_FORMAT_BGRX1010102, 0}, - {DRM_FORMAT_RGBA1010102, 0}, - {DRM_FORMAT_RGBX1010102, 0}, - {DRM_FORMAT_ABGR2101010, 0}, - {DRM_FORMAT_ABGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_XBGR2101010, 0}, - {DRM_FORMAT_XBGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_ARGB2101010, 0}, - {DRM_FORMAT_XRGB2101010, 0}, -}; -- cgit v1.2.3 From e6b63a7bb6cd9cd0496b7e6ee05a0bea217933f9 Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 11 Dec 2018 10:42:21 -0800 Subject: drm/msm/dpu: Use simple list for plane format init Simplify the initilization of a list of formats by passing the list in directly instead of copying it from one structure to another. Signed-off-by: Fritz Koenig Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 33 ----- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h | 14 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 19 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h | 151 ++++++++++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 25 ++-- 7 files changed, 93 insertions(+), 154 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c index 0874f0a53bf9..d53abc8ce670 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c @@ -1137,36 +1137,3 @@ const struct msm_format *dpu_get_msm_format( return &fmt->base; return NULL; } - -uint32_t dpu_populate_formats( - const struct dpu_format_extended *format_list, - uint32_t *pixel_formats, - uint64_t *pixel_modifiers, - uint32_t pixel_formats_max) -{ - uint32_t i, fourcc_format; - - if (!format_list || !pixel_formats) - return 0; - - for (i = 0, fourcc_format = 0; - format_list->fourcc_format && i < pixel_formats_max; - ++format_list) { - /* verify if listed format is in dpu_format_map? */ - - /* optionally return modified formats */ - if (pixel_modifiers) { - /* assume same modifier for all fb planes */ - pixel_formats[i] = format_list->fourcc_format; - pixel_modifiers[i++] = format_list->modifier; - } else { - /* assume base formats grouped together */ - if (fourcc_format != format_list->fourcc_format) { - fourcc_format = format_list->fourcc_format; - pixel_formats[i++] = fourcc_format; - } - } - } - - return i; -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h index a54451d8d011..c02c81e7a667 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h @@ -40,20 +40,6 @@ const struct msm_format *dpu_get_msm_format( const uint32_t format, const uint64_t modifiers); -/** - * dpu_populate_formats - populate the given array with fourcc codes supported - * @format_list: pointer to list of possible formats - * @pixel_formats: array to populate with fourcc codes - * @pixel_modifiers: array to populate with drm modifiers, can be NULL - * @pixel_formats_max: length of pixel formats array - * Return: number of elements populated - */ -uint32_t dpu_populate_formats( - const struct dpu_format_extended *format_list, - uint32_t *pixel_formats, - uint64_t *pixel_modifiers, - uint32_t pixel_formats_max); - /** * dpu_format_check_modified_format - validate format and buffers for * dpu non-standard, i.e. modified format diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 512ac0834d2b..df6852cc98b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -151,7 +151,9 @@ static const struct dpu_sspp_blks_common sdm845_sspp_common = { .id = DPU_SSPP_CSC_10BIT, \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ + .num_formats = ARRAY_SIZE(plane_formats_yuv), \ .virt_format_list = plane_formats, \ + .virt_num_formats = ARRAY_SIZE(plane_formats), \ } #define _DMA_SBLK(num, sdma_pri) \ @@ -163,7 +165,9 @@ static const struct dpu_sspp_blks_common sdm845_sspp_common = { .src_blk = {.name = STRCAT("sspp_src_", num), \ .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ .format_list = plane_formats, \ + .num_formats = ARRAY_SIZE(plane_formats), \ .virt_format_list = plane_formats, \ + .virt_num_formats = ARRAY_SIZE(plane_formats), \ } static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 144358a3d0fb..a55653b2e466 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -251,17 +251,6 @@ struct dpu_pp_blk { u32 version; }; -/** - * struct dpu_format_extended - define dpu specific pixel format+modifier - * @fourcc_format: Base FOURCC pixel format code - * @modifier: 64-bit drm format modifier, same modifier must be applied to all - * framebuffer planes - */ -struct dpu_format_extended { - uint32_t fourcc_format; - uint64_t modifier; -}; - /** * enum dpu_qos_lut_usage - define QoS LUT use cases */ @@ -348,7 +337,9 @@ struct dpu_sspp_blks_common { * @pcc_blk: * @igc_blk: * @format_list: Pointer to list of supported formats + * @num_formats: Number of supported formats * @virt_format_list: Pointer to list of supported formats for virtual planes + * @virt_num_formats: Number of supported formats for virtual planes */ struct dpu_sspp_sub_blks { const struct dpu_sspp_blks_common *common; @@ -366,8 +357,10 @@ struct dpu_sspp_sub_blks { struct dpu_pp_blk pcc_blk; struct dpu_pp_blk igc_blk; - const struct dpu_format_extended *format_list; - const struct dpu_format_extended *virt_format_list; + const u32 *format_list; + u32 num_formats; + const u32 *virt_format_list; + u32 virt_num_formats; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h index c37ba38ac83d..d09730985951 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h @@ -12,84 +12,81 @@ #include "dpu_hw_mdss.h" -static const struct dpu_format_extended plane_formats[] = { - {DRM_FORMAT_ARGB8888, 0}, - {DRM_FORMAT_ABGR8888, 0}, - {DRM_FORMAT_RGBA8888, 0}, - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_BGRA8888, 0}, - {DRM_FORMAT_XRGB8888, 0}, - {DRM_FORMAT_RGBX8888, 0}, - {DRM_FORMAT_BGRX8888, 0}, - {DRM_FORMAT_XBGR8888, 0}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_RGB888, 0}, - {DRM_FORMAT_BGR888, 0}, - {DRM_FORMAT_RGB565, 0}, - {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_BGR565, 0}, - {DRM_FORMAT_ARGB1555, 0}, - {DRM_FORMAT_ABGR1555, 0}, - {DRM_FORMAT_RGBA5551, 0}, - {DRM_FORMAT_BGRA5551, 0}, - {DRM_FORMAT_XRGB1555, 0}, - {DRM_FORMAT_XBGR1555, 0}, - {DRM_FORMAT_RGBX5551, 0}, - {DRM_FORMAT_BGRX5551, 0}, - {DRM_FORMAT_ARGB4444, 0}, - {DRM_FORMAT_ABGR4444, 0}, - {DRM_FORMAT_RGBA4444, 0}, - {DRM_FORMAT_BGRA4444, 0}, - {DRM_FORMAT_XRGB4444, 0}, - {DRM_FORMAT_XBGR4444, 0}, - {DRM_FORMAT_RGBX4444, 0}, - {DRM_FORMAT_BGRX4444, 0}, - {0, 0}, +static const uint32_t qcom_compressed_supported_formats[] = { + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_BGR565, }; -static const struct dpu_format_extended plane_formats_yuv[] = { - {DRM_FORMAT_ARGB8888, 0}, - {DRM_FORMAT_ABGR8888, 0}, - {DRM_FORMAT_RGBA8888, 0}, - {DRM_FORMAT_BGRX8888, 0}, - {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_BGRA8888, 0}, - {DRM_FORMAT_XRGB8888, 0}, - {DRM_FORMAT_XBGR8888, 0}, - {DRM_FORMAT_RGBX8888, 0}, - {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_RGB888, 0}, - {DRM_FORMAT_BGR888, 0}, - {DRM_FORMAT_RGB565, 0}, - {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_BGR565, 0}, - {DRM_FORMAT_ARGB1555, 0}, - {DRM_FORMAT_ABGR1555, 0}, - {DRM_FORMAT_RGBA5551, 0}, - {DRM_FORMAT_BGRA5551, 0}, - {DRM_FORMAT_XRGB1555, 0}, - {DRM_FORMAT_XBGR1555, 0}, - {DRM_FORMAT_RGBX5551, 0}, - {DRM_FORMAT_BGRX5551, 0}, - {DRM_FORMAT_ARGB4444, 0}, - {DRM_FORMAT_ABGR4444, 0}, - {DRM_FORMAT_RGBA4444, 0}, - {DRM_FORMAT_BGRA4444, 0}, - {DRM_FORMAT_XRGB4444, 0}, - {DRM_FORMAT_XBGR4444, 0}, - {DRM_FORMAT_RGBX4444, 0}, - {DRM_FORMAT_BGRX4444, 0}, +static const uint32_t plane_formats[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_ABGR1555, + DRM_FORMAT_RGBA5551, + DRM_FORMAT_BGRA5551, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_RGBX5551, + DRM_FORMAT_BGRX5551, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_ABGR4444, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_BGRA4444, + DRM_FORMAT_XRGB4444, + DRM_FORMAT_XBGR4444, + DRM_FORMAT_RGBX4444, + DRM_FORMAT_BGRX4444, +}; + +static const uint32_t plane_formats_yuv[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_ABGR1555, + DRM_FORMAT_RGBA5551, + DRM_FORMAT_BGRA5551, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_RGBX5551, + DRM_FORMAT_BGRX5551, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_ABGR4444, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_BGRA4444, + DRM_FORMAT_XRGB4444, + DRM_FORMAT_XBGR4444, + DRM_FORMAT_RGBX4444, + DRM_FORMAT_BGRX4444, - {DRM_FORMAT_NV12, 0}, - {DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED}, - {DRM_FORMAT_NV21, 0}, - {DRM_FORMAT_NV16, 0}, - {DRM_FORMAT_NV61, 0}, - {DRM_FORMAT_VYUY, 0}, - {DRM_FORMAT_UYVY, 0}, - {DRM_FORMAT_YUYV, 0}, - {DRM_FORMAT_YVYU, 0}, - {DRM_FORMAT_YUV420, 0}, - {DRM_FORMAT_YVU420, 0}, - {0, 0}, + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_VYUY, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_YUV420, + DRM_FORMAT_YVU420, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index 321fc64ddd0e..efe70c508ee0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -18,7 +18,6 @@ #include "dpu_hw_mdss.h" #define REG_MASK(n) ((BIT(n)) - 1) -struct dpu_format_extended; /* * This is the common struct maintained by each sub block diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 6aefcd6db46b..ee5f484937b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -95,8 +95,6 @@ struct dpu_plane { enum dpu_sspp pipe; uint32_t features; /* capabilities from catalog */ - uint32_t nformats; - uint32_t formats[64]; struct dpu_hw_pipe *pipe_hw; struct dpu_hw_pipe_cfg pipe_cfg; @@ -1444,11 +1442,12 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, unsigned long possible_crtcs, u32 master_plane_id) { struct drm_plane *plane = NULL, *master_plane = NULL; - const struct dpu_format_extended *format_list; + const uint32_t *format_list; struct dpu_plane *pdpu; struct msm_drm_private *priv = dev->dev_private; struct dpu_kms *kms = to_dpu_kms(priv->kms); int zpos_max = DPU_ZPOS_MAX; + uint32_t num_formats; int ret = -EINVAL; /* create and zero local structure */ @@ -1491,23 +1490,17 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, goto clean_sspp; } - if (!master_plane_id) - format_list = pdpu->pipe_sblk->format_list; - else + if (pdpu->is_virtual) { format_list = pdpu->pipe_sblk->virt_format_list; - - pdpu->nformats = dpu_populate_formats(format_list, - pdpu->formats, - 0, - ARRAY_SIZE(pdpu->formats)); - - if (!pdpu->nformats) { - DPU_ERROR("[%u]no valid formats for plane\n", pipe); - goto clean_sspp; + num_formats = pdpu->pipe_sblk->virt_num_formats; + } + else { + format_list = pdpu->pipe_sblk->format_list; + num_formats = pdpu->pipe_sblk->num_formats; } ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, - pdpu->formats, pdpu->nformats, + format_list, num_formats, NULL, type, NULL); if (ret) goto clean_sspp; -- cgit v1.2.3 From 410f119ba726e0af6a5734f20e004a77240a7b0b Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 11 Dec 2018 10:42:22 -0800 Subject: drm/msm/dpu: Plane helper for modifiers Filter planes based on the supported modifiers Signed-off-by: Fritz Koenig Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ee5f484937b9..020a23ca606a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1408,6 +1408,23 @@ static void dpu_plane_early_unregister(struct drm_plane *plane) debugfs_remove_recursive(pdpu->debugfs_root); } +static bool dpu_plane_format_mod_supported(struct drm_plane *plane, + uint32_t format, uint64_t modifier) +{ + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) { + int i; + for (i = 0; i < ARRAY_SIZE(qcom_compressed_supported_formats); i++) { + if (format == qcom_compressed_supported_formats[i]) + return true; + } + } + + return false; +} + static const struct drm_plane_funcs dpu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -1417,6 +1434,7 @@ static const struct drm_plane_funcs dpu_plane_funcs = { .atomic_destroy_state = dpu_plane_destroy_state, .late_register = dpu_plane_late_register, .early_unregister = dpu_plane_early_unregister, + .format_mod_supported = dpu_plane_format_mod_supported, }; static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = { -- cgit v1.2.3 From 3ba25595e235d48a00f65084d6d35458abe9885e Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 11 Dec 2018 10:42:23 -0800 Subject: drm/msm/dpu: Initialize supported modifiers Pass list of supported modifiers to plane init. Signed-off-by: Fritz Koenig Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 020a23ca606a..b01183b309b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -119,6 +119,12 @@ struct dpu_plane { bool debugfs_default_scale; }; +static const uint64_t supported_format_modifiers[] = { + DRM_FORMAT_MOD_QCOM_COMPRESSED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + #define to_dpu_plane(x) container_of(x, struct dpu_plane, base) static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) @@ -1519,7 +1525,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, format_list, num_formats, - NULL, type, NULL); + supported_format_modifiers, type, NULL); if (ret) goto clean_sspp; -- cgit v1.2.3 From 918ce5b981eab7b3340e0b44a64454b58d2b7c8a Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 11 Dec 2018 10:42:24 -0800 Subject: drm/msm/dpu: Correct initialization of modifiers allow_fb_modifiers needs to be set before drm_universal_plane_init is called. Signed-off-by: Fritz Koenig Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 4d67b3c96702..56555c3a750a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -926,16 +926,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) goto hw_intr_init_err; } - /* - * _dpu_kms_drm_obj_init should create the DRM related objects - * i.e. CRTCs, planes, encoders, connectors and so forth - */ - rc = _dpu_kms_drm_obj_init(dpu_kms); - if (rc) { - DPU_ERROR("modeset init failed: %d\n", rc); - goto drm_obj_init_err; - } - dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; @@ -952,6 +942,16 @@ static int dpu_kms_hw_init(struct msm_kms *kms) */ dev->mode_config.allow_fb_modifiers = true; + /* + * _dpu_kms_drm_obj_init should create the DRM related objects + * i.e. CRTCs, planes, encoders, connectors and so forth + */ + rc = _dpu_kms_drm_obj_init(dpu_kms); + if (rc) { + DPU_ERROR("modeset init failed: %d\n", rc); + goto drm_obj_init_err; + } + dpu_vbif_init_memtypes(dpu_kms); pm_runtime_put_sync(&dpu_kms->pdev->dev); -- cgit v1.2.3 From 8998010c538d43509fd890c0dd9e147259cc4254 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:33 -0800 Subject: drm/msm/dpu: avoid tracking reservations in RM RM was equipped with reservation tracking structure RSVP to cache HW reservation of displays for certain clients where atomic_checks (atomic commit with TEST_ONLY) for all the displays are called before their respective atomic_commits. Since DPU doesn't support the sequence anymore, clean up the support from RM. Replace rsvp with the corresponding encoder id to tag the HW blocks reserved. It prepares DPU to get rid of RM altogether and track reservations using private states. changes in v2: - none Signed-off-by: Jeykumar Sankaran Reviewed-by: Sean Paul Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 284 +++++---------------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 4 - 2 files changed, 43 insertions(+), 245 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index bdb117709674..36a929bc1d18 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -21,8 +21,8 @@ #include "dpu_encoder.h" #include "dpu_trace.h" -#define RESERVED_BY_OTHER(h, r) \ - ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) +#define RESERVED_BY_OTHER(h, r) \ + ((h)->enc_id && (h)->enc_id != r) /** * struct dpu_rm_requirements - Reservation requirements parameter bundle @@ -34,85 +34,23 @@ struct dpu_rm_requirements { struct dpu_encoder_hw_resources hw_res; }; -/** - * struct dpu_rm_rsvp - Use Case Reservation tagging structure - * Used to tag HW blocks as reserved by a CRTC->Encoder->Connector chain - * By using as a tag, rather than lists of pointers to HW blocks used - * we can avoid some list management since we don't know how many blocks - * of each type a given use case may require. - * @list: List head for list of all reservations - * @seq: Global RSVP sequence number for debugging, especially for - * differentiating differenct allocations for same encoder. - * @enc_id: Reservations are tracked by Encoder DRM object ID. - * CRTCs may be connected to multiple Encoders. - * An encoder or connector id identifies the display path. - */ -struct dpu_rm_rsvp { - struct list_head list; - uint32_t seq; - uint32_t enc_id; -}; /** * struct dpu_rm_hw_blk - hardware block tracking list member * @list: List head for list of all hardware blocks tracking items - * @rsvp: Pointer to use case reservation if reserved by a client - * @rsvp_nxt: Temporary pointer used during reservation to the incoming - * request. Will be swapped into rsvp if proposal is accepted * @type: Type of hardware block this structure tracks * @id: Hardware ID number, within it's own space, ie. LM_X - * @catalog: Pointer to the hardware catalog entry for this block + * @enc_id: Encoder id to which this blk is binded * @hw: Pointer to the hardware register access object for this block */ struct dpu_rm_hw_blk { struct list_head list; - struct dpu_rm_rsvp *rsvp; - struct dpu_rm_rsvp *rsvp_nxt; enum dpu_hw_blk_type type; uint32_t id; + uint32_t enc_id; struct dpu_hw_blk *hw; }; -/** - * dpu_rm_dbg_rsvp_stage - enum of steps in making reservation for event logging - */ -enum dpu_rm_dbg_rsvp_stage { - DPU_RM_STAGE_BEGIN, - DPU_RM_STAGE_AFTER_CLEAR, - DPU_RM_STAGE_AFTER_RSVPNEXT, - DPU_RM_STAGE_FINAL -}; - -static void _dpu_rm_print_rsvps( - struct dpu_rm *rm, - enum dpu_rm_dbg_rsvp_stage stage) -{ - struct dpu_rm_rsvp *rsvp; - struct dpu_rm_hw_blk *blk; - enum dpu_hw_blk_type type; - - DPU_DEBUG("%d\n", stage); - - list_for_each_entry(rsvp, &rm->rsvps, list) { - DRM_DEBUG_KMS("%d rsvp[s%ue%u]\n", stage, rsvp->seq, - rsvp->enc_id); - } - - for (type = 0; type < DPU_HW_BLK_MAX; type++) { - list_for_each_entry(blk, &rm->hw_blks[type], list) { - if (!blk->rsvp && !blk->rsvp_nxt) - continue; - - DRM_DEBUG_KMS("%d rsvp[s%ue%u->s%ue%u] %d %d\n", stage, - (blk->rsvp) ? blk->rsvp->seq : 0, - (blk->rsvp) ? blk->rsvp->enc_id : 0, - (blk->rsvp_nxt) ? blk->rsvp_nxt->seq : 0, - (blk->rsvp_nxt) ? blk->rsvp_nxt->enc_id : 0, - blk->type, blk->id); - } - } -} - struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm) { return rm->hw_mdp; @@ -148,15 +86,13 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) i->blk = list_prepare_entry(i->blk, blk_list, list); list_for_each_entry_continue(i->blk, blk_list, list) { - struct dpu_rm_rsvp *rsvp = i->blk->rsvp; - if (i->blk->type != i->type) { DPU_ERROR("found incorrect block type %d on %d list\n", i->blk->type, i->type); return false; } - if ((i->enc_id == 0) || (rsvp && rsvp->enc_id == i->enc_id)) { + if (i->enc_id == i->blk->enc_id) { i->hw = i->blk->hw; DPU_DEBUG("found type %d id %d for enc %d\n", i->type, i->blk->id, i->enc_id); @@ -208,22 +144,9 @@ static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw) int dpu_rm_destroy(struct dpu_rm *rm) { - - struct dpu_rm_rsvp *rsvp_cur, *rsvp_nxt; struct dpu_rm_hw_blk *hw_cur, *hw_nxt; enum dpu_hw_blk_type type; - if (!rm) { - DPU_ERROR("invalid rm\n"); - return -EINVAL; - } - - list_for_each_entry_safe(rsvp_cur, rsvp_nxt, &rm->rsvps, list) { - list_del(&rsvp_cur->list); - kfree(rsvp_cur); - } - - for (type = 0; type < DPU_HW_BLK_MAX; type++) { list_for_each_entry_safe(hw_cur, hw_nxt, &rm->hw_blks[type], list) { @@ -293,6 +216,7 @@ static int _dpu_rm_hw_blk_create( blk->type = type; blk->id = id; blk->hw = hw; + blk->enc_id = 0; list_add_tail(&blk->list, &rm->hw_blks[type]); return 0; @@ -316,7 +240,6 @@ int dpu_rm_init(struct dpu_rm *rm, mutex_init(&rm->rm_lock); - INIT_LIST_HEAD(&rm->rsvps); for (type = 0; type < DPU_HW_BLK_MAX; type++) INIT_LIST_HEAD(&rm->hw_blks[type]); @@ -410,7 +333,7 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) * proposed use case requirements, incl. hardwired dependent blocks like * pingpong * @rm: dpu resource manager handle - * @rsvp: reservation currently being created + * @enc_id: encoder id requesting for allocation * @reqs: proposed use case requirements * @lm: proposed layer mixer, function checks if lm, and all other hardwired * blocks connected to the lm (pp) is available and appropriate @@ -422,7 +345,7 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) */ static bool _dpu_rm_check_lm_and_get_connected_blks( struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, + uint32_t enc_id, struct dpu_rm_requirements *reqs, struct dpu_rm_hw_blk *lm, struct dpu_rm_hw_blk **pp, @@ -449,7 +372,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( } /* Already reserved? */ - if (RESERVED_BY_OTHER(lm, rsvp)) { + if (RESERVED_BY_OTHER(lm, enc_id)) { DPU_DEBUG("lm %d already reserved\n", lm_cfg->id); return false; } @@ -467,7 +390,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( return false; } - if (RESERVED_BY_OTHER(*pp, rsvp)) { + if (RESERVED_BY_OTHER(*pp, enc_id)) { DPU_DEBUG("lm %d pp %d already reserved\n", lm->id, (*pp)->id); return false; @@ -476,10 +399,8 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( return true; } -static int _dpu_rm_reserve_lms( - struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, - struct dpu_rm_requirements *reqs) +static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, + struct dpu_rm_requirements *reqs) { struct dpu_rm_hw_blk *lm[MAX_BLOCKS]; @@ -504,7 +425,7 @@ static int _dpu_rm_reserve_lms( lm[lm_count] = iter_i.blk; if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, rsvp, reqs, lm[lm_count], + rm, enc_id, reqs, lm[lm_count], &pp[lm_count], NULL)) continue; @@ -519,7 +440,7 @@ static int _dpu_rm_reserve_lms( continue; if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, rsvp, reqs, iter_j.blk, + rm, enc_id, reqs, iter_j.blk, &pp[lm_count], iter_i.blk)) continue; @@ -537,10 +458,10 @@ static int _dpu_rm_reserve_lms( if (!lm[i]) break; - lm[i]->rsvp_nxt = rsvp; - pp[i]->rsvp_nxt = rsvp; + lm[i]->enc_id = enc_id; + pp[i]->enc_id = enc_id; - trace_dpu_rm_reserve_lms(lm[i]->id, lm[i]->type, rsvp->enc_id, + trace_dpu_rm_reserve_lms(lm[i]->id, lm[i]->type, enc_id, pp[i]->id); } @@ -549,7 +470,7 @@ static int _dpu_rm_reserve_lms( static int _dpu_rm_reserve_ctls( struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, + uint32_t enc_id, const struct msm_display_topology *top) { struct dpu_rm_hw_blk *ctls[MAX_BLOCKS]; @@ -570,7 +491,7 @@ static int _dpu_rm_reserve_ctls( unsigned long features = ctl->caps->features; bool has_split_display; - if (RESERVED_BY_OTHER(iter.blk, rsvp)) + if (RESERVED_BY_OTHER(iter.blk, enc_id)) continue; has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features; @@ -591,9 +512,9 @@ static int _dpu_rm_reserve_ctls( return -ENAVAIL; for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) { - ctls[i]->rsvp_nxt = rsvp; + ctls[i]->enc_id = enc_id; trace_dpu_rm_reserve_ctls(ctls[i]->id, ctls[i]->type, - rsvp->enc_id); + enc_id); } return 0; @@ -601,7 +522,7 @@ static int _dpu_rm_reserve_ctls( static int _dpu_rm_reserve_intf( struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, + uint32_t enc_id, uint32_t id, enum dpu_hw_blk_type type) { @@ -614,14 +535,14 @@ static int _dpu_rm_reserve_intf( if (iter.blk->id != id) continue; - if (RESERVED_BY_OTHER(iter.blk, rsvp)) { + if (RESERVED_BY_OTHER(iter.blk, enc_id)) { DPU_ERROR("type %d id %d already reserved\n", type, id); return -ENAVAIL; } - iter.blk->rsvp_nxt = rsvp; + iter.blk->enc_id = enc_id; trace_dpu_rm_reserve_intf(iter.blk->id, iter.blk->type, - rsvp->enc_id); + enc_id); break; } @@ -636,7 +557,7 @@ static int _dpu_rm_reserve_intf( static int _dpu_rm_reserve_intf_related_hw( struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, + uint32_t enc_id, struct dpu_encoder_hw_resources *hw_res) { int i, ret = 0; @@ -646,7 +567,7 @@ static int _dpu_rm_reserve_intf_related_hw( if (hw_res->intfs[i] == INTF_MODE_NONE) continue; id = i + INTF_0; - ret = _dpu_rm_reserve_intf(rm, rsvp, id, + ret = _dpu_rm_reserve_intf(rm, enc_id, id, DPU_HW_BLK_INTF); if (ret) return ret; @@ -655,33 +576,27 @@ static int _dpu_rm_reserve_intf_related_hw( return ret; } -static int _dpu_rm_make_next_rsvp( +static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct dpu_rm_rsvp *rsvp, struct dpu_rm_requirements *reqs) { int ret; - /* Create reservation info, tag reserved blocks with it as we go */ - rsvp->seq = ++rm->rsvp_next_seq; - rsvp->enc_id = enc->base.id; - list_add_tail(&rsvp->list, &rm->rsvps); - - ret = _dpu_rm_reserve_lms(rm, rsvp, reqs); + ret = _dpu_rm_reserve_lms(rm, enc->base.id, reqs); if (ret) { DPU_ERROR("unable to find appropriate mixers\n"); return ret; } - ret = _dpu_rm_reserve_ctls(rm, rsvp, &reqs->topology); + ret = _dpu_rm_reserve_ctls(rm, enc->base.id, &reqs->topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - ret = _dpu_rm_reserve_intf_related_hw(rm, rsvp, &reqs->hw_res); + ret = _dpu_rm_reserve_intf_related_hw(rm, enc->base.id, &reqs->hw_res); if (ret) return ret; @@ -706,108 +621,31 @@ static int _dpu_rm_populate_requirements( return 0; } -static struct dpu_rm_rsvp *_dpu_rm_get_rsvp( - struct dpu_rm *rm, - struct drm_encoder *enc) +static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) { - struct dpu_rm_rsvp *i; - - if (!rm || !enc) { - DPU_ERROR("invalid params\n"); - return NULL; - } - - if (list_empty(&rm->rsvps)) - return NULL; - - list_for_each_entry(i, &rm->rsvps, list) - if (i->enc_id == enc->base.id) - return i; - - return NULL; -} - -/** - * _dpu_rm_release_rsvp - release resources and release a reservation - * @rm: KMS handle - * @rsvp: RSVP pointer to release and release resources for - */ -static void _dpu_rm_release_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp) -{ - struct dpu_rm_rsvp *rsvp_c, *rsvp_n; struct dpu_rm_hw_blk *blk; enum dpu_hw_blk_type type; - if (!rsvp) - return; - - DPU_DEBUG("rel rsvp %d enc %d\n", rsvp->seq, rsvp->enc_id); - - list_for_each_entry_safe(rsvp_c, rsvp_n, &rm->rsvps, list) { - if (rsvp == rsvp_c) { - list_del(&rsvp_c->list); - break; - } - } - for (type = 0; type < DPU_HW_BLK_MAX; type++) { list_for_each_entry(blk, &rm->hw_blks[type], list) { - if (blk->rsvp == rsvp) { - blk->rsvp = NULL; - DPU_DEBUG("rel rsvp %d enc %d %d %d\n", - rsvp->seq, rsvp->enc_id, - blk->type, blk->id); - } - if (blk->rsvp_nxt == rsvp) { - blk->rsvp_nxt = NULL; - DPU_DEBUG("rel rsvp_nxt %d enc %d %d %d\n", - rsvp->seq, rsvp->enc_id, - blk->type, blk->id); + if (blk->enc_id == enc_id) { + blk->enc_id = 0; + DPU_DEBUG("rel enc %d %d %d\n", enc_id, + blk->type, blk->id); } } } - - kfree(rsvp); } void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) { - struct dpu_rm_rsvp *rsvp; - - if (!rm || !enc) { - DPU_ERROR("invalid params\n"); - return; - } - mutex_lock(&rm->rm_lock); - rsvp = _dpu_rm_get_rsvp(rm, enc); - if (!rsvp) { - DPU_ERROR("failed to find rsvp for enc %d\n", enc->base.id); - goto end; - } + _dpu_rm_release_reservation(rm, enc->base.id); - _dpu_rm_release_rsvp(rm, rsvp); -end: mutex_unlock(&rm->rm_lock); } -static void _dpu_rm_commit_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp) -{ - struct dpu_rm_hw_blk *blk; - enum dpu_hw_blk_type type; - - /* Swap next rsvp to be the active */ - for (type = 0; type < DPU_HW_BLK_MAX; type++) { - list_for_each_entry(blk, &rm->hw_blks[type], list) { - if (blk->rsvp_nxt) { - blk->rsvp = blk->rsvp_nxt; - blk->rsvp_nxt = NULL; - } - } - } -} - int dpu_rm_reserve( struct dpu_rm *rm, struct drm_encoder *enc, @@ -815,7 +653,6 @@ int dpu_rm_reserve( struct msm_display_topology topology, bool test_only) { - struct dpu_rm_rsvp *rsvp_cur, *rsvp_nxt; struct dpu_rm_requirements reqs; int ret; @@ -828,8 +665,6 @@ int dpu_rm_reserve( mutex_lock(&rm->rm_lock); - _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_BEGIN); - ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, &reqs, topology); if (ret) { @@ -837,50 +672,17 @@ int dpu_rm_reserve( goto end; } - /* - * We only support one active reservation per-hw-block. But to implement - * transactional semantics for test-only, and for allowing failure while - * modifying your existing reservation, over the course of this - * function we can have two reservations: - * Current: Existing reservation - * Next: Proposed reservation. The proposed reservation may fail, or may - * be discarded if in test-only mode. - * If reservation is successful, and we're not in test-only, then we - * replace the current with the next. - */ - rsvp_nxt = kzalloc(sizeof(*rsvp_nxt), GFP_KERNEL); - if (!rsvp_nxt) { - ret = -ENOMEM; - goto end; - } - - rsvp_cur = _dpu_rm_get_rsvp(rm, enc); - - /* Check the proposed reservation, store it in hw's "next" field */ - ret = _dpu_rm_make_next_rsvp(rm, enc, crtc_state, rsvp_nxt, &reqs); - - _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_AFTER_RSVPNEXT); - + ret = _dpu_rm_make_reservation(rm, enc, crtc_state, &reqs); if (ret) { DPU_ERROR("failed to reserve hw resources: %d\n", ret); - _dpu_rm_release_rsvp(rm, rsvp_nxt); + _dpu_rm_release_reservation(rm, enc->base.id); } else if (test_only) { - /* - * Normally, if test_only, test the reservation and then undo - * However, if the user requests LOCK, then keep the reservation - * made during the atomic_check phase. - */ - DPU_DEBUG("test_only: discard test rsvp[s%de%d]\n", - rsvp_nxt->seq, rsvp_nxt->enc_id); - _dpu_rm_release_rsvp(rm, rsvp_nxt); - } else { - _dpu_rm_release_rsvp(rm, rsvp_cur); - - _dpu_rm_commit_rsvp(rm, rsvp_nxt); + /* test_only: test the reservation and then undo */ + DPU_DEBUG("test_only: discard test [enc: %d]\n", + enc->base.id); + _dpu_rm_release_reservation(rm, enc->base.id); } - _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_FINAL); - end: mutex_unlock(&rm->rm_lock); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index b8273bd23801..0dd3c2131ca1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -23,21 +23,17 @@ /** * struct dpu_rm - DPU dynamic hardware resource manager * @dev: device handle for event logging purposes - * @rsvps: list of hardware reservations by each crtc->encoder->connector * @hw_blks: array of lists of hardware resources present in the system, one * list per type of hardware block * @hw_mdp: hardware object for mdp_top * @lm_max_width: cached layer mixer maximum width - * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rm_lock: resource manager mutex */ struct dpu_rm { struct drm_device *dev; - struct list_head rsvps; struct list_head hw_blks[DPU_HW_BLK_MAX]; struct dpu_hw_mdp *hw_mdp; uint32_t lm_max_width; - uint32_t rsvp_next_seq; struct mutex rm_lock; }; -- cgit v1.2.3 From 3763f1a551100578fe3bf11fb1d1781f22808453 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:34 -0800 Subject: drm/msm/dpu: remove dev from RM Not used. Remove from RM. changes in v2: - none Signed-off-by: Jeykumar Sankaran Reviewed-by: Sean Paul Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 ++----- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 6 +----- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 56555c3a750a..05edd8580a81 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -877,8 +877,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) goto power_error; } - rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mmio, - dpu_kms->dev); + rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mmio); if (rc) { DPU_ERROR("rm init failed: %d\n", rc); goto power_error; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 36a929bc1d18..5ce89b9050da 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -224,13 +224,12 @@ static int _dpu_rm_hw_blk_create( int dpu_rm_init(struct dpu_rm *rm, struct dpu_mdss_cfg *cat, - void __iomem *mmio, - struct drm_device *dev) + void __iomem *mmio) { int rc, i; enum dpu_hw_blk_type type; - if (!rm || !cat || !mmio || !dev) { + if (!rm || !cat || !mmio) { DPU_ERROR("invalid kms\n"); return -EINVAL; } @@ -243,8 +242,6 @@ int dpu_rm_init(struct dpu_rm *rm, for (type = 0; type < DPU_HW_BLK_MAX; type++) INIT_LIST_HEAD(&rm->hw_blks[type]); - rm->dev = dev; - /* Some of the sub-blocks require an mdptop to be created */ rm->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, mmio, cat); if (IS_ERR_OR_NULL(rm->hw_mdp)) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 0dd3c2131ca1..f41fd19e24bd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -22,7 +22,6 @@ /** * struct dpu_rm - DPU dynamic hardware resource manager - * @dev: device handle for event logging purposes * @hw_blks: array of lists of hardware resources present in the system, one * list per type of hardware block * @hw_mdp: hardware object for mdp_top @@ -30,7 +29,6 @@ * @rm_lock: resource manager mutex */ struct dpu_rm { - struct drm_device *dev; struct list_head hw_blks[DPU_HW_BLK_MAX]; struct dpu_hw_mdp *hw_mdp; uint32_t lm_max_width; @@ -63,13 +61,11 @@ struct dpu_rm_hw_iter { * @rm: DPU Resource Manager handle * @cat: Pointer to hardware catalog * @mmio: mapped register io address of MDP - * @dev: device handle for event logging purposes * @Return: 0 on Success otherwise -ERROR */ int dpu_rm_init(struct dpu_rm *rm, struct dpu_mdss_cfg *cat, - void __iomem *mmio, - struct drm_device *dev); + void __iomem *mmio); /** * dpu_rm_destroy - Free all memory allocated by dpu_rm_init -- cgit v1.2.3 From 720a221f8770b59ab9fd35f71e568b0013a3fe24 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:35 -0800 Subject: drm/msm/dpu: clean up dpu_rm_check_property_topctl declaration Definition was removed already. Clean up header declaration. changes in v2: - none Signed-off-by: Jeykumar Sankaran Reviewed-by: Sean Paul Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index f41fd19e24bd..eb6a6ac6483b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -136,12 +136,4 @@ void dpu_rm_init_hw_iter( * @Return: true on match found, false on no match found */ bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter); - -/** - * dpu_rm_check_property_topctl - validate property bitmask before it is set - * @val: user's proposed topology control bitmask - * @Return: 0 on success or error - */ -int dpu_rm_check_property_topctl(uint64_t val); - #endif /* __DPU_RM_H__ */ -- cgit v1.2.3 From ab92182cddd37ce4a944058d26533e4b0e0af2c2 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:36 -0800 Subject: drm/msm/dpu: remove encoder from crtc mixer struct Not actively used. Clean up the crtc mixer struct. changes in v2: - none Signed-off-by: Jeykumar Sankaran Reviewed-by: Sean Paul Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 9be7c355debd..d6e692598b52 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -465,8 +465,6 @@ static void _dpu_crtc_setup_mixer_for_encoder( return; } - mixer->encoder = enc; - cstate->num_mixers++; DPU_DEBUG("setup mixer %d: lm %d\n", i, mixer->hw_lm->idx - LM_0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index dbfb38a1986c..e59d62be4980 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -84,14 +84,12 @@ struct dpu_crtc_smmu_state_data { * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC * @hw_lm: LM HW Driver context * @lm_ctl: CTL Path HW driver context - * @encoder: Encoder attached to this lm & ctl * @mixer_op_mode: mixer blending operation mode * @flush_mask: mixer flush mask for ctl, mixer and pipe */ struct dpu_crtc_mixer { struct dpu_hw_mixer *hw_lm; struct dpu_hw_ctl *lm_ctl; - struct drm_encoder *encoder; u32 mixer_op_mode; u32 flush_mask; }; -- cgit v1.2.3 From 1a5e177856039bc75e30a18e89db79d4b17d6981 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:37 -0800 Subject: drm/msm/dpu: clean up redundant hw type struct dpu_hw_blk has hw block type info. Remove duplicate type tracking in struct dpu_rm_hw_blk. changes in v2: - remove redundant type in trace api's (Sean Paul) Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 22 +++++----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 28 +++++++++++----------------- 2 files changed, 16 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 5ce89b9050da..e7fc9a48c9e4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -38,14 +38,12 @@ struct dpu_rm_requirements { /** * struct dpu_rm_hw_blk - hardware block tracking list member * @list: List head for list of all hardware blocks tracking items - * @type: Type of hardware block this structure tracks * @id: Hardware ID number, within it's own space, ie. LM_X * @enc_id: Encoder id to which this blk is binded * @hw: Pointer to the hardware register access object for this block */ struct dpu_rm_hw_blk { struct list_head list; - enum dpu_hw_blk_type type; uint32_t id; uint32_t enc_id; struct dpu_hw_blk *hw; @@ -86,12 +84,6 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) i->blk = list_prepare_entry(i->blk, blk_list, list); list_for_each_entry_continue(i->blk, blk_list, list) { - if (i->blk->type != i->type) { - DPU_ERROR("found incorrect block type %d on %d list\n", - i->blk->type, i->type); - return false; - } - if (i->enc_id == i->blk->enc_id) { i->hw = i->blk->hw; DPU_DEBUG("found type %d id %d for enc %d\n", @@ -151,7 +143,7 @@ int dpu_rm_destroy(struct dpu_rm *rm) list_for_each_entry_safe(hw_cur, hw_nxt, &rm->hw_blks[type], list) { list_del(&hw_cur->list); - _dpu_rm_hw_destroy(hw_cur->type, hw_cur->hw); + _dpu_rm_hw_destroy(type, hw_cur->hw); kfree(hw_cur); } } @@ -213,7 +205,6 @@ static int _dpu_rm_hw_blk_create( return -ENOMEM; } - blk->type = type; blk->id = id; blk->hw = hw; blk->enc_id = 0; @@ -458,8 +449,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, lm[i]->enc_id = enc_id; pp[i]->enc_id = enc_id; - trace_dpu_rm_reserve_lms(lm[i]->id, lm[i]->type, enc_id, - pp[i]->id); + trace_dpu_rm_reserve_lms(lm[i]->id, enc_id, pp[i]->id); } return rc; @@ -510,8 +500,7 @@ static int _dpu_rm_reserve_ctls( for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) { ctls[i]->enc_id = enc_id; - trace_dpu_rm_reserve_ctls(ctls[i]->id, ctls[i]->type, - enc_id); + trace_dpu_rm_reserve_ctls(ctls[i]->id, enc_id); } return 0; @@ -538,8 +527,7 @@ static int _dpu_rm_reserve_intf( } iter.blk->enc_id = enc_id; - trace_dpu_rm_reserve_intf(iter.blk->id, iter.blk->type, - enc_id); + trace_dpu_rm_reserve_intf(iter.blk->id, enc_id); break; } @@ -628,7 +616,7 @@ static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) if (blk->enc_id == enc_id) { blk->enc_id = 0; DPU_DEBUG("rel enc %d %d %d\n", enc_id, - blk->type, blk->id); + type, blk->id); } } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index c78b521ceda1..8bb46090bd16 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -831,48 +831,42 @@ TRACE_EVENT(dpu_plane_disable, ); DECLARE_EVENT_CLASS(dpu_rm_iter_template, - TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id), - TP_ARGS(id, type, enc_id), + TP_PROTO(uint32_t id, uint32_t enc_id), + TP_ARGS(id, enc_id), TP_STRUCT__entry( __field( uint32_t, id ) - __field( enum dpu_hw_blk_type, type ) __field( uint32_t, enc_id ) ), TP_fast_assign( __entry->id = id; - __entry->type = type; __entry->enc_id = enc_id; ), - TP_printk("id:%d type:%d enc_id:%u", __entry->id, __entry->type, - __entry->enc_id) + TP_printk("id:%d enc_id:%u", __entry->id, __entry->enc_id) ); DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_intf, - TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id), - TP_ARGS(id, type, enc_id) + TP_PROTO(uint32_t id, uint32_t enc_id), + TP_ARGS(id, enc_id) ); DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_ctls, - TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id), - TP_ARGS(id, type, enc_id) + TP_PROTO(uint32_t id, uint32_t enc_id), + TP_ARGS(id, enc_id) ); TRACE_EVENT(dpu_rm_reserve_lms, - TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id, - uint32_t pp_id), - TP_ARGS(id, type, enc_id, pp_id), + TP_PROTO(uint32_t id, uint32_t enc_id, uint32_t pp_id), + TP_ARGS(id, enc_id, pp_id), TP_STRUCT__entry( __field( uint32_t, id ) - __field( enum dpu_hw_blk_type, type ) __field( uint32_t, enc_id ) __field( uint32_t, pp_id ) ), TP_fast_assign( __entry->id = id; - __entry->type = type; __entry->enc_id = enc_id; __entry->pp_id = pp_id; ), - TP_printk("id:%d type:%d enc_id:%u pp_id:%u", __entry->id, - __entry->type, __entry->enc_id, __entry->pp_id) + TP_printk("id:%d enc_id:%u pp_id:%u", __entry->id, + __entry->enc_id, __entry->pp_id) ); TRACE_EVENT(dpu_vbif_wait_xin_halt_fail, -- cgit v1.2.3 From 7579cb0533d7ce92b52cd40c9080e690e6548b5a Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 7 Dec 2018 18:38:38 -0800 Subject: drm/msm/dpu: maintain hw_mdp in kms hw_mdp block is common for displays. No need to reserve per display. changes in v2: - use IS_ERR for error checking (Jordan Crouse) Signed-off-by: Jeykumar Sankaran Reviewed-by: Sean Paul Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 11 +++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 20 -------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 10 ---------- 3 files changed, 7 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 05edd8580a81..d39b745c3d27 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -627,6 +627,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->vbif[VBIF_RT]); dpu_kms->vbif[VBIF_RT] = NULL; + if (dpu_kms->hw_mdp) + dpu_hw_mdp_destroy(dpu_kms->hw_mdp); + dpu_kms->hw_mdp = NULL; + if (dpu_kms->mmio) devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->mmio); dpu_kms->mmio = NULL; @@ -885,11 +889,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->rm_init = true; - dpu_kms->hw_mdp = dpu_rm_get_mdp(&dpu_kms->rm); - if (IS_ERR_OR_NULL(dpu_kms->hw_mdp)) { + dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio, + dpu_kms->catalog); + if (IS_ERR(dpu_kms->hw_mdp)) { rc = PTR_ERR(dpu_kms->hw_mdp); - if (!dpu_kms->hw_mdp) - rc = -EINVAL; DPU_ERROR("failed to get hw_mdp: %d\n", rc); dpu_kms->hw_mdp = NULL; goto power_error; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index e7fc9a48c9e4..037d9f4187f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -49,11 +49,6 @@ struct dpu_rm_hw_blk { struct dpu_hw_blk *hw; }; -struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm) -{ - return rm->hw_mdp; -} - void dpu_rm_init_hw_iter( struct dpu_rm_hw_iter *iter, uint32_t enc_id, @@ -148,9 +143,6 @@ int dpu_rm_destroy(struct dpu_rm *rm) } } - dpu_hw_mdp_destroy(rm->hw_mdp); - rm->hw_mdp = NULL; - mutex_destroy(&rm->rm_lock); return 0; @@ -165,11 +157,8 @@ static int _dpu_rm_hw_blk_create( void *hw_catalog_info) { struct dpu_rm_hw_blk *blk; - struct dpu_hw_mdp *hw_mdp; void *hw; - hw_mdp = rm->hw_mdp; - switch (type) { case DPU_HW_BLK_LM: hw = dpu_hw_lm_init(id, mmio, cat); @@ -233,15 +222,6 @@ int dpu_rm_init(struct dpu_rm *rm, for (type = 0; type < DPU_HW_BLK_MAX; type++) INIT_LIST_HEAD(&rm->hw_blks[type]); - /* Some of the sub-blocks require an mdptop to be created */ - rm->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, mmio, cat); - if (IS_ERR_OR_NULL(rm->hw_mdp)) { - rc = PTR_ERR(rm->hw_mdp); - rm->hw_mdp = NULL; - DPU_ERROR("failed: mdp hw not available\n"); - goto fail; - } - /* Interrogate HW catalog and create tracking items for hw blocks */ for (i = 0; i < cat->mixer_count; i++) { struct dpu_lm_cfg *lm = &cat->mixer[i]; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index eb6a6ac6483b..381611fc5877 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -24,13 +24,11 @@ * struct dpu_rm - DPU dynamic hardware resource manager * @hw_blks: array of lists of hardware resources present in the system, one * list per type of hardware block - * @hw_mdp: hardware object for mdp_top * @lm_max_width: cached layer mixer maximum width * @rm_lock: resource manager mutex */ struct dpu_rm { struct list_head hw_blks[DPU_HW_BLK_MAX]; - struct dpu_hw_mdp *hw_mdp; uint32_t lm_max_width; struct mutex rm_lock; }; @@ -103,14 +101,6 @@ int dpu_rm_reserve(struct dpu_rm *rm, */ void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc); -/** - * dpu_rm_get_mdp - Retrieve HW block for MDP TOP. - * This is never reserved, and is usable by any display. - * @rm: DPU Resource Manager handle - * @Return: Pointer to hw block or NULL - */ -struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm); - /** * dpu_rm_init_hw_iter - setup given iterator for new iteration over hw list * using dpu_rm_get_hw -- cgit v1.2.3 From 070e64dc1bbc879b7e0e9fffccd9dd139baf89f0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 3 Jan 2019 11:06:02 -0800 Subject: drm/msm/dpu: Convert to a chained irq chip Devices that make up DPU, i.e. graphics card, request their interrupts from this "virtual" interrupt chip. The interrupt chip builds upon a GIC SPI interrupt that raises high when any of the interrupts in the DPU's irq status register are triggered. From the kernel's perspective this is a chained irq chip, so requesting a flow handler for the GIC SPI and then calling generic IRQ handling code from that irq handler is not completely proper. It's better to convert this to a chained irq so that the GIC SPI irq doesn't appear in /proc/interrupts, can't have CPU affinity changed, and won't be accounted for with irq stats. Doing this also silences a recursive lockdep warning because we can specify a different lock class for the chained interrupts, silencing a warning that is easy to see with 'threadirqs' on the kernel commandline. WARNING: inconsistent lock state 4.19.10 #76 Tainted: G W -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. irq/40-dpu_mdss/203 [HC0[0]:SC0[2]:HE1:SE0] takes: 0000000053ea9021 (&irq_desc_lock_class){?.-.}, at: handle_level_irq+0x34/0x26c {IN-HARDIRQ-W} state was registered at: lock_acquire+0x244/0x360 _raw_spin_lock+0x64/0xa0 handle_fasteoi_irq+0x54/0x2ec generic_handle_irq+0x44/0x5c __handle_domain_irq+0x9c/0x11c gic_handle_irq+0x208/0x260 el1_irq+0xb4/0x130 arch_cpu_idle+0x178/0x3cc default_idle_call+0x3c/0x54 do_idle+0x1a8/0x3dc cpu_startup_entry+0x24/0x28 rest_init+0x240/0x270 start_kernel+0x5a8/0x6bc irq event stamp: 18 hardirqs last enabled at (17): [] _raw_spin_unlock_irq+0x40/0xc0 hardirqs last disabled at (16): [] __schedule+0x20c/0x1bbc softirqs last enabled at (0): [] copy_process+0xb50/0x3964 softirqs last disabled at (18): [] local_bh_disable+0x8/0x20 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&irq_desc_lock_class); lock(&irq_desc_lock_class); *** DEADLOCK *** no locks held by irq/40-dpu_mdss/203. stack backtrace: CPU: 0 PID: 203 Comm: irq/40-dpu_mdss Tainted: G W 4.19.10 #76 Call trace: dump_backtrace+0x0/0x2f8 show_stack+0x20/0x2c __dump_stack+0x20/0x28 dump_stack+0xcc/0x10c mark_lock+0xbe0/0xe24 __lock_acquire+0x4cc/0x2708 lock_acquire+0x244/0x360 _raw_spin_lock+0x64/0xa0 handle_level_irq+0x34/0x26c generic_handle_irq+0x44/0x5c dpu_mdss_irq+0x64/0xec irq_forced_thread_fn+0x58/0x9c irq_thread+0x120/0x1dc kthread+0x248/0x260 ret_from_fork+0x10/0x18 ------------[ cut here ]------------ irq 169 handler irq_default_primary_handler+0x0/0x18 enabled interrupts Cc: Sean Paul Cc: Jordan Crouse Cc: Jayant Shekhar Cc: Rajesh Yadav Cc: Jeykumar Sankaran Signed-off-by: Stephen Boyd Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 36 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index cb307a2abf06..7316b4ab1b85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -23,11 +23,14 @@ struct dpu_mdss { struct dpu_irq_controller irq_controller; }; -static irqreturn_t dpu_mdss_irq(int irq, void *arg) +static void dpu_mdss_irq(struct irq_desc *desc) { - struct dpu_mdss *dpu_mdss = arg; + struct dpu_mdss *dpu_mdss = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); u32 interrupts; + chained_irq_enter(chip, desc); + interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS); while (interrupts) { @@ -39,20 +42,20 @@ static irqreturn_t dpu_mdss_irq(int irq, void *arg) hwirq); if (mapping == 0) { DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq); - return IRQ_NONE; + break; } rc = generic_handle_irq(mapping); if (rc < 0) { DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n", hwirq, mapping, rc); - return IRQ_NONE; + break; } interrupts &= ~(1 << hwirq); } - return IRQ_HANDLED; + chained_irq_exit(chip, desc); } static void dpu_mdss_irq_mask(struct irq_data *irqd) @@ -83,16 +86,16 @@ static struct irq_chip dpu_mdss_irq_chip = { .irq_unmask = dpu_mdss_irq_unmask, }; +static struct lock_class_key dpu_mdss_lock_key, dpu_mdss_request_key; + static int dpu_mdss_irqdomain_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq) { struct dpu_mdss *dpu_mdss = domain->host_data; - int ret; + irq_set_lockdep_class(irq, &dpu_mdss_lock_key, &dpu_mdss_request_key); irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq); - ret = irq_set_chip_data(irq, dpu_mdss); - - return ret; + return irq_set_chip_data(irq, dpu_mdss); } static const struct irq_domain_ops dpu_mdss_irqdomain_ops = { @@ -159,11 +162,13 @@ static void dpu_mdss_destroy(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); struct dss_module_power *mp = &dpu_mdss->mp; + int irq; pm_runtime_suspend(dev->dev); pm_runtime_disable(dev->dev); _dpu_mdss_irq_domain_fini(dpu_mdss); - free_irq(platform_get_irq(pdev, 0), dpu_mdss); + irq = platform_get_irq(pdev, 0); + irq_set_chained_handler_and_data(irq, NULL, NULL); msm_dss_put_clk(mp->clk_config, mp->num_clk); devm_kfree(&pdev->dev, mp->clk_config); @@ -187,6 +192,7 @@ int dpu_mdss_init(struct drm_device *dev) struct dpu_mdss *dpu_mdss; struct dss_module_power *mp; int ret = 0; + int irq; dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL); if (!dpu_mdss) @@ -219,12 +225,12 @@ int dpu_mdss_init(struct drm_device *dev) if (ret) goto irq_domain_error; - ret = request_irq(platform_get_irq(pdev, 0), - dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss); - if (ret) { - DPU_ERROR("failed to init irq: %d\n", ret); + irq = platform_get_irq(pdev, 0); + if (irq < 0) goto irq_error; - } + + irq_set_chained_handler_and_data(irq, dpu_mdss_irq, + dpu_mdss); pm_runtime_enable(dev->dev); -- cgit v1.2.3 From 9b9c8e7e829a7144b664f6dcbc26dc9af3818bfe Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Mon, 17 Dec 2018 14:35:03 -0800 Subject: drm/msm/dpu: fix documentation for intf_type Fix intf_type description in msm_disp_info to show that it represents drm encoder mode of the display. changes in v3: - introduced in the series changes in v4: - none Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/msm_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 927e5d86f7c1..197ed319a97b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -126,7 +126,7 @@ struct msm_display_topology { /** * struct msm_display_info - defines display properties - * @intf_type: DRM_MODE_CONNECTOR_ display type + * @intf_type: DRM_MODE_ENCODER_ type * @capabilities: Bitmask of display flags * @num_of_h_tiles: Number of horizontal tiles in case of split interface * @h_tile_instance: Controller instance used per tile. Number of elements is -- cgit v1.2.3 From a802ee99c448ca0496fa307f3e46b834ae2a46a3 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Mon, 17 Dec 2018 14:35:04 -0800 Subject: drm/msm/dpu: handle failures while initializing displays Bail out KMS hw init on display initialization failures with proper error logging. changes in v3: - introduced in the series changes in v4: - avoid duplicate return on errors (Sean Paul) - avoid spamming errors on failures (Jordon Crouse) Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index d39b745c3d27..885bf88afa3e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -405,35 +405,38 @@ static void dpu_kms_wait_for_commit_done(struct msm_kms *kms, } } -static void _dpu_kms_initialize_dsi(struct drm_device *dev, +static int _dpu_kms_initialize_dsi(struct drm_device *dev, struct msm_drm_private *priv, struct dpu_kms *dpu_kms) { struct drm_encoder *encoder = NULL; - int i, rc; + int i, rc = 0; + + if (!(priv->dsi[0] || priv->dsi[1])) + return rc; /*TODO: Support two independent DSI connectors */ encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI); - if (IS_ERR_OR_NULL(encoder)) { + if (IS_ERR(encoder)) { DPU_ERROR("encoder init failed for dsi display\n"); - return; + return PTR_ERR(encoder); } priv->encoders[priv->num_encoders++] = encoder; for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) { - if (!priv->dsi[i]) { - DPU_DEBUG("invalid msm_dsi for ctrl %d\n", i); - return; - } + if (!priv->dsi[i]) + continue; rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder); if (rc) { DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n", i, rc); - continue; + break; } } + + return rc; } /** @@ -444,16 +447,16 @@ static void _dpu_kms_initialize_dsi(struct drm_device *dev, * @dpu_kms: Pointer to dpu kms structure * Returns: Zero on success */ -static void _dpu_kms_setup_displays(struct drm_device *dev, +static int _dpu_kms_setup_displays(struct drm_device *dev, struct msm_drm_private *priv, struct dpu_kms *dpu_kms) { - _dpu_kms_initialize_dsi(dev, priv, dpu_kms); - /** * Extend this function to initialize other * types of displays */ + + return _dpu_kms_initialize_dsi(dev, priv, dpu_kms); } static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms) @@ -516,7 +519,9 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) * Create encoder and query display drivers to create * bridges and connectors */ - _dpu_kms_setup_displays(dev, priv, dpu_kms); + ret = _dpu_kms_setup_displays(dev, priv, dpu_kms); + if (ret) + goto fail; max_crtc_count = min(catalog->mixer_count, priv->num_encoders); -- cgit v1.2.3 From 0029f3b6a8f4d7aa8c775c5528aa46bf1ac31c1c Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Wed, 19 Dec 2018 00:23:53 +0530 Subject: drm/msm/dpu: Remove unused enum and comment from dpu mdss Remove enum dpu_iommu_domain from dpu mdss as its unused. Remove unnecessary comment for variable which is already removed. Signed-off-by: Jayant Shekhar Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 68c54d2c9677..1ab8d4a889f7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -258,12 +258,6 @@ enum dpu_vbif { VBIF_NRT = VBIF_1 }; -enum dpu_iommu_domain { - DPU_IOMMU_DOMAIN_UNSECURE, - DPU_IOMMU_DOMAIN_SECURE, - DPU_IOMMU_DOMAIN_MAX -}; - /** * DPU HW,Component order color map */ @@ -358,7 +352,6 @@ enum dpu_3d_blend_mode { * @alpha_enable: whether the format has an alpha channel * @num_planes: number of planes (including meta data planes) * @fetch_mode: linear, tiled, or ubwc hw fetch behavior - * @is_yuv: is format a yuv variant * @flag: usage bit flags * @tile_width: format tile width * @tile_height: format tile height -- cgit v1.2.3 From a004f603fa617025d85e91a41ccb65ebb0df5351 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Tue, 18 Dec 2018 18:50:38 +0530 Subject: drm/msm/dpu: Cleanup dpu plane interface Remove unused functions from dpu plane interface and unused variables from dpu plane state structure. Reviewed-by: Jordan Crouse Signed-off-by: Jayant Shekhar Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h index 7fed0b627708..0e6063acd041 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -28,23 +28,18 @@ /** * struct dpu_plane_state: Define dpu extension of drm plane state object * @base: base drm plane state object - * @property_state: Local storage for msm_prop properties - * @property_values: cached plane property values * @aspace: pointer to address space for input/output buffers - * @input_fence: dereferenced input fence pointer * @stage: assigned by crtc blender * @multirect_index: index of the rectangle of SSPP * @multirect_mode: parallel or time multiplex multirect mode * @pending: whether the current update is still pending * @scaler3_cfg: configuration data for scaler3 * @pixel_ext: configuration data for pixel extensions - * @scaler_check_state: indicates status of user provided pixel extension data * @cdp_cfg: CDP configuration */ struct dpu_plane_state { struct drm_plane_state base; struct msm_gem_address_space *aspace; - void *input_fence; enum dpu_stage stage; uint32_t multirect_index; uint32_t multirect_mode; @@ -106,12 +101,6 @@ void dpu_plane_restore(struct drm_plane *plane); */ void dpu_plane_flush(struct drm_plane *plane); -/** - * dpu_plane_kickoff - final plane operations before commit kickoff - * @plane: Pointer to drm plane structure - */ -void dpu_plane_kickoff(struct drm_plane *plane); - /** * dpu_plane_set_error: enable/disable error condition * @plane: pointer to drm_plane structure @@ -146,14 +135,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane); */ void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state); -/** - * dpu_plane_wait_input_fence - wait for input fence object - * @plane: Pointer to DRM plane object - * @wait_ms: Wait timeout value - * Returns: Zero on success - */ -int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms); - /** * dpu_plane_color_fill - enables color fill on plane * @plane: Pointer to DRM plane object @@ -164,12 +145,4 @@ int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms); int dpu_plane_color_fill(struct drm_plane *plane, uint32_t color, uint32_t alpha); -/** - * dpu_plane_set_revalidate - sets revalidate flag which forces a full - * validation of the plane properties in the next atomic check - * @plane: Pointer to DRM plane object - * @enable: Boolean to set/unset the flag - */ -void dpu_plane_set_revalidate(struct drm_plane *plane, bool enable); - #endif /* _DPU_PLANE_H_ */ -- cgit v1.2.3 From 5e1023d613c34f41d6fdda46819824b8150c03d3 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Tue, 18 Dec 2018 17:05:48 +0530 Subject: drm/msm/dpu: Clean up dpu hw interrupts Remove unused functions and macros from files handling dpu hardware interrupts. changes in v2: Removed clear_interrupt_status (Jordan Crouse) changes in v3: Changed commit text Signed-off-by: Jayant Shekhar Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 44 ----------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 44 ----------------------- 2 files changed, 88 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index c0b7f0049365..8a28a03ac6a9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -170,10 +170,6 @@ /** * AD4 interrupt status bit definitions */ -#define DPU_INTR_BRIGHTPR_UPDATED BIT(4) -#define DPU_INTR_DARKENH_UPDATED BIT(3) -#define DPU_INTR_STREN_OUTROI_UPDATED BIT(2) -#define DPU_INTR_STREN_INROI_UPDATED BIT(1) #define DPU_INTR_BACKLIGHT_UPDATED BIT(0) /** * struct dpu_intr_reg - array of DPU register sets @@ -782,18 +778,6 @@ static int dpu_hw_intr_irqidx_lookup(enum dpu_intr_type intr_type, return -EINVAL; } -static void dpu_hw_intr_set_mask(struct dpu_hw_intr *intr, uint32_t reg_off, - uint32_t mask) -{ - if (!intr) - return; - - DPU_REG_WRITE(&intr->hw, reg_off, mask); - - /* ensure register writes go through */ - wmb(); -} - static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr, void (*cbfunc)(void *, int), void *arg) @@ -1004,18 +988,6 @@ static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr) return 0; } -static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr, - uint32_t *mask) -{ - if (!intr || !mask) - return -EINVAL; - - *mask = IRQ_SOURCE_MDP | IRQ_SOURCE_DSI0 | IRQ_SOURCE_DSI1 - | IRQ_SOURCE_HDMI | IRQ_SOURCE_EDP; - - return 0; -} - static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr) { int i; @@ -1065,19 +1037,6 @@ static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr, wmb(); } -static void dpu_hw_intr_clear_interrupt_status(struct dpu_hw_intr *intr, - int irq_idx) -{ - unsigned long irq_flags; - - if (!intr) - return; - - spin_lock_irqsave(&intr->irq_lock, irq_flags); - dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx); - spin_unlock_irqrestore(&intr->irq_lock, irq_flags); -} - static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr, int irq_idx, bool clear) { @@ -1113,16 +1072,13 @@ static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr, static void __setup_intr_ops(struct dpu_hw_intr_ops *ops) { - ops->set_mask = dpu_hw_intr_set_mask; ops->irq_idx_lookup = dpu_hw_intr_irqidx_lookup; ops->enable_irq = dpu_hw_intr_enable_irq; ops->disable_irq = dpu_hw_intr_disable_irq; ops->dispatch_irqs = dpu_hw_intr_dispatch_irq; ops->clear_all_irqs = dpu_hw_intr_clear_irqs; ops->disable_all_irqs = dpu_hw_intr_disable_irqs; - ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts; ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses; - ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status; ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock; ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index 61e4cba36562..4d7a1c727ce2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -20,13 +20,6 @@ #include "dpu_hw_util.h" #include "dpu_hw_mdss.h" -#define IRQ_SOURCE_MDP BIT(0) -#define IRQ_SOURCE_DSI0 BIT(4) -#define IRQ_SOURCE_DSI1 BIT(5) -#define IRQ_SOURCE_HDMI BIT(8) -#define IRQ_SOURCE_EDP BIT(12) -#define IRQ_SOURCE_MHL BIT(16) - /** * dpu_intr_type - HW Interrupt Type * @DPU_IRQ_TYPE_WB_ROT_COMP: WB rotator done @@ -95,18 +88,6 @@ struct dpu_hw_intr; * Interrupt operations. */ struct dpu_hw_intr_ops { - /** - * set_mask - Programs the given interrupt register with the - * given interrupt mask. Register value will get overwritten. - * @intr: HW interrupt handle - * @reg_off: MDSS HW register offset - * @irqmask: IRQ mask value - */ - void (*set_mask)( - struct dpu_hw_intr *intr, - uint32_t reg, - uint32_t irqmask); - /** * irq_idx_lookup - Lookup IRQ index on the HW interrupt type * Used for all irq related ops @@ -176,16 +157,6 @@ struct dpu_hw_intr_ops { void (*get_interrupt_statuses)( struct dpu_hw_intr *intr); - /** - * clear_interrupt_status - Clears HW interrupt status based on given - * lookup IRQ index. - * @intr: HW interrupt handle - * @irq_idx: Lookup irq index return from irq_idx_lookup - */ - void (*clear_interrupt_status)( - struct dpu_hw_intr *intr, - int irq_idx); - /** * clear_intr_status_nolock() - clears the HW interrupts without lock * @intr: HW interrupt handle @@ -206,21 +177,6 @@ struct dpu_hw_intr_ops { struct dpu_hw_intr *intr, int irq_idx, bool clear); - - /** - * get_valid_interrupts - Gets a mask of all valid interrupt sources - * within DPU. These are actually status bits - * within interrupt registers that specify the - * source of the interrupt in IRQs. For example, - * valid interrupt sources can be MDP, DSI, - * HDMI etc. - * @intr: HW interrupt handle - * @mask: Returning the interrupt source MASK - * @return: 0 for success, otherwise failure - */ - int (*get_valid_interrupts)( - struct dpu_hw_intr *intr, - uint32_t *mask); }; /** -- cgit v1.2.3 From 7f0bf1c09f3c8763a9807f66dcf4c7adad0ce7ff Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Mon, 17 Dec 2018 15:34:09 -0800 Subject: drm/msm/dpu: Change definition of RGB565 and BGR565 Correct definition of both formats by swapping red and blue channels v3: update commit message Signed-off-by: Tanmay Shah Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c index d53abc8ce670..f59fe1a9f4b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c @@ -263,13 +263,13 @@ static const struct dpu_format dpu_format_map[] = { INTERLEAVED_RGB_FMT(RGB565, 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3, + C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3, false, 2, 0, DPU_FETCH_LINEAR, 1), INTERLEAVED_RGB_FMT(BGR565, 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, - C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3, + C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3, false, 2, 0, DPU_FETCH_LINEAR, 1), -- cgit v1.2.3 From 3c12568271e294825df2f5377e1993a4a26a8bc0 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 14 Dec 2018 15:57:51 -0800 Subject: drm/msm/dpu: use kthread_destroy_worker to release msm workers use kthread_destroy_worker to destroy workers and release their associated kthreads. changes in v3: - introduced in the series changes in v4: - none changes in v5: - none Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/msm_drv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index d2cdc7b553fe..5f859653442d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -291,14 +291,12 @@ static int msm_drm_uninit(struct device *dev) /* clean up display commit/event worker threads */ for (i = 0; i < priv->num_crtcs; i++) { if (priv->disp_thread[i].thread) { - kthread_flush_worker(&priv->disp_thread[i].worker); - kthread_stop(priv->disp_thread[i].thread); + kthread_destroy_worker(&priv->disp_thread[i].worker); priv->disp_thread[i].thread = NULL; } if (priv->event_thread[i].thread) { - kthread_flush_worker(&priv->event_thread[i].worker); - kthread_stop(priv->event_thread[i].thread); + kthread_destroy_worker(&priv->event_thread[i].worker); priv->event_thread[i].thread = NULL; } } -- cgit v1.2.3 From 5aeb66563fe22e7ce2e7b403b531630865a87446 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 14 Dec 2018 15:57:52 -0800 Subject: drm/msm/dpu: use msm wq for vblank events DPU was using one thread per display to dispatch async commits and vblank requests. Since clean up already happened in msm to use the common thread for all the display commits, display threads are only used to cater vblank requests. Since a single thread is sufficient to do the job without any performance hits, use msm workqueue to queue requests. A separate patch is submitted later in this series to remove the display threads altogether. changes in v2: - switch to system wq before removing disp threads (Sean Paul) changes in v3: - none changes in v4: - use msm wq for vblank events changes in v5: - none Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/msm_drv.c | 9 ++++----- drivers/gpu/drm/msm/msm_drv.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 5f859653442d..6c311f92c11d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -213,7 +213,7 @@ struct vblank_event { bool enable; }; -static void vblank_ctrl_worker(struct kthread_work *work) +static void vblank_ctrl_worker(struct work_struct *work) { struct msm_vblank_ctrl *vbl_ctrl = container_of(work, struct msm_vblank_ctrl, work); @@ -261,8 +261,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list); spin_unlock_irqrestore(&vbl_ctrl->lock, flags); - kthread_queue_work(&priv->disp_thread[crtc_id].worker, - &vbl_ctrl->work); + queue_work(priv->wq, &vbl_ctrl->work); return 0; } @@ -282,7 +281,7 @@ static int msm_drm_uninit(struct device *dev) * work before drm_irq_uninstall() to avoid work re-enabling an * irq after uninstall has disabled it. */ - kthread_flush_work(&vbl_ctrl->work); + flush_work(&vbl_ctrl->work); list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { list_del(&vbl_ev->node); kfree(vbl_ev); @@ -489,7 +488,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) INIT_LIST_HEAD(&priv->inactive_list); INIT_LIST_HEAD(&priv->vblank_ctrl.event_list); - kthread_init_work(&priv->vblank_ctrl.work, vblank_ctrl_worker); + INIT_WORK(&priv->vblank_ctrl.work, vblank_ctrl_worker); spin_lock_init(&priv->vblank_ctrl.lock); drm_mode_config_init(ddev); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 197ed319a97b..e2689c2e580e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -78,7 +78,7 @@ enum msm_mdp_plane_property { }; struct msm_vblank_ctrl { - struct kthread_work work; + struct work_struct work; struct list_head event_list; spinlock_t lock; }; -- cgit v1.2.3 From e077fe752cd344ab11bf0e47743f369d73905f82 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 14 Dec 2018 15:57:53 -0800 Subject: drm/msm/dpu: use msm wq for idle power collapse msm is using msm wq for dispatching commit and vblank events. Switch idle power collapse feature also to use msm wq to handle delayed work handlers so that msm can get rid of redundant display threads. changes in v2: - patch introduced in v2 changes in v3: - none changes in v4: - use msm wq for delayed works changes in v5: - none Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 36158b7d99cd..3d1e1e4cdac5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -205,7 +205,7 @@ struct dpu_encoder_virt { bool idle_pc_supported; struct mutex rc_lock; enum dpu_enc_rc_states rc_state; - struct kthread_delayed_work delayed_off_work; + struct delayed_work delayed_off_work; struct kthread_work vsync_event_work; struct msm_display_topology topology; bool mode_set_complete; @@ -742,7 +742,6 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, { struct dpu_encoder_virt *dpu_enc; struct msm_drm_private *priv; - struct msm_drm_thread *disp_thread; bool is_vid_mode = false; if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private || @@ -755,12 +754,6 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, is_vid_mode = dpu_enc->disp_info.capabilities & MSM_DISPLAY_CAP_VID_MODE; - if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) { - DPU_ERROR("invalid crtc index\n"); - return -EINVAL; - } - disp_thread = &priv->disp_thread[drm_enc->crtc->index]; - /* * when idle_pc is not supported, process only KICKOFF, STOP and MODESET * events and return early for other events (ie wb display). @@ -777,8 +770,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, switch (sw_event) { case DPU_ENC_RC_EVENT_KICKOFF: /* cancel delayed off work, if any */ - if (kthread_cancel_delayed_work_sync( - &dpu_enc->delayed_off_work)) + if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work)) DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n", sw_event); @@ -837,10 +829,8 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, return 0; } - kthread_queue_delayed_work( - &disp_thread->worker, - &dpu_enc->delayed_off_work, - msecs_to_jiffies(dpu_enc->idle_timeout)); + queue_delayed_work(priv->wq, &dpu_enc->delayed_off_work, + msecs_to_jiffies(dpu_enc->idle_timeout)); trace_dpu_enc_rc(DRMID(drm_enc), sw_event, dpu_enc->idle_pc_supported, dpu_enc->rc_state, @@ -849,8 +839,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, case DPU_ENC_RC_EVENT_PRE_STOP: /* cancel delayed off work, if any */ - if (kthread_cancel_delayed_work_sync( - &dpu_enc->delayed_off_work)) + if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work)) DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n", sw_event); @@ -1368,7 +1357,7 @@ static void dpu_encoder_frame_done_callback( } } -static void dpu_encoder_off_work(struct kthread_work *work) +static void dpu_encoder_off_work(struct work_struct *work) { struct dpu_encoder_virt *dpu_enc = container_of(work, struct dpu_encoder_virt, delayed_off_work.work); @@ -2193,7 +2182,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, mutex_init(&dpu_enc->rc_lock); - kthread_init_delayed_work(&dpu_enc->delayed_off_work, + INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, dpu_encoder_off_work); dpu_enc->idle_timeout = IDLE_TIMEOUT; -- cgit v1.2.3 From d9db30ce7d04515d5d09a2517f5559c6f2f03c52 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 14 Dec 2018 15:57:54 -0800 Subject: drm/msm: clean up display thread Since there are no clients using these threads, cleaning it up. changes in v2: - switch all the dependent clients to use system wq before removing the disp_threads (Sean Paul) changes in v3: - none changes in v4: - none changes in v5: - Rebase on latest tip with [1] (Sean Paul) [1] https://patchwork.freedesktop.org/patch/255105/ Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/msm_drv.c | 35 +---------------------------------- drivers/gpu/drm/msm/msm_drv.h | 1 - 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 6c311f92c11d..a8a0b246e3a9 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -287,13 +287,8 @@ static int msm_drm_uninit(struct device *dev) kfree(vbl_ev); } - /* clean up display commit/event worker threads */ + /* clean up event worker threads */ for (i = 0; i < priv->num_crtcs; i++) { - if (priv->disp_thread[i].thread) { - kthread_destroy_worker(&priv->disp_thread[i].worker); - priv->disp_thread[i].thread = NULL; - } - if (priv->event_thread[i].thread) { kthread_destroy_worker(&priv->event_thread[i].worker); priv->event_thread[i].thread = NULL; @@ -551,27 +546,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) */ param.sched_priority = 16; for (i = 0; i < priv->num_crtcs; i++) { - - /* initialize display thread */ - priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id; - kthread_init_worker(&priv->disp_thread[i].worker); - priv->disp_thread[i].dev = ddev; - priv->disp_thread[i].thread = - kthread_run(kthread_worker_fn, - &priv->disp_thread[i].worker, - "crtc_commit:%d", priv->disp_thread[i].crtc_id); - if (IS_ERR(priv->disp_thread[i].thread)) { - DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n"); - priv->disp_thread[i].thread = NULL; - goto err_msm_uninit; - } - - ret = sched_setscheduler(priv->disp_thread[i].thread, - SCHED_FIFO, ¶m); - if (ret) - dev_warn(dev, "disp_thread set priority failed: %d\n", - ret); - /* initialize event thread */ priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id; kthread_init_worker(&priv->event_thread[i].worker); @@ -586,13 +560,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) goto err_msm_uninit; } - /** - * event thread should also run at same priority as disp_thread - * because it is handling frame_done events. A lower priority - * event thread and higher priority disp_thread can causes - * frame_pending counters beyond 2. This can lead to commit - * failure at crtc commit level. - */ ret = sched_setscheduler(priv->event_thread[i].thread, SCHED_FIFO, ¶m); if (ret) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index e2689c2e580e..06f3aa876483 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -199,7 +199,6 @@ struct msm_drm_private { unsigned int num_crtcs; struct drm_crtc *crtcs[MAX_CRTCS]; - struct msm_drm_thread disp_thread[MAX_CRTCS]; struct msm_drm_thread event_thread[MAX_CRTCS]; unsigned int num_encoders; -- cgit v1.2.3 From 48d1d28eec5cd7ebb8bb30009078feb438172cf2 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 14 Dec 2018 15:57:55 -0800 Subject: drm/msm: subclass work object for vblank events msm maintains a separate structure to define vblank work definitions and a list to track events submitted to the workqueue. We can avoid this redundant list and its protection mechanism, if we subclass the work object to encapsulate vblank event parameters. changes in v2: - subclass optimization on system wq (Sean Paul) changes in v3: - none changes in v4: - move flush_workqueue before irq uninstall changes in v5: - none Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/msm_drv.c | 71 ++++++++++++++----------------------------- drivers/gpu/drm/msm/msm_drv.h | 7 ----- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index a8a0b246e3a9..5e7b5fa01401 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -207,61 +207,44 @@ u32 msm_readl(const void __iomem *addr) return val; } -struct vblank_event { - struct list_head node; +struct msm_vblank_work { + struct work_struct work; int crtc_id; bool enable; + struct msm_drm_private *priv; }; static void vblank_ctrl_worker(struct work_struct *work) { - struct msm_vblank_ctrl *vbl_ctrl = container_of(work, - struct msm_vblank_ctrl, work); - struct msm_drm_private *priv = container_of(vbl_ctrl, - struct msm_drm_private, vblank_ctrl); + struct msm_vblank_work *vbl_work = container_of(work, + struct msm_vblank_work, work); + struct msm_drm_private *priv = vbl_work->priv; struct msm_kms *kms = priv->kms; - struct vblank_event *vbl_ev, *tmp; - unsigned long flags; - - spin_lock_irqsave(&vbl_ctrl->lock, flags); - list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { - list_del(&vbl_ev->node); - spin_unlock_irqrestore(&vbl_ctrl->lock, flags); - - if (vbl_ev->enable) - kms->funcs->enable_vblank(kms, - priv->crtcs[vbl_ev->crtc_id]); - else - kms->funcs->disable_vblank(kms, - priv->crtcs[vbl_ev->crtc_id]); - - kfree(vbl_ev); - spin_lock_irqsave(&vbl_ctrl->lock, flags); - } + if (vbl_work->enable) + kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]); + else + kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]); - spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + kfree(vbl_work); } static int vblank_ctrl_queue_work(struct msm_drm_private *priv, int crtc_id, bool enable) { - struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; - struct vblank_event *vbl_ev; - unsigned long flags; + struct msm_vblank_work *vbl_work; - vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC); - if (!vbl_ev) + vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC); + if (!vbl_work) return -ENOMEM; - vbl_ev->crtc_id = crtc_id; - vbl_ev->enable = enable; + INIT_WORK(&vbl_work->work, vblank_ctrl_worker); - spin_lock_irqsave(&vbl_ctrl->lock, flags); - list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list); - spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + vbl_work->crtc_id = crtc_id; + vbl_work->enable = enable; + vbl_work->priv = priv; - queue_work(priv->wq, &vbl_ctrl->work); + queue_work(priv->wq, &vbl_work->work); return 0; } @@ -273,19 +256,15 @@ static int msm_drm_uninit(struct device *dev) struct msm_drm_private *priv = ddev->dev_private; struct msm_kms *kms = priv->kms; struct msm_mdss *mdss = priv->mdss; - struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; - struct vblank_event *vbl_ev, *tmp; int i; /* We must cancel and cleanup any pending vblank enable/disable * work before drm_irq_uninstall() to avoid work re-enabling an * irq after uninstall has disabled it. */ - flush_work(&vbl_ctrl->work); - list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { - list_del(&vbl_ev->node); - kfree(vbl_ev); - } + + flush_workqueue(priv->wq); + destroy_workqueue(priv->wq); /* clean up event worker threads */ for (i = 0; i < priv->num_crtcs; i++) { @@ -315,9 +294,6 @@ static int msm_drm_uninit(struct device *dev) drm_irq_uninstall(ddev); pm_runtime_put_sync(dev); - flush_workqueue(priv->wq); - destroy_workqueue(priv->wq); - if (kms && kms->funcs) kms->funcs->destroy(kms); @@ -482,9 +458,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) priv->wq = alloc_ordered_workqueue("msm", 0); INIT_LIST_HEAD(&priv->inactive_list); - INIT_LIST_HEAD(&priv->vblank_ctrl.event_list); - INIT_WORK(&priv->vblank_ctrl.work, vblank_ctrl_worker); - spin_lock_init(&priv->vblank_ctrl.lock); drm_mode_config_init(ddev); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 06f3aa876483..cb642fefbd2f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -77,12 +77,6 @@ enum msm_mdp_plane_property { PLANE_PROP_MAX_NUM }; -struct msm_vblank_ctrl { - struct work_struct work; - struct list_head event_list; - spinlock_t lock; -}; - #define MSM_GPU_MAX_RINGS 4 #define MAX_H_TILES_PER_DISPLAY 2 @@ -227,7 +221,6 @@ struct msm_drm_private { struct notifier_block vmap_notifier; struct shrinker shrinker; - struct msm_vblank_ctrl vblank_ctrl; struct drm_atomic_state *pm_state; }; -- cgit v1.2.3 From 45815d0962e90ee5dbefff9a88c195a769ace21b Mon Sep 17 00:00:00 2001 From: Chandan Uddaraju Date: Mon, 28 Jan 2019 14:58:53 -0800 Subject: drm: add definitions for DP Audio/Video compliance tests This change adds definitions needed for DP audio compliance testing. It also adds missing definition for DP video compliance. Changes in V2: -- Delete cover letter for this patch. -- Move the description from cover letter into patch commit message. -- Remove DPU from subject prefix Reviewed-by: Sean Paul Acked-by: Daniel Vetter # for merging through -msm. Signed-off-by: Chandan Uddaraju Signed-off-by: Sean Paul --- include/drm/drm_dp_helper.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index c223c87ef119..af181c9c8f54 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -560,6 +560,8 @@ # define DP_TEST_LINK_EDID_READ (1 << 2) # define DP_TEST_LINK_PHY_TEST_PATTERN (1 << 3) /* DPCD >= 1.1 */ # define DP_TEST_LINK_FAUX_PATTERN (1 << 4) /* DPCD >= 1.2 */ +# define DP_TEST_LINK_AUDIO_PATTERN (1 << 5) /* DPCD >= 1.2 */ +# define DP_TEST_LINK_AUDIO_DISABLED_VIDEO (1 << 6) /* DPCD >= 1.2 */ #define DP_TEST_LINK_RATE 0x219 # define DP_LINK_RATE_162 (0x6) @@ -608,6 +610,7 @@ # define DP_COLOR_FORMAT_RGB (0 << 1) # define DP_COLOR_FORMAT_YCbCr422 (1 << 1) # define DP_COLOR_FORMAT_YCbCr444 (2 << 1) +# define DP_TEST_DYNAMIC_RANGE_VESA (0 << 3) # define DP_TEST_DYNAMIC_RANGE_CEA (1 << 3) # define DP_TEST_YCBCR_COEFFICIENTS (1 << 4) # define DP_YCBCR_COEFFICIENTS_ITU601 (0 << 4) @@ -657,6 +660,16 @@ #define DP_TEST_SINK 0x270 # define DP_TEST_SINK_START (1 << 0) +#define DP_TEST_AUDIO_MODE 0x271 +#define DP_TEST_AUDIO_PATTERN_TYPE 0x272 +#define DP_TEST_AUDIO_PERIOD_CH1 0x273 +#define DP_TEST_AUDIO_PERIOD_CH2 0x274 +#define DP_TEST_AUDIO_PERIOD_CH3 0x275 +#define DP_TEST_AUDIO_PERIOD_CH4 0x276 +#define DP_TEST_AUDIO_PERIOD_CH5 0x277 +#define DP_TEST_AUDIO_PERIOD_CH6 0x278 +#define DP_TEST_AUDIO_PERIOD_CH7 0x279 +#define DP_TEST_AUDIO_PERIOD_CH8 0x27A #define DP_FEC_STATUS 0x280 /* 1.4 */ # define DP_FEC_DECODE_EN_DETECTED (1 << 0) -- cgit v1.2.3 From d3db61caf45add8ab84152fda6aaa0534cf331a5 Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Mon, 28 Jan 2019 11:53:28 -0500 Subject: drm/msm/dpu: remove struct encoder_kickoff_params The contents of struct encoder_kickoff_params are never used. Remove the structure and all remnants of it from function calls. Changes in v2 (seanpaul): - Actually remove the struct (Jeykumar) Cc: Jeykumar Sankaran Signed-off-by: Bruce Wang Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 ++----- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 13 +------------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 5 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 5 ++--- 6 files changed, 11 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index d6e692598b52..4b599b78c661 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -716,11 +716,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) * may delay and flush at an irq event (e.g. ppdone) */ drm_for_each_encoder_mask(encoder, crtc->dev, - crtc->state->encoder_mask) { - struct dpu_encoder_kickoff_params params = { 0 }; - dpu_encoder_prepare_for_kickoff(encoder, ¶ms, async); - } - + crtc->state->encoder_mask) + dpu_encoder_prepare_for_kickoff(encoder, async); if (!async) { /* wait for frame_event_done completion */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3d1e1e4cdac5..11a5f2840471 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1745,15 +1745,14 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) nsecs_to_jiffies(ktime_to_ns(wakeup_time))); } -void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, - struct dpu_encoder_kickoff_params *params, bool async) +void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, bool async) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; bool needs_hw_reset = false; unsigned int i; - if (!drm_enc || !params) { + if (!drm_enc) { DPU_ERROR("invalid args\n"); return; } @@ -1767,7 +1766,7 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, phys = dpu_enc->phys_encs[i]; if (phys) { if (phys->ops.prepare_for_kickoff) - phys->ops.prepare_for_kickoff(phys, params); + phys->ops.prepare_for_kickoff(phys); if (phys->enable_state == DPU_ENC_ERR_NEEDS_HW_RESET) needs_hw_reset = true; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 3f5dafe00580..d77f74fb26d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -37,15 +37,6 @@ struct dpu_encoder_hw_resources { enum dpu_intf_mode intfs[INTF_MAX]; }; -/** - * dpu_encoder_kickoff_params - info encoder requires at kickoff - * @affected_displays: bitmask, bit set means the ROI of the commit lies within - * the bounds of the physical display at the bit index - */ -struct dpu_encoder_kickoff_params { - unsigned long affected_displays; -}; - /** * dpu_encoder_get_hw_resources - Populate table of required hardware resources * @encoder: encoder pointer @@ -88,11 +79,9 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *encoder, * Immediately: if no previous commit is outstanding. * Delayed: Block until next trigger can be issued. * @encoder: encoder pointer - * @params: kickoff time parameters * @async: true if this is an asynchronous commit */ -void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder, - struct dpu_encoder_kickoff_params *params, bool async); +void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder, bool async); /** * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous 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 44e6f8b68e70..db94f3d3bea3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -144,8 +144,7 @@ struct dpu_encoder_phys_ops { int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc); - void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_kickoff_params *params); + void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc); void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); void (*trigger_start)(struct dpu_encoder_phys *phys_enc); bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc); 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 99ab5ca9bed3..a399e1edd313 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 @@ -594,8 +594,7 @@ static void dpu_encoder_phys_cmd_get_hw_resources( } static void dpu_encoder_phys_cmd_prepare_for_kickoff( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_kickoff_params *params) + struct dpu_encoder_phys *phys_enc) { struct dpu_encoder_phys_cmd *cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); @@ -693,7 +692,7 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done( /* required for both controllers */ if (!rc && cmd_enc->serialize_wait4pp) - dpu_encoder_phys_cmd_prepare_for_kickoff(phys_enc, NULL); + dpu_encoder_phys_cmd_prepare_for_kickoff(phys_enc); return rc; } 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 acdab5b0db18..3c4eb470a82c 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 @@ -587,14 +587,13 @@ static int dpu_encoder_phys_vid_wait_for_vblank( } static void dpu_encoder_phys_vid_prepare_for_kickoff( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_kickoff_params *params) + struct dpu_encoder_phys *phys_enc) { struct dpu_encoder_phys_vid *vid_enc; struct dpu_hw_ctl *ctl; int rc; - if (!phys_enc || !params) { + if (!phys_enc) { DPU_ERROR("invalid encoder/parameters\n"); return; } -- cgit v1.2.3 From b6bd458c16ac2a7122fc4bc62bbdc66c9310ded7 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 13 Feb 2019 09:58:29 -0500 Subject: MAINTAINERS: update entry for drm/msm We've moved the tree to a shared gitlab tree, so that Sean can help out with maintainer duties. Cc: Sean Paul Acked-by: Sean Paul Signed-off-by: Rob Clark --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6e1cef2f21d9..6d5879ef4202 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4830,10 +4830,11 @@ F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt DRM DRIVER FOR MSM ADRENO GPU M: Rob Clark +M: Sean Paul L: linux-arm-msm@vger.kernel.org L: dri-devel@lists.freedesktop.org L: freedreno@lists.freedesktop.org -T: git git://people.freedesktop.org/~robclark/linux +T: git https://gitlab.freedesktop.org/drm/msm.git S: Maintained F: drivers/gpu/drm/msm/ F: include/uapi/drm/msm_drm.h -- cgit v1.2.3 From 7cce8e4efe5e782e130f79f8d55fdad48f2db52d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Feb 2019 10:19:27 +0300 Subject: drm/msm: fix an error code in the ioctl The copy_to/from_user() functions return the number of bytes remaining to be copied but we should return -EFAULT to the user. Fixes: f05c83e77460 ("drm/msm: add uapi to get/set debug name") Signed-off-by: Dan Carpenter Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 5e7b5fa01401..87eae44a1006 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -851,8 +851,9 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, ret = -EINVAL; break; } - ret = copy_from_user(msm_obj->name, - u64_to_user_ptr(args->value), args->len); + if (copy_from_user(msm_obj->name, u64_to_user_ptr(args->value), + args->len)) + ret = -EFAULT; msm_obj->name[args->len] = '\0'; for (i = 0; i < args->len; i++) { if (!isprint(msm_obj->name[i])) { @@ -868,8 +869,9 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, } args->len = strlen(msm_obj->name); if (args->value) { - ret = copy_to_user(u64_to_user_ptr(args->value), - msm_obj->name, args->len); + if (copy_to_user(u64_to_user_ptr(args->value), + msm_obj->name, args->len)) + ret = -EFAULT; } break; } -- cgit v1.2.3 From 860433ed2a55dcd18f36c61b3c4fdb12dc76c869 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 19 Feb 2019 11:40:19 -0700 Subject: drm/msm: Truncate the buffer object name if the copy from user failed (Resend since there was a compile error that I forgot to commit before sending) If there is a error while doing a copy_from_user() for MSM_INFO_SET_NAME make sure to truncate the object name so that there isn't a chance that we'll have random data in the string. This is on top of [1] reported and fixed by Dan Carpenter. [1] https://patchwork.freedesktop.org/series/56656/ Fixes: f05c83e77460 ("drm/msm: add uapi to get/set debug name") Reported-by: Dan Carpenter Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 87eae44a1006..906b2bb79f6a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -852,8 +852,11 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, break; } if (copy_from_user(msm_obj->name, u64_to_user_ptr(args->value), - args->len)) + args->len)) { + msm_obj->name[0] = '\0'; ret = -EFAULT; + break; + } msm_obj->name[args->len] = '\0'; for (i = 0; i < args->len; i++) { if (!isprint(msm_obj->name[i])) { -- cgit v1.2.3