aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/xlnx/zynqmp_disp.c
AgeCommit message (Collapse)Author
2024-05-08drm: xlnx: zynqmp_dpsub: Fix compilation errorAnatoliy Klymenko
Fix W=1 clang 19 compilation error in zynqmp_disp_layer_drm_formats(). Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202404260946.4oZXvHD2-lkp@intel.com/ Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Fixes: b0f0469ab662 ("drm: xlnx: zynqmp_dpsub: Anounce supported input formats") Link: https://patchwork.freedesktop.org/patch/msgid/20240426-dp-live-fmt-fix-v3-2-e904b5ae51d7@amd.com (cherry picked from commit c72211751870ffa2cff5d91834059456cfa7cbd5) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
2024-05-08drm: xlnx: zynqmp_dpsub: Fix few function commentsAnatoliy Klymenko
Fix arguments description for zynqmp_disp_layer_find_live_format() and zynqmp_disp_layer_set_live_format(). Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202404260616.KFGDpCDN-lkp@intel.com/ Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Fixes: 1b5151bd3a2e ("drm: xlnx: zynqmp_dpsub: Set input live format") Link: https://patchwork.freedesktop.org/patch/msgid/20240426-dp-live-fmt-fix-v3-1-e904b5ae51d7@amd.com (cherry picked from commit 87f36e03c0f1d69245ad295309418e982c88fbe7) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
2024-04-24drm: xlnx: zynqmp_dpsub: Set input live formatAnatoliy Klymenko
Program live video input format according to selected media bus format. In the bridge mode of operation, DPSUB is connected to FPGA CRTC which almost certainly supports a single media bus format as its output. Expect this to be delivered via the new bridge atomic state. Program DPSUB registers accordingly. Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240416-dp-live-fmt-v4-6-c7f379b7168e@amd.com
2024-04-24drm: xlnx: zynqmp_dpsub: Minimize usage of global flagAnatoliy Klymenko
Avoid usage of global zynqmp_dpsub.dma_enabled flag in DPSUB layer context. This flag signals whether the driver runs in DRM CRTC or DRM bridge mode, assuming that all display layers share the same live or non-live mode of operation. Using per-layer mode instead of global flag will simplify future support of the hybrid scenario. Remove redundant checks in DMA request/release contexts as zynqmp_disp_layer.info is well-defined for all layer types, including the correct number of DMA channels required for each particular layer. Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Reviewed-by: Tomi Valkeinen <tomi.valkainen@ideasonboard.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240416-dp-live-fmt-v4-5-c7f379b7168e@amd.com
2024-04-24drm: xlnx: zynqmp_dpsub: Anounce supported input formatsAnatoliy Klymenko
DPSUB in bridge mode supports multiple input media bus formats. Announce the list of supported input media bus formats via drm_bridge.atomic_get_input_bus_fmts callback. Introduce a set of live input formats supported by DPSUB. Add safeguards to format list functions to prevent their misuse in the different layer modes contexts. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240416-dp-live-fmt-v4-4-c7f379b7168e@amd.com
2024-04-24drm: xlnx: zynqmp_dpsub: Set layer mode during creationAnatoliy Klymenko
Set layer mode of operation (live or dma-based) during layer creation. Each DPSUB layer mode of operation is defined by corresponding DT node port connection, so it is possible to assign it during layer object creation. Previously it was set in layer enable functions, although it is too late as setting layer format depends on layer mode, and should be done before given layer enabled. Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Tomi Valkeinen <tomi.valkainen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240416-dp-live-fmt-v4-1-c7f379b7168e@amd.com
2024-02-07drm: xlnx: zynqmp_dpsub: Fix timing for live modeAnatoliy Klymenko
Expect external video timing in live video input mode, program DPSUB acordingly. Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240124025402.373620-3-anatoliy.klymenko@amd.com
2023-08-02drm: xlnx: zynqmp_dpsub: Use devm_platform_ioremap_resource_byname()Li Zetao
Convert platform_get_resource_byname() + devm_ioremap_resource() to a single call to devm_platform_ioremap_resource_byname(), as this is exactly what this function does. Signed-off-by: Li Zetao <lizetao1@huawei.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-08-02drm: xlnx: zynqmp_dpsub: Use dev_err_probe instead of dev_errWang Ming
It is possible that dma_request_chan() returns EPROBE_DEFER, in which case the driver defers probing without printing any message. Use dev_err_probe() to record the probe deferral cause and ease debugging. Signed-off-by: Wang Ming <machel@vivo.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Support operation without DMA engineLaurent Pinchart
To prepare for usage of the DPSUB as a DisplayPort bridge without creating a DRM device, make initialization and usage of the DMA engine optional. The flag that controls this feature is currently hardcoded to operating with the DMA engine, this will be made dynamic based on the device tree configuration in a subsequent change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Allow configuration of layer modeLaurent Pinchart
Add a mode parameter to the zynqmp_disp_layer_enable() to set the layer mode, to prepare for live mode support. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Manage DP and DISP allocations manuallyLaurent Pinchart
The zynqmp_disp and zynqmp_dp structures are allocated with drmm_kzalloc(). While this simplifies management of memory, it requires a DRM device, which will not be available at probe time when the DP bridge will be used standalone, with a DRM device in the PL. To prepare for this, switch to manual allocation for zynqmp_disp and zynqmp_dp. The cleanup still uses the DRM managed infrastructure, but one level up, at the top level. This will be addressed separately. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move planes handling to zynqmp_kms.cLaurent Pinchart
Decouple the planes handling from the display controller programming by moving the corresponding code from zynqmp_disp.c to zynqmp_kms.c. This prepares for using the DPSUB with a live video input, without creating DRM planes in the DPSUB driver. While at it, fix a typo in a comment. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move CRTC handling to zynqmp_kms.cLaurent Pinchart
Decouple the CRTC handling from the display controller programming by moving the corresponding code from zynqmp_disp.c to zynqmp_kms.c. This prepares for using the DPSUB with a live video input, without creating a DRM CRTC in the DPSUB driver. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move planes to zynqmp_dpsub structureLaurent Pinchart
Decouple the zynqmp_disp, which handles the hardware configuration, from the DRM planes by moving the planes to the zynqmp_dpsub structure. The planes handling code will be moved to a separate file in a subsequent step. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move CRTC to zynqmp_dpsub structureLaurent Pinchart
Decouple the zynqmp_disp, which handles the hardware configuration, from the DRM CRTC by moving the CRTC to the zynqmp_dpsub structure. The CRTC handling code will be moved to a separate file in a subsequent step. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move audio clk from zynqmp_disp to zynqmp_dpsubLaurent Pinchart
The audio clock is an external resource from the DPSUB point of view, not a resource internal to the display controller. Move it to the zynqmp_dpsub structure, to allow accessing it from outside the disp code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Move pclk from zynqmp_disp to zynqmp_dpsubLaurent Pinchart
The video clock is an external resource from the DPSUB point of view, not a resource internal to the display controller. Move it to the zynqmp_dpsub structure, to allow accessing it from outside the disp code. While at it, rename the fields from pclk and pclk_from_ps to vid_clk and vid_clk_from_ps, to better reflect their purpose and match the documentation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Don't use drmm_kcalloc() for temporary dataLaurent Pinchart
The array of formats passed to drm_universal_plane_init() doesn't need to outlive the function call, as it's copied internally. Use kcalloc() instead of drmm_kcalloc() to allocate it, and free it right after usage. While at it, move the allocation and initialization of the formats array to a separate function, to prepare for splitting the DRM plane handling to a separate file. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Remplace hardcoded values with ARRAY_SIZE()Laurent Pinchart
Use the ARRAY_SIZE() macro to iterate over arrays, instead of hardcoding their size. This makes the code less error-prone should the array size change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Pass format info to zynqmp_disp_layer_set_format()Laurent Pinchart
The zynqmp_disp_layer_set_format() function only needs format information, not a full plane state. Get the necessary info from the plane state in the caller and pass it to zynqmp_disp_layer_set_format(). This prepares for calling the function from non-DRM code. This doesn't introduce any functional change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Use local variable in zynqmp_disp_layer_update()Laurent Pinchart
Reuse the local info variable instead of going through the layer pointer in zynqmp_disp_layer_update(). This doesn't introduce any functional change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Configure blender in zynqmp_disp_enable()Laurent Pinchart
To prepare for control of the blender outside of the CRTC code, move the setup of the blender to the zynqmp_disp_enable() function. This doesn't introduce any functional change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Don't pass CRTC to zynqmp_disp_setup_clock()Laurent Pinchart
To prepare for usage of the clock setup function outside of the CRTC code, replace the DRM-specific structures passed as parameters with a pointer to the zynqmp_disp and the requested clock rate. This doesn't introduce any functional change. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Drop unused zynqmp_disp_format.bus_fmt fieldLaurent Pinchart
The bus_fmt field of the zynqmp_disp_format structure is unused. Drop it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-19drm: xlnx: zynqmp_dpsub: Drop unused zynqmp_disp.event fieldLaurent Pinchart
The event field of the zynqmp_disp structure is unused. Drop it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-08-03drm/gem: rename struct drm_gem_dma_object.{paddr => dma_addr}Danilo Krummrich
The field paddr of struct drm_gem_dma_object holds a DMA address, which might actually be a physical address. However, depending on the platform, it can also be a bus address or a virtual address managed by an IOMMU. Hence, rename the field to dma_addr, which is more applicable. In order to do this renaming the following coccinelle script was used: ``` @@ struct drm_gem_dma_object *gem; @@ - gem->paddr + gem->dma_addr @@ struct drm_gem_dma_object gem; @@ - gem.paddr + gem.dma_addr @exists@ typedef dma_addr_t; symbol paddr; @@ dma_addr_t paddr; <... - paddr + dma_addr ...> @@ symbol paddr; @@ dma_addr_t - paddr + dma_addr ; ``` This patch is compile-time tested with: ``` make ARCH={x86_64,arm,arm64} allyesconfig make ARCH={x86_64,arm,arm64} drivers/gpu/drm` ``` Acked-by: Sam Ravnborg <sam@ravnborg.org> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Danilo Krummrich <dakr@redhat.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220802000405.949236-5-dakr@redhat.com
2022-08-03drm/fb: rename FB CMA helpers to FB DMA helpersDanilo Krummrich
Rename "FB CMA" helpers to "FB DMA" helpers - considering the hierarchy of APIs (mm/cma -> dma -> fb dma) calling them "FB DMA" seems to be more applicable. Besides that, commit e57924d4ae80 ("drm/doc: Task to rename CMA helpers") requests to rename the CMA helpers and implies that people seem to be confused about the naming. In order to do this renaming the following script was used: ``` #!/bin/bash DIRS="drivers/gpu include/drm Documentation/gpu" REGEX_SYM_UPPER="[0-9A-Z_\-]" REGEX_SYM_LOWER="[0-9a-z_\-]" REGEX_GREP_UPPER="(${REGEX_SYM_UPPER}*)(FB)_CMA_(${REGEX_SYM_UPPER}*)" REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(fb)_cma_(${REGEX_SYM_LOWER}*)" REGEX_SED_UPPER="s/${REGEX_GREP_UPPER}/\1\2_DMA_\3/g" REGEX_SED_LOWER="s/${REGEX_GREP_LOWER}/\1\2_dma_\3/g" # Find all upper case 'CMA' symbols and replace them with 'DMA'. for ff in $(grep -REHl "${REGEX_GREP_UPPER}" $DIRS) do sed -i -E "$REGEX_SED_UPPER" $ff done # Find all lower case 'cma' symbols and replace them with 'dma'. for ff in $(grep -REHl "${REGEX_GREP_LOWER}" $DIRS) do sed -i -E "$REGEX_SED_LOWER" $ff done # Replace all occurrences of 'CMA' / 'cma' in comments and # documentation files with 'DMA' / 'dma'. for ff in $(grep -RiHl " cma " $DIRS) do sed -i -E "s/ cma / dma /g" $ff sed -i -E "s/ CMA / DMA /g" $ff done ``` Only a few more manual modifications were needed, e.g. reverting the following modifications in some DRM Kconfig files - select CMA if HAVE_DMA_CONTIGUOUS + select DMA if HAVE_DMA_CONTIGUOUS as well as manually picking the occurrences of 'CMA'/'cma' in comments and documentation which relate to "FB CMA", but not "GEM CMA". This patch is compile-time tested building a x86_64 kernel with `make allyesconfig && make drivers/gpu/drm`. Acked-by: Sam Ravnborg <sam@ravnborg.org> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> #drivers/gpu/drm/arm Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220802000405.949236-3-dakr@redhat.com
2022-07-26drm/atomic-helper: Remove _HELPER_ infix from DRM_PLANE_HELPER_NO_SCALINGThomas Zimmermann
Rename DRM_PLANE_HELPER_NO_SCALING to DRM_PLANE_NO_SCALING. The constant is not really a helper, but rather a characteristic of the plane itself. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220720083058.15371-4-tzimmermann@suse.de
2022-07-26drm/atomic-helper: Move DRM_PLANE_HELPER_NO_SCALING to atomic helpersThomas Zimmermann
The macro DRM_PLANE_HELPER_NO_SCALING is only useful with the interfaces in drm_atomic_helper.h, but defined in drm_plane_helper.h. So half of DRM includes the latter header file for using this macro. Move the macro and remove the include statements. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220720083058.15371-3-tzimmermann@suse.de
2022-06-21drm/xlnx: Fix build failure due to missing includeVille Syrjälä
Dropping drm_blend.h from drm_crtc.h broke the xlnx driver. Make it build again by including drm_blend.h from the driver directly. My .config was missing some required dependencies so I never build tested it :/ Cc: Hyun Kwon <hyun.kwon@xilinx.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Fixes: 90bb087f6674 ("drm: Drop drm_blend.h from drm_crtc.h") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220621075648.7717-1-ville.syrjala@linux.intel.com Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-17dmaengine: xilinx_dpdma: stop using slave_id fieldArnd Bergmann
The display driver wants to pass a custom flag to the DMA engine driver, which it started doing by using the slave_id field that was traditionally used for a different purpose. As there is no longer a correct use for the slave_id field, it should really be removed, and the remaining users changed over to something different. The new mechanism for passing nonstandard settings is using the .peripheral_config field, so use that to pass a newly defined structure here, making it clear that this will not work in portable drivers. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20211122222203.4103644-10-arnd@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
2021-08-09drm/xlnx/zynqmp_disp: Fix incorrectly named enum 'zynqmp_disp_layer_id'Lee Jones
Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/xlnx/zynqmp_disp.c:101: warning: expecting prototype for enum zynqmp_disp_id. Prototype was for enum zynqmp_disp_layer_id instead Signed-off-by: Lee Jones <lee.jones@linaro.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp_dpsub: Expose plane ordering to userspaceLaurent Pinchart
While the DPSUB has a fixed plane order, it still makes sense to expose it to userspace to avoid hardcoding assumptions. Do so by adding an immutable zpos property to planes. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp_dpsub: Add global alpha supportLaurent Pinchart
The graphics plane has a global alpha setting. Expose it through the plane's alpha property. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp_dpsub: Fix graphics layer blendingLaurent Pinchart
To display the graphics layer, the global alpha needs to be enabled. Enable it when the graphics plane is enabled (with full opacity), and disable it otherwise. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp_dpsub: Pass disp structure to all internal functionsLaurent Pinchart
The internal functions dealing with the audio/video buffer manager, the blender, and the audio mixer, all receive pointers to the respective objects. Those objects are embedded in the zynqmp_disp structure, and a very small. Treating them as separate objects would require expanding them with back-pointers to the zynqmp_disp in order to access fields such as the device pointer for debug messages, and this isn't worth it. Instead, merge those structures with the zynqmp_disp structure, and pass the zynqmp_disp pointer to all internal functions. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp: Add zynqmp_disp_layer_is_video() to simplify the codeQuanyang Wang
Add a new function zynqmp_disp_layer_is_video() to simplify the code that judges if a layer is the video layer. Acked-by: Paul Cercueil <paul@crapouillou.net> Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> [Renamed is_layer_vid() to zynqmp_disp_layer_is_video()]] Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-09drm: xlnx: zynqmp_dpsub: Call pm_runtime_get_sync before setting pixel clockQuanyang Wang
The Runtime PM subsystem will force the device "fd4a0000.zynqmp-display" to enter suspend state while booting if the following conditions are met: - the usage counter is zero (pm_runtime_get_sync hasn't been called yet) - no 'active' children (no zynqmp-dp-snd-xx node under dpsub node) - no other device in the same power domain (dpdma node has no "power-domains = <&zynqmp_firmware PD_DP>" property) So there is a scenario as below: 1) DP device enters suspend state <- call zynqmp_gpd_power_off 2) zynqmp_disp_crtc_setup_clock <- configurate register VPLL_FRAC_CFG 3) pm_runtime_get_sync <- call zynqmp_gpd_power_on and clear previous VPLL_FRAC_CFG configuration 4) clk_prepare_enable(disp->pclk) <- enable failed since VPLL_FRAC_CFG configuration is corrupted From above, we can see that pm_runtime_get_sync may clear register VPLL_FRAC_CFG configuration and result the failure of clk enabling. Putting pm_runtime_get_sync at the very beginning of the function zynqmp_disp_crtc_atomic_enable can resolve this issue. Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-03-16Merge tag 'drm-misc-next-2021-03-03' of ↵Dave Airlie
git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for 5.13: UAPI Changes: Cross-subsystem Changes: Core Changes: - %p4cc printk format modifier - atomic: introduce drm_crtc_commit_wait, rework atomic plane state helpers to take the drm_commit_state structure - dma-buf: heaps rework to return a struct dma_buf - simple-kms: Add plate state helpers - ttm: debugfs support, removal of sysfs Driver Changes: - Convert drivers to shadow plane helpers - arc: Move to drm/tiny - ast: cursor plane reworks - gma500: Remove TTM and medfield support - mxsfb: imx8mm support - panfrost: MMU IRQ handling rework - qxl: rework to better handle resources deallocation, locking - sun4i: Add alpha properties for UI and VI layers - vc4: RPi4 CEC support - vmwgfx: doc cleanup Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20210303100600.dgnkadonzuvfnu22@gilmour
2021-02-25drm: Use state helper instead of the plane state pointerMaxime Ripard
Many drivers reference the plane->state pointer in order to get the current plane state in their atomic_update or atomic_disable hooks, which would be the new plane state in the global atomic state since _swap_state happened when those hooks are run. Use the drm_atomic_get_new_plane_state helper to get that state to make it more obvious. This was made using the coccinelle script below: @ plane_atomic_func @ identifier helpers; identifier func; @@ ( static const struct drm_plane_helper_funcs helpers = { ..., .atomic_disable = func, ..., }; | static const struct drm_plane_helper_funcs helpers = { ..., .atomic_update = func, ..., }; ) @ adds_new_state @ identifier plane_atomic_func.func; identifier plane, state; identifier new_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... - struct drm_plane_state *new_state = plane->state; + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); ... } @ include depends on adds_new_state @ @@ #include <drm/drm_atomic.h> @ no_include depends on !include && adds_new_state @ @@ + #include <drm/drm_atomic.h> #include <drm/...> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
2021-02-25drm/atomic: Pass the full state to planes atomic disable and updateMaxime Ripard
The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's convert the remaining helpers to provide a consistent interface, this time with the planes atomic_update and atomic_disable. The conversion was done using the coccinelle script below, built tested on all the drivers. @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... void (*atomic_update)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... void (*atomic_disable)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @ plane_atomic_func @ identifier helpers; identifier func; @@ ( static const struct drm_plane_helper_funcs helpers = { ..., .atomic_update = func, ..., }; | static const struct drm_plane_helper_funcs helpers = { ..., .atomic_disable = func, ..., }; ) @@ struct drm_plane_helper_funcs *FUNCS; identifier f; identifier crtc_state; identifier plane, plane_state, state; expression e; @@ f(struct drm_crtc_state *crtc_state) { ... struct drm_atomic_state *state = e; <+... ( - FUNCS->atomic_disable(plane, plane_state) + FUNCS->atomic_disable(plane, state) | - FUNCS->atomic_update(plane, plane_state) + FUNCS->atomic_update(plane, state) ) ...+> } @@ identifier plane_atomic_func.func; identifier plane; symbol state; @@ func(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_plane_state *old_plane_state) { <... - state + old_plane_state ...> } @ ignores_old_state @ identifier plane_atomic_func.func; identifier plane, old_state; @@ func(struct drm_plane *plane, struct drm_plane_state *old_state) { ... when != old_state } @ adds_old_state depends on plane_atomic_func && !ignores_old_state @ identifier plane_atomic_func.func; identifier plane, plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *plane_state) { + struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane); ... } @ depends on plane_atomic_func @ identifier plane_atomic_func.func; identifier plane, plane_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *plane_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_old_state @ @@ #include <drm/drm_atomic.h> @ no_include depends on !include && adds_old_state @ @@ + #include <drm/drm_atomic.h> #include <drm/...> @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane); <+... - plane_state->state + state ...+> } Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-9-maxime@cerno.tech
2021-02-24drm: Store new plane state in a variable for atomic_update and disableMaxime Ripard
In order to store the new plane state in a subsequent helper, let's move the plane->state dereferences into a variable. This was done using the following coccinelle script, plus some hand changes for vmwgfx: @ plane_atomic_func @ identifier helpers; identifier func; @@ ( static const struct drm_plane_helper_funcs helpers = { ..., .atomic_disable = func, ..., }; | static const struct drm_plane_helper_funcs helpers = { ..., .atomic_update = func, ..., }; ) @ has_new_state_old_state @ identifier plane_atomic_func.func; identifier plane; identifier new_state; symbol old_state; @@ func(struct drm_plane *plane, struct drm_plane_state *old_state) { ... struct drm_plane_state *new_state = plane->state; ... } @ depends on !has_new_state_old_state @ identifier plane_atomic_func.func; identifier plane; symbol old_state; @@ func(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct drm_plane_state *new_state = plane->state; <+... - plane->state + new_state ...+> } @ has_new_state_state @ identifier plane_atomic_func.func; identifier plane; identifier new_state; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { ... struct drm_plane_state *new_state = plane->state; ... } @ depends on !has_new_state_state @ identifier plane_atomic_func.func; identifier plane; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { + struct drm_plane_state *new_plane_state = plane->state; <+... - plane->state + new_plane_state ...+> } @ has_new_state_old_s @ identifier plane_atomic_func.func; identifier plane; identifier new_state; symbol old_s; @@ func(struct drm_plane *plane, struct drm_plane_state *old_s) { ... struct drm_plane_state *new_state = plane->state; ... } @ depends on !has_new_state_old_s @ identifier plane_atomic_func.func; identifier plane; symbol old_s; @@ func(struct drm_plane *plane, struct drm_plane_state *old_s) { + struct drm_plane_state *new_s = plane->state; <+... - plane->state + new_s ...+> } Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
2021-02-24drm: Use the state pointer directly in planes atomic_checkMaxime Ripard
Now that atomic_check takes the global atomic state as a parameter, we don't need to go through the pointer in the plane state. This was done using the following coccinelle script: @ plane_atomic_func @ identifier helpers; identifier func; @@ static struct drm_plane_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... - struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); <... when != plane_state - plane_state->state + state ...> } @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); <... - plane_state->state + state ...> } Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-5-maxime@cerno.tech
2021-02-24drm/atomic: Pass the full state to planes atomic_checkMaxime Ripard
The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's convert all the remaining helpers to provide a consistent interface, starting with the planes atomic_check. The conversion was done using the coccinelle script below plus some manual changes for vmwgfx, built tested on all the drivers. @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... int (*atomic_check)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @ plane_atomic_func @ identifier helpers; identifier func; @@ static const struct drm_plane_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @@ struct drm_plane_helper_funcs *FUNCS; identifier f; identifier dev; identifier plane, plane_state, state; @@ f(struct drm_device *dev, struct drm_atomic_state *state) { <+... - FUNCS->atomic_check(plane, plane_state) + FUNCS->atomic_check(plane, state) ...+> } @ ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { ... when != new_plane_state } @ adds_new_state depends on plane_atomic_func && !ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); ... } @ depends on plane_atomic_func @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *new_plane_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_new_state @ @@ #include <drm/drm_atomic.h> @ no_include depends on !include && adds_new_state @ @@ + #include <drm/drm_atomic.h> #include <drm/...> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-4-maxime@cerno.tech
2021-02-24drm: Rename plane atomic_check state namesMaxime Ripard
Most drivers call the argument to the plane atomic_check hook simply state, which is going to conflict with the global atomic state in a later rework. Let's rename it to new_plane_state (or new_state depending on the convention used in the driver). This was done using the coccinelle script below, and built tested: @ plane_atomic_func @ identifier helpers; identifier func; @@ static const struct drm_plane_helper_funcs helpers = { .atomic_check = func, }; @ has_old_state @ identifier plane_atomic_func.func; identifier plane; expression e; symbol old_state; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { ... struct drm_plane_state *old_state = e; ... } @ depends on has_old_state @ identifier plane_atomic_func.func; identifier plane; symbol old_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *state + struct drm_plane_state *new_state ) { <+... - state + new_state ...+> } @ has_state @ identifier plane_atomic_func.func; identifier plane; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { ... } @ depends on has_state @ identifier plane_atomic_func.func; identifier plane; symbol old_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *state + struct drm_plane_state *new_plane_state ) { <+... - state + new_plane_state ...+> } Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-2-maxime@cerno.tech
2021-02-03drm/xlnx: fix kmemleak by sending vblank_event in atomic_disableQuanyang Wang
When running xrandr to change resolution of DP, the kmemleak as below can be observed: unreferenced object 0xffff00080a351000 (size 256): comm "Xorg", pid 248, jiffies 4294899614 (age 19.960s) hex dump (first 32 bytes): 98 a0 bc 01 08 00 ff ff 01 00 00 00 00 00 00 00 ................ ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000e0bd0f69>] kmemleak_alloc+0x30/0x40 [<00000000cde2f318>] kmem_cache_alloc+0x3d4/0x588 [<0000000088ea9bd7>] drm_atomic_helper_setup_commit+0x84/0x5f8 [<000000002290a264>] drm_atomic_helper_commit+0x58/0x388 [<00000000f6ea78c3>] drm_atomic_commit+0x4c/0x60 [<00000000c8e0725e>] drm_atomic_connector_commit_dpms+0xe8/0x110 [<0000000020ade187>] drm_mode_obj_set_property_ioctl+0x1b0/0x450 [<00000000918206d6>] drm_connector_property_set_ioctl+0x3c/0x68 [<000000008d51e7a5>] drm_ioctl_kernel+0xc4/0x118 [<000000002a819b75>] drm_ioctl+0x214/0x448 [<000000008ca4e588>] __arm64_sys_ioctl+0xa8/0xf0 [<0000000034e15a35>] el0_svc_common.constprop.0+0x74/0x190 [<000000001b93d916>] do_el0_svc+0x24/0x90 [<00000000ce9230e0>] el0_svc+0x14/0x20 [<00000000e3607d82>] el0_sync_handler+0xb0/0xb8 [<000000003e79c15f>] el0_sync+0x174/0x180 This is because there is a scenario that a drm_crtc_commit commit is allocated but not freed. The drm subsystem require/release references to a CRTC commit by calling drm_crtc_commit_get/put, and when drm_crtc_commit_put find that commit.ref.refcount is zero, it will call __drm_crtc_commit_free to free this CRTC commit. Among these drm_crtc_commit_get/put pairs, there is a drm_crtc_commit_get in drm_atomic_helper_setup_commit as below: ... new_crtc_state->event->base.completion = &commit->flip_done; new_crtc_state->event->base.completion_release = release_crtc_commit; drm_crtc_commit_get(commit); ... This reference to the CRTC commit should be released at the function release_crtc_commit by calling e->completion_release(e->completion) in drm_send_event_locked. So we need to call drm_send_event_locked at two places: handling vblank event in the irq handler and the crtc disable helper. But in zynqmp_disp_crtc_atomic_disable, it only marks the flip is done and not call drm_crtc_commit_put. This result that the refcount of this commit is always non-zero and this commit will never be freed. Since the function drm_crtc_send_vblank_event has operations both sending a flip_done signal and releasing reference to the CRTC commit, let's use it instead. Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20210202064121.173362-1-quanyang.wang@windriver.com
2020-11-03drm: Use the state pointer directly in atomic_checkMaxime Ripard
Now that atomic_check takes the global atomic state as a parameter, we don't need to go through the pointer in the CRTC state. This was done using the following coccinelle script: @ crtc_atomic_func @ identifier helpers; identifier func; @@ static struct drm_crtc_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @@ identifier crtc_atomic_func.func; identifier crtc, state; @@ func(struct drm_crtc *crtc, struct drm_atomic_state *state) { ... - struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ... when != crtc_state - crtc_state->state + state ... } @@ struct drm_crtc_state *crtc_state; identifier crtc_atomic_func.func; identifier crtc, state; @@ func(struct drm_crtc *crtc, struct drm_atomic_state *state) { ... - crtc_state->state + state ... } Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201102133834.1176740-3-maxime@cerno.tech
2020-11-02drm/atomic: Pass the full state to CRTC atomic begin and flushMaxime Ripard
The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's start convert all the remaining helpers to provide a consistent interface, starting with the CRTC's atomic_begin and atomic_flush. The conversion was done using the coccinelle script below, built tested on all the drivers and actually tested on vc4. virtual report @@ struct drm_crtc_helper_funcs *FUNCS; identifier old_crtc_state, old_state; identifier crtc; identifier f; @@ f(struct drm_crtc_state *old_crtc_state) { ... struct drm_atomic_state *old_state = old_crtc_state->state; <... - FUNCS->atomic_begin(crtc, old_crtc_state); + FUNCS->atomic_begin(crtc, old_state); ...> } @@ struct drm_crtc_helper_funcs *FUNCS; identifier old_crtc_state, old_state; identifier crtc; identifier f; @@ f(struct drm_crtc_state *old_crtc_state) { ... struct drm_atomic_state *old_state = old_crtc_state->state; <... - FUNCS->atomic_flush(crtc, old_crtc_state); + FUNCS->atomic_flush(crtc, old_state); ...> } @@ struct drm_crtc_helper_funcs *FUNCS; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; identifier dev, state; identifier f; @@ f(struct drm_device *dev, struct drm_atomic_state *state, ...) { <... - FUNCS->atomic_begin(crtc, crtc_state); + FUNCS->atomic_begin(crtc, state); ...> } @@ struct drm_crtc_helper_funcs *FUNCS; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; identifier dev, state; identifier f; @@ f(struct drm_device *dev, struct drm_atomic_state *state, ...) { <... - FUNCS->atomic_flush(crtc, crtc_state); + FUNCS->atomic_flush(crtc, state); ...> } @@ identifier crtc, old_state; @@ struct drm_crtc_helper_funcs { ... - void (*atomic_begin)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_begin)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... - void (*atomic_flush)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_flush)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... } @ crtc_atomic_func @ identifier helpers; identifier func; @@ ( static struct drm_crtc_helper_funcs helpers = { ..., .atomic_begin = func, ..., }; | static struct drm_crtc_helper_funcs helpers = { ..., .atomic_flush = func, ..., }; ) @ ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@ void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { ... when != old_state } @ adds_old_state depends on crtc_atomic_func && !ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@ void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); ... } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; expression E; type T; @@ void func(...) { ... - T state = E; + T crtc_state = E; <+... - state + crtc_state ...+> } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; type T; @@ void func(...) { ... - T state; + T crtc_state; <+... - state + crtc_state ...+> } @@ identifier old_state; identifier crtc; @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); ... } @@ identifier old_state; identifier crtc; @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ); @@ identifier old_state; identifier crtc; @@ void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... } @@ identifier old_state; identifier crtc; @@ void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ); @@ identifier old_state; identifier crtc; @@ void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... } @@ identifier old_state; identifier crtc; @@ void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ); @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; identifier old_state; identifier crtc; @@ void func(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_old_state @ @@ #include <drm/drm_atomic.h> @ no_include depends on !include && adds_old_state @ @@ + #include <drm/drm_atomic.h> #include <drm/...> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-2-maxime@cerno.tech
2020-11-02drm/atomic: Pass the full state to CRTC atomic_checkMaxime Ripard
The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's start convert all the remaining helpers to provide a consistent interface, starting with the CRTC's atomic_check. The conversion was done using the coccinelle script below, built tested on all the drivers and actually tested on vc4. virtual report @@ struct drm_crtc_helper_funcs *FUNCS; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; identifier dev, state; identifier ret, f; @@ f(struct drm_device *dev, struct drm_atomic_state *state) { <... - ret = FUNCS->atomic_check(crtc, crtc_state); + ret = FUNCS->atomic_check(crtc, state); ...> } @@ identifier crtc, new_state; @@ struct drm_crtc_helper_funcs { ... - int (*atomic_check)(struct drm_crtc *crtc, struct drm_crtc_state *new_state); + int (*atomic_check)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... } @ crtc_atomic_func @ identifier helpers; identifier func; @@ static struct drm_crtc_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @ ignores_new_state @ identifier crtc_atomic_func.func; identifier crtc, new_state; @@ int func(struct drm_crtc *crtc, struct drm_crtc_state *new_state) { ... when != new_state } @ adds_new_state depends on crtc_atomic_func && !ignores_new_state @ identifier crtc_atomic_func.func; identifier crtc, new_state; @@ int func(struct drm_crtc *crtc, struct drm_crtc_state *new_state) { + struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); ... } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; expression E; type T; @@ int func(...) { ... - T state = E; + T crtc_state = E; <+... - state + crtc_state ...+> } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; type T; @@ int func(...) { ... - T state; + T crtc_state; <+... - state + crtc_state ...+> } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; identifier new_state; identifier crtc; @@ int func(struct drm_crtc *crtc, - struct drm_crtc_state *new_state + struct drm_atomic_state *state ) { ... } @@ identifier new_state; identifier crtc; @@ int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *new_state + struct drm_atomic_state *state ) { + struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); ... } @@ identifier new_state; identifier crtc; @@ int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *new_state + struct drm_atomic_state *state ); @ include depends on adds_new_state @ @@ #include <drm/drm_atomic.h> @ no_include depends on !include && adds_new_state @ @@ + #include <drm/drm_atomic.h> #include <drm/...> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-1-maxime@cerno.tech