[PATCH v2 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765
The tc358765 is similar to tc358775 except for the stdby-gpios. Signed-off-by: Tony Lindgren --- .../bindings/display/bridge/toshiba,tc358775.yaml | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml @@ -10,7 +10,7 @@ maintainers: - Vinay Simha BN description: | - This binding supports DSI to LVDS bridge TC358775 + This binding supports DSI to LVDS bridges TC358765 and TC358775 MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane. Video frame size: @@ -21,7 +21,9 @@ description: | properties: compatible: -const: toshiba,tc358775 +enum: + - toshiba,tc358765 + - toshiba,tc358775 reg: maxItems: 1 -- 2.43.0
[PATCH v2 02/10] dt-bindings: display: bridge: tc358775: Add data-lanes
The device uses a clock lane, and 1 to 4 DSI data lanes. Let's add the data-lanes property starting at 1 similar to what the other bridge bindings are doing. Let's also drop the data-lanes properties in the example for the DSI host controller to avoid confusion. The configuration of the DSI host depends on the controller used and is unrelated to the bridge binding. Signed-off-by: Tony Lindgren --- .../display/bridge/toshiba,tc358775.yaml | 21 --- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml @@ -46,11 +46,26 @@ properties: properties: port@0: -$ref: /schemas/graph.yaml#/properties/port +$ref: /schemas/graph.yaml#/$defs/port-base description: | DSI Input. The remote endpoint phandle should be a reference to a valid mipi_dsi_host device node. +properties: + endpoint: +$ref: /schemas/media/video-interfaces.yaml# +unevaluatedProperties: false + +properties: + data-lanes: +description: array of physical DSI data lane indexes. +minItems: 1 +items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 + port@1: $ref: /schemas/graph.yaml#/properties/port description: | @@ -105,6 +120,7 @@ examples: reg = <0>; d2l_in_test: endpoint { remote-endpoint = <_out>; +data-lanes = <1 2 3 4>; }; }; @@ -129,7 +145,6 @@ examples: reg = <1>; dsi0_out: endpoint { remote-endpoint = <_in_test>; -data-lanes = <0 1 2 3>; }; }; }; @@ -164,6 +179,7 @@ examples: reg = <0>; d2l_in_dual: endpoint { remote-endpoint = <_out_dual>; +data-lanes = <1 2 3 4>; }; }; @@ -195,7 +211,6 @@ examples: reg = <1>; dsi0_out_dual: endpoint { remote-endpoint = <_in_dual>; -data-lanes = <0 1 2 3>; }; }; }; -- 2.43.0
[PATCH v2 01/10] dt-bindings: display: bridge: tc358775: make stby gpio and vdd supplies optional
From: Michael Walle For a normal operation, the vdd supplies nor the stby GPIO is needed. There are boards, where these voltages are statically enabled during board power-up. The reset pin is required because once the PPI (PHY protocol interface) is started, it can only be stopped by asserting the reset pin. Signed-off-by: Michael Walle Signed-off-by: Tony Lindgren --- .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml @@ -68,9 +68,6 @@ properties: required: - compatible - reg - - vdd-supply - - vddio-supply - - stby-gpios - reset-gpios - ports -- 2.43.0
[PATCH v2 00/10] Improvments for tc358775 with support for tc358765
Here's v2 of these changes merged with patches from Michael. Regards, Tony Changes since v1: - After a brief offline discussion with Michael, merge series with Michael's patch series to make stby gpio and supplies optional as they may be hardwired - Use Michael's better patch for the jeida timings change - Parse lanes on the bridge side like other bridge devices do, and if not found, also parse on the DSI host side and warn Michael Walle (3): dt-bindings: display: bridge: tc358775: make stby gpio and vdd supplies optional drm/bridge: tc358775: fix support for jeida-18 and jeida-24 drm/bridge: tc358775: make standby GPIO optional Tony Lindgren (7): dt-bindings: display: bridge: tc358775: Add data-lanes dt-bindings: display: bridge: tc358775: Add support for tc358765 drm/bridge: tc358775: Get bridge data lanes instead of the DSI host lanes drm/bridge: tc358775: Add burst and low-power modes drm/bridge: tc358775: Enable pre_enable_prev_first flag drm/bridge: tc358775: Add support for tc358765 drm/bridge: tc358775: Configure hs_rate and lp_rate .../display/bridge/toshiba,tc358775.yaml | 30 +-- drivers/gpu/drm/bridge/tc358775.c | 90 +++ 2 files changed, 75 insertions(+), 45 deletions(-) -- 2.43.0
Re: [PATCH] drm/imagination: DRM_POWERVR should depend on ARCH_K3
On 19:29-20231128, Geert Uytterhoeven wrote: > The Imagination Technologies PowerVR Series 6 GPU is currently only > supported on Texas Instruments K3 AM62x SoCs. Hence add a dependency on > ARCH_K3, to prevent asking the user about this driver when configuring a > kernel without Texas Instruments K3 Multicore SoC support. > > Fixes: 4babef0708656c54 ("drm/imagination: Add skeleton PowerVR driver") Minor nitpick here - 12 char sha.. otherwise: Reviewed-by: Nishanth Menon > Signed-off-by: Geert Uytterhoeven > --- > drivers/gpu/drm/imagination/Kconfig | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/imagination/Kconfig > b/drivers/gpu/drm/imagination/Kconfig > index 3bfa2ac212dccb73..af492dbd9afd4ed9 100644 > --- a/drivers/gpu/drm/imagination/Kconfig > +++ b/drivers/gpu/drm/imagination/Kconfig > @@ -6,6 +6,7 @@ config DRM_POWERVR > depends on ARM64 > depends on DRM > depends on PM > + depends on ARCH_K3 || COMPILE_TEST > select DRM_EXEC > select DRM_GEM_SHMEM_HELPER > select DRM_SCHED > -- > 2.34.1 > -- Regards, Nishanth Menon Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3 1A34 DDB5 849D 1736 249D
Re: [PATCH 01/17] drm/msm: add arrays listing formats supported by MDP4/MDP5 hardware
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: MDP4 and MDP5 drivers enumerate supported formats each time the plane is created. As the list of supported image formats is constant, create corresponding data arrays to be used by MDP4 and MDP5 drivers. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp_format.c | 49 +-- drivers/gpu/drm/msm/disp/mdp_kms.h| 5 +++ 2 files changed, 52 insertions(+), 2 deletions(-) After going through the patch series, as commented in patch 17 I am totally fine with migrating to drmm-managed APIs but I dont like to maintain 3 format arrays. Can we keep the existing format mechanism to avoid having two more arrays? diff --git a/drivers/gpu/drm/msm/disp/mdp_format.c b/drivers/gpu/drm/msm/disp/mdp_format.c index 025595336f26..ba9abe8b3acc 100644 --- a/drivers/gpu/drm/msm/disp/mdp_format.c +++ b/drivers/gpu/drm/msm/disp/mdp_format.c @@ -81,8 +81,8 @@ static struct csc_cfg csc_convert[CSC_MAX] = { #define BPC0A 0 /* - * Note: Keep RGB formats 1st, followed by YUV formats to avoid breaking - * mdp_get_rgb_formats()'s implementation. + * Note: Keep mdp_rgb_formats and mdp_rgb_yuv_formats in sync when adding + * entries to this array. */ static const struct mdp_format formats[] = { /* name a r g b e0 e1 e2 e3 alpha tight cpp cnt ... */ @@ -138,6 +138,51 @@ static const struct mdp_format formats[] = { MDP_PLANE_PLANAR, CHROMA_420, true), }; +const uint32_t mdp_rgb_formats[] = { + DRM_FORMAT_ARGB, + DRM_FORMAT_ABGR, + DRM_FORMAT_RGBA, + DRM_FORMAT_BGRA, + DRM_FORMAT_XRGB, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGBX, + DRM_FORMAT_BGRX, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, +}; + +size_t mdp_rgb_num_formats = ARRAY_SIZE(mdp_rgb_formats); + +const uint32_t mdp_rgb_yuv_formats[] = { + DRM_FORMAT_ARGB, + DRM_FORMAT_ABGR, + DRM_FORMAT_RGBA, + DRM_FORMAT_BGRA, + DRM_FORMAT_XRGB, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGBX, + DRM_FORMAT_BGRX, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + + 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, +}; + +size_t mdp_rgb_yuv_num_formats = ARRAY_SIZE(mdp_rgb_yuv_formats); + /* * Note: * @rgb_only must be set to true, when requesting diff --git a/drivers/gpu/drm/msm/disp/mdp_kms.h b/drivers/gpu/drm/msm/disp/mdp_kms.h index b0286d5d5130..11402a859574 100644 --- a/drivers/gpu/drm/msm/disp/mdp_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp_kms.h @@ -94,6 +94,11 @@ struct mdp_format { uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier); +extern const uint32_t mdp_rgb_formats[]; +extern size_t mdp_rgb_num_formats; +extern const uint32_t mdp_rgb_yuv_formats[]; +extern size_t mdp_rgb_yuv_num_formats; + /* MDP capabilities */ #define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */ #define MDP_CAP_DSC BIT(1) /* VESA Display Stream Compression*/
Re: [PATCH 17/17] drm/msm: drop mdp_get_formats()
On 12/1/2023 5:25 PM, Abhinav Kumar wrote: On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Drop the function mdp_get_formats(), which became unused after converting both MDP4 and MDP5 planes to use static formats arrays. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp_format.c | 24 drivers/gpu/drm/msm/disp/mdp_kms.h | 1 - 2 files changed, 25 deletions(-) Reviewed-by: Abhinav Kumar Actually, I have one concern with patch 1 and patch 17 of this series. You cannot get rid of static const struct mdp_format formats[] because mdp_get_format() still uses it. Now, we end up having to maintain two arrays to hold the formats, the already existing formats[] one and newly added mdp_rgb_formats[] and mdp_rgb_yuv_formats[]. This is an overkill. I am fine with overall migrating to drmm-managed APIs but I think patch 1 and this one are not necessary.
Re: [PATCH 17/17] drm/msm: drop mdp_get_formats()
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Drop the function mdp_get_formats(), which became unused after converting both MDP4 and MDP5 planes to use static formats arrays. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp_format.c | 24 drivers/gpu/drm/msm/disp/mdp_kms.h| 1 - 2 files changed, 25 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 16/17] drm/msm/mdp4: use drmm-managed allocation for mdp4_plane
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp4_plane allocation to use drmm_plane_alloc(). This removes the need to perform any actions on plane destruction. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 59 -- 1 file changed, 20 insertions(+), 39 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 15/17] drm/msm/mdp4: use drmm-managed allocation for mdp4_lcdc_encoder
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp4_lcdc_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on this encoder destruction. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 36 --- 1 file changed, 7 insertions(+), 29 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 14/17] drm/msm/mdp4: use drmm-managed allocation for mdp4_dtv_encoder
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp4_dtv_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on this encoder destruction. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c | 37 --- 1 file changed, 7 insertions(+), 30 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 13/17] drm/msm/mdp4: use drmm-managed allocation for mdp4_dsi_encoder
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp4_dsi_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on this encoder destruction. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c | 32 +++ 1 file changed, 5 insertions(+), 27 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 12/17] drm/msm/mdp4: use drmm-managed allocation for mdp4_crtc
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp4_crtc allocation to use drmm_crtc_alloc(). This removes the need to perform any actions on CRTC destruction. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 33 --- 1 file changed, 17 insertions(+), 16 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH] drm/msm/a6xx: add QMP dependency
On 16/10/2023 23:04, Arnd Bergmann wrote: From: Arnd Bergmann When QMP is in a loadable module, the A6xx GPU driver fails to link as built-in: x86_64-linux-ld: drivers/gpu/drm/msm/adreno/a6xx_gmu.o: in function `a6xx_gmu_resume': a6xx_gmu.c:(.text+0xd62): undefined reference to `qmp_send' Add the usual dependency that still allows compiling without QMP but otherwise avoids the broken combination of options. Fixes: 88a0997f2f949 ("drm/msm/a6xx: Send ACD state to QMP at GMU resume") Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/msm/Kconfig | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
[PATCH v7 02/10] drm/msm/dpu: Drop unused get_scaler_ver callback from SSPP
From: Marijn Suijten This pointer callback is never used and should be removed. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov [DB: dropped the helpers completely, which are unused now] Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 13 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 6 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 6 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 3 --- 4 files changed, 1 insertion(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 8e3c65989c49..b408d456c123 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -395,15 +395,6 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx, format); } -static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx) -{ - if (!ctx) - return 0; - - return dpu_hw_get_scaler3_ver(>hw, - ctx->cap->sblk->scaler_blk.base); -} - /* * dpu_hw_sspp_setup_rects() */ @@ -616,10 +607,8 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c, if (test_bit(DPU_SSPP_SCALER_QSEED3, ) || test_bit(DPU_SSPP_SCALER_QSEED3LITE, ) || - test_bit(DPU_SSPP_SCALER_QSEED4, )) { + test_bit(DPU_SSPP_SCALER_QSEED4, )) c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3; - c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver; - } if (test_bit(DPU_SSPP_CDP, )) c->ops.setup_cdp = dpu_hw_sspp_setup_cdp; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index f93969fddb22..b094ea23ad32 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -296,12 +296,6 @@ struct dpu_hw_sspp_ops { struct dpu_hw_scaler3_cfg *scaler3_cfg, const struct dpu_format *format); - /** -* get_scaler_ver - get scaler h/w version -* @ctx: Pointer to pipe context -*/ - u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx); - /** * setup_cdp - setup client driven prefetch * @pipe: Pointer to software pipe context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index 18b16b2d2bf5..0b05061e3e62 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -381,12 +381,6 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c, DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode); } -u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, - u32 scaler_offset) -{ - return DPU_REG_READ(c, QSEED3_HW_VERSION + scaler_offset); -} - void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, const struct dpu_csc_cfg *data, bool csc10) 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 4bea139081bc..fe083b2e5696 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -340,9 +340,6 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c, u32 scaler_offset, u32 scaler_version, const struct dpu_format *format); -u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, - u32 scaler_offset); - void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, const struct dpu_csc_cfg *data, bool csc10); -- 2.42.0
[PATCH v7 09/10] drm/msm/dpu: merge DPU_SSPP_SCALER_QSEED3, QSEED3LITE, QSEED4
Three different features, DPU_SSPP_SCALER_QSEED3, QSEED3LITE and QSEED4 are all related to different versions of the same HW scaling block. Corresponding driver parts use scaler_blk.version to identify the correct way to program the hardware. In order to simplify the driver codepath, merge these three feature bits into QSEED3_COMPATIBLE bin. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 8 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c| 9 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 +-- 4 files changed, 9 insertions(+), 19 deletions(-) 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 b8ea33d0f364..c24817b0e4e5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -22,19 +22,19 @@ BIT(DPU_SSPP_CSC_10BIT)) #define VIG_MSM8998_MASK \ - (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) + (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) #define VIG_SDM845_MASK \ - (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3)) + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) #define VIG_SDM845_MASK_SDMA \ (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) #define VIG_SC7180_MASK \ - (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4)) + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) #define VIG_SM6125_MASK \ - (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE)) + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) #define VIG_SC7180_MASK_SDMA \ (VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) 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 f9586ddbafda..d6b9000b63b0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -51,9 +51,7 @@ enum { /** * SSPP sub-blocks/features * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support - * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support - * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support - * @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support + * @DPU_SSPP_SCALER_QSEED3_COMPATIBLE, QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4) * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes * @DPU_SSPP_CSC,Support of Color space converion * @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion @@ -71,9 +69,7 @@ enum { */ enum { DPU_SSPP_SCALER_QSEED2 = 0x1, - DPU_SSPP_SCALER_QSEED3, - DPU_SSPP_SCALER_QSEED3LITE, - DPU_SSPP_SCALER_QSEED4, + DPU_SSPP_SCALER_QSEED3_COMPATIBLE, DPU_SSPP_SCALER_RGB, DPU_SSPP_CSC, DPU_SSPP_CSC_10BIT, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index b408d456c123..26307d9fc81d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -605,9 +605,7 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c, test_bit(DPU_SSPP_SMART_DMA_V2, >cap->features)) c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; - if (test_bit(DPU_SSPP_SCALER_QSEED3, ) || - test_bit(DPU_SSPP_SCALER_QSEED3LITE, ) || - test_bit(DPU_SSPP_SCALER_QSEED4, )) + if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, )) c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3; if (test_bit(DPU_SSPP_CDP, )) @@ -643,10 +641,7 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, cfg->len, kms); - if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) || - cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) || - cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) || - cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) + if (sblk->scaler_blk.len) dpu_debugfs_create_regset32("scaler_blk", 0400, debugfs_root, sblk->scaler_blk.base + cfg->base, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 121cb0d290ee..6f4224956f6c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -470,8 +470,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw, scale_cfg->src_height[i] /= chroma_subsmpl_v; } - if (pipe_hw->cap->features & - BIT(DPU_SSPP_SCALER_QSEED4)) { +
[PATCH v7 07/10] drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro
As the subblock info is now mostly gone, inline and drop the macro DPU_HW_SUBBLK_INFO. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 40 ++- 1 file changed, 21 insertions(+), 19 deletions(-) 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 b2a9b2cf2c05..f9586ddbafda 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -248,49 +248,51 @@ enum { u32 len; \ unsigned long features -/** - * MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU - * @name: string name for debug purposes - * @base: offset of this sub-block relative to the block - * offset - * @lenregister block length of this sub-block - */ -#define DPU_HW_SUBBLK_INFO \ - char name[DPU_HW_BLK_NAME_LEN]; \ - u32 base; \ - u32 len - /** * struct dpu_scaler_blk: Scaler information - * @info: HW register and features supported by this sub-blk + * @name: string name for debug purposes + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block * @version: qseed block revision, on QSEED3+ platforms this is the value of * scaler_blk.base + QSEED3_HW_VERSION registers. */ struct dpu_scaler_blk { - DPU_HW_SUBBLK_INFO; + char name[DPU_HW_BLK_NAME_LEN]; + u32 base; + u32 len; u32 version; }; struct dpu_csc_blk { - DPU_HW_SUBBLK_INFO; + char name[DPU_HW_BLK_NAME_LEN]; + u32 base; + u32 len; }; /** * struct dpu_pp_blk : Pixel processing sub-blk information - * @info: HW register and features supported by this sub-blk + * @name: string name for debug purposes + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block * @version: HW Algorithm version */ struct dpu_pp_blk { - DPU_HW_SUBBLK_INFO; + char name[DPU_HW_BLK_NAME_LEN]; + u32 base; + u32 len; u32 version; }; /** * struct dpu_dsc_blk - DSC Encoder sub-blk information - * @info: HW register and features supported by this sub-blk + * @name: string name for debug purposes + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block */ struct dpu_dsc_blk { - DPU_HW_SUBBLK_INFO; + char name[DPU_HW_BLK_NAME_LEN]; + u32 base; + u32 len; }; /** -- 2.42.0
[PATCH v7 06/10] drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks
As we have dropped the variadic parts of SSPP sub-blocks declarations, deduplicate them now, reducing memory cruft. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 6 +- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 8 +- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 4 +- .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 8 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 4 +- .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 4 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 8 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 20 ++-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 97 +-- 17 files changed, 120 insertions(+), 167 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 4dcc9f804ac1..1d3e9666c741 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -69,7 +69,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = _vig_sblk_0, + .sblk = _vig_sblk_qseed3_1_2, .xin_id = 0, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG0, @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = _vig_sblk_1, + .sblk = _vig_sblk_qseed3_1_2, .xin_id = 4, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG1, @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = _vig_sblk_2, + .sblk = _vig_sblk_qseed3_1_2, .xin_id = 8, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG2, @@ -93,7 +93,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = _vig_sblk_3, + .sblk = _vig_sblk_qseed3_1_2, .xin_id = 12, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG3, @@ -101,7 +101,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1ac, .features = DMA_MSM8998_MASK, - .sblk = _dma_sblk_0, + .sblk = _dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA0, @@ -109,7 +109,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1ac, .features = DMA_MSM8998_MASK, - .sblk = _dma_sblk_1, + .sblk = _dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA1, @@ -117,7 +117,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1ac, .features = DMA_CURSOR_MSM8998_MASK, - .sblk = _dma_sblk_2, + .sblk = _dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA2, @@ -125,7 +125,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x1ac, .features = DMA_CURSOR_MSM8998_MASK, - .sblk = _dma_sblk_3, + .sblk = _dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA3, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 03159d359500..7a23389a5732 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++
[PATCH v7 08/10] drm/msm/dpu: rewrite scaler and CSC presense checks
In order to check whether the SSPP block has scaler and CSC subblocks the funcion dpu_plane_atomic_check_pipe() uses macros which enumerate all possible scaler and CSC features. Replace those checks with the scaler and CSC subblock length checks in order to be able to drop those two macros. Suggested-by: Abhinav Kumar Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 15 --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++-- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index b094ea23ad32..28e7d53bd191 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -21,21 +21,6 @@ struct dpu_hw_sspp; #define DPU_SSPP_ROT_90BIT(3) #define DPU_SSPP_SOLID_FILLBIT(4) -/** - * Define all scaler feature bits in catalog - */ -#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \ -BIT(DPU_SSPP_SCALER_QSEED2) | \ -BIT(DPU_SSPP_SCALER_QSEED3) | \ -BIT(DPU_SSPP_SCALER_QSEED3LITE) | \ -BIT(DPU_SSPP_SCALER_QSEED4)) - -/* - * Define all CSC feature bits in catalog - */ -#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \ - BIT(DPU_SSPP_CSC_10BIT)) - /** * Component indices */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 3eef5e025e12..121cb0d290ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -774,8 +774,8 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; if (DPU_FORMAT_IS_YUV(fmt) && - (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) || -!(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) { + (!pipe->sspp->cap->sblk->scaler_blk.len || +!pipe->sspp->cap->sblk->csc_blk.len)) { DPU_DEBUG_PLANE(pdpu, "plane doesn't have scaler/csc for yuv\n"); return -EINVAL; -- 2.42.0
[PATCH v7 10/10] drm/msm/gpu: drop duplicating VIG feature masks
After folding QSEED3LITE and QSEED4 feature bits into QSEED3_COMPATIBLE several VIG feature masks became equal. Drop these duplicates. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 11 +-- 11 files changed, 26 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h index 3969f2925d89..76b2ec0d2489 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h @@ -68,7 +68,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, - .features = VIG_SM6125_MASK, + .features = VIG_SDM845_MASK, .sblk = _vig_sblk_qseed3_2_4, .xin_id = 0, .type = SSPP_TYPE_VIG, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index f751d63845d1..9acf07108899 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -74,7 +74,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SC7180_MASK_SDMA, + .features = VIG_SDM845_MASK_SDMA, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -82,7 +82,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f8, - .features = VIG_SC7180_MASK_SDMA, + .features = VIG_SDM845_MASK_SDMA, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 4, .type = SSPP_TYPE_VIG, @@ -90,7 +90,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { }, { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1f8, - .features = VIG_SC7180_MASK_SDMA, + .features = VIG_SDM845_MASK_SDMA, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 8, .type = SSPP_TYPE_VIG, @@ -98,7 +98,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { }, { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1f8, - .features = VIG_SC7180_MASK_SDMA, + .features = VIG_SDM845_MASK_SDMA, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 12, .type = SSPP_TYPE_VIG, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 7627f16c5b2d..783269c6ead1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -51,7 +51,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SC7180_MASK, + .features = VIG_SDM845_MASK, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 7aefdb7eb494..43f64a005f5a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -38,7 +38,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SC7180_MASK, + .features = VIG_SDM845_MASK, .sblk = _vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h index 99df9816f171..e17a30be7525 100644 ---
[PATCH v7 05/10] drm/msm/dpu: drop the `smart_dma_priority' field from struct dpu_sspp_sub_blks
In preparation to deduplicating SSPP subblocks, drop the (unused) `smart_dma_priority' field from struct dpu_sspp_sub_blks. If it is needed later (e.g. for SmartDMA v1), it should be added to the SSPP declarations themselves. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 112 +++--- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 - 2 files changed, 40 insertions(+), 74 deletions(-) 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 eb9dfdcf610e..4179174ee4ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -252,11 +252,10 @@ static const uint32_t wb2_formats[] = { #define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min)) /* SSPP common configuration */ -#define _VIG_SBLK(sdma_pri, scaler_ver) \ +#define _VIG_SBLK(scaler_ver) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ - .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -269,11 +268,10 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = NULL, \ } -#define _VIG_SBLK_ROT(sdma_pri, scaler_ver, rot_cfg) \ +#define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ - .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -286,11 +284,10 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = rot_cfg, \ } -#define _DMA_SBLK(sdma_pri) \ +#define _DMA_SBLK() \ { \ .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ - .smart_dma_priority = sdma_pri, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ .virt_format_list = plane_formats, \ @@ -298,17 +295,13 @@ static const uint32_t wb2_formats[] = { } static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = - _VIG_SBLK(0, - SSPP_SCALER_VER(1, 2)); + _VIG_SBLK(SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = - _VIG_SBLK(0, - SSPP_SCALER_VER(1, 2)); + _VIG_SBLK(SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = - _VIG_SBLK(0, - SSPP_SCALER_VER(1, 2)); + _VIG_SBLK(SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = - _VIG_SBLK(0, - SSPP_SCALER_VER(1, 2)); + _VIG_SBLK(SSPP_SCALER_VER(1, 2)); static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { .rot_maxheight = 1088, @@ -317,107 +310,82 @@ static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { }; static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = - _VIG_SBLK(5, - SSPP_SCALER_VER(1, 3)); + _VIG_SBLK(SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = - _VIG_SBLK(6, - SSPP_SCALER_VER(1, 3)); + _VIG_SBLK(SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = - _VIG_SBLK(7, - SSPP_SCALER_VER(1, 3)); + _VIG_SBLK(SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = - _VIG_SBLK(8, - SSPP_SCALER_VER(1, 3)); + _VIG_SBLK(SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_0 = - _VIG_SBLK(5, - SSPP_SCALER_VER(1, 4)); + _VIG_SBLK(SSPP_SCALER_VER(1, 4)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_1 = - _VIG_SBLK(6, - SSPP_SCALER_VER(1, 4)); + _VIG_SBLK(SSPP_SCALER_VER(1, 4)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_2 = - _VIG_SBLK(7, - SSPP_SCALER_VER(1, 4)); +
[PATCH v7 03/10] drm/msm/dpu: Drop unused qseed_type from catalog dpu_caps
From: Marijn Suijten The SSPP scaler subblk is responsible for reporting its version (via the .id field, feature bits on the parent SSPP block, and since recently also from reading a register to supersede a read-but-unset version field in the catalog), leaving this global qseed_type field logically unused. Remove this dead code to lighten the catalog and bringup-overhead. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 -- 15 files changed, 16 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index aa1867943c9f..4dcc9f804ac1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -10,7 +10,6 @@ static const struct dpu_caps msm8998_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x7, - .qseed_type = DPU_SSPP_SCALER_QSEED3, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 38ac0c1a134b..03159d359500 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -10,7 +10,6 @@ static const struct dpu_caps sdm845_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, - .qseed_type = DPU_SSPP_SCALER_QSEED3, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index c022e57864a4..4184c18d81f3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -10,7 +10,6 @@ static const struct dpu_caps sm8150_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, - .qseed_type = DPU_SSPP_SCALER_QSEED3, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index efee84c8dba6..bd91dcc791d9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -10,7 +10,6 @@ static const struct dpu_caps sc8180x_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, - .qseed_type = DPU_SSPP_SCALER_QSEED3, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 94278a3e3483..885a2bec8258 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -10,7 +10,6 @@ static const struct dpu_caps sm8250_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, - .qseed_type = DPU_SSPP_SCALER_QSEED4, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index c0d88ddccb28..c9d1f1292b3d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -10,7 +10,6 @@ static const struct dpu_caps sc7180_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x9, - .qseed_type = DPU_SSPP_SCALER_QSEED4, .has_dim_layer = true,
[PATCH v7 04/10] drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO
The field `id' is not used for subblocks. The handling code usually knows, which sub-block it is now looking at. Drop the field completely. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 76 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 - 2 files changed, 36 insertions(+), 42 deletions(-) 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 7056c08b9957..eb9dfdcf610e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -252,17 +252,15 @@ static const uint32_t wb2_formats[] = { #define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min)) /* SSPP common configuration */ -#define _VIG_SBLK(sdma_pri, qseed_ver, scaler_ver) \ +#define _VIG_SBLK(sdma_pri, scaler_ver) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = "scaler", \ - .id = qseed_ver, \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = {.name = "csc", \ - .id = DPU_SSPP_CSC_10BIT, \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ @@ -271,17 +269,15 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = NULL, \ } -#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, scaler_ver, rot_cfg) \ +#define _VIG_SBLK_ROT(sdma_pri, scaler_ver, rot_cfg) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = "scaler", \ - .id = qseed_ver, \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = {.name = "csc", \ - .id = DPU_SSPP_CSC_10BIT, \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ @@ -302,16 +298,16 @@ static const uint32_t wb2_formats[] = { } static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(0, SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(0, SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(0, SSPP_SCALER_VER(1, 2)); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(0, SSPP_SCALER_VER(1, 2)); static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { @@ -321,29 +317,29 @@ static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { }; static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = - _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(5, SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = - _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(6, SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = - _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(7, SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = - _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(8, SSPP_SCALER_VER(1, 3)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_0 = - _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(5, SSPP_SCALER_VER(1, 4)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_1 = - _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3, + _VIG_SBLK(6, SSPP_SCALER_VER(1, 4)); static const struct dpu_sspp_sub_blks sm8150_vig_sblk_2 = - _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3, +
[PATCH v7 01/10] drm/msm/dpu: populate SSPP scaler block version
The function _dpu_hw_sspp_setup_scaler3() passes and dpu_hw_setup_scaler3() uses scaler_blk.version to determine in which way the scaler (QSEED3) block should be programmed. However up to now we were not setting this field. Set it now, splitting the vig_sblk data which has different version fields. Reported-by: Marijn Suijten Fixes: 9b6f4fedaac2 ("drm/msm/dpu: Add SM6125 support") Fixes: 27f0df03f3ff ("drm/msm/dpu: Add SM6375 support") Fixes: 3186acba5cdc ("drm/msm/dpu: Add SM6350 support") Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550") Fixes: 4a352c2fc15a ("drm/msm/dpu: Introduce SC8280XP") Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog") Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450") Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115") Fixes: dabfdd89eaa9 ("drm/msm/disp/dpu1: add inline rotation support for sc7280") Fixes: f3af2d6ee9ab ("drm/msm/dpu: Add SC8180x to hw catalog") Fixes: 94391a14fc27 ("drm/msm/dpu1: Add MSM8998 to hw catalog") Fixes: af776a3e1c30 ("drm/msm/dpu: add SM8250 to hw catalog") Fixes: 386fced3f76f ("drm/msm/dpu: add SM8150 to hw catalog") Fixes: b75ab05a3479 ("msm:disp:dpu1: add scaler support on SC7180 display") Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 8 +- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 8 +- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 8 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 95 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 3 +- 5 files changed, 87 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 9392ad2b4d3f..c022e57864a4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_0, + .sblk = _vig_sblk_0, .xin_id = 0, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG0, @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_1, + .sblk = _vig_sblk_1, .xin_id = 4, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG1, @@ -93,7 +93,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_2, + .sblk = _vig_sblk_2, .xin_id = 8, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG2, @@ -101,7 +101,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_3, + .sblk = _vig_sblk_3, .xin_id = 12, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG3, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index e07f4c8c25b9..efee84c8dba6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -76,7 +76,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_0, + .sblk = _vig_sblk_0, .xin_id = 0, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG0, @@ -84,7 +84,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_1, + .sblk = _vig_sblk_1, .xin_id = 4, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG1, @@ -92,7 +92,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1f0, .features = VIG_SDM845_MASK, - .sblk = _vig_sblk_2, + .sblk = _vig_sblk_2, .xin_id = 8, .type =
[PATCH v7 00/10] drm/msm/dpu: simplify DPU sub-blocks info
The handling code also usually knows, which sub-block it is now looking at. Drop unused 'id' field and arguments and merge some of sub-block declarations. While we are at it, also fix all VIG subblocks to contain correct scaler block version and drop the becoming unused QSEED-related feature bits. Changes since v6: - Renamed the merged DPU_SSPP_SCALER_QSEED3 to DPU_SSPP_SCALER_QSEED3_COMPATIBLE (Abhinav) Changes since v5: - Fixed the rogue vig_qseed3_noscale sblk. There is no qseed3 in the noscale VIG blocks. Changes since v4: - Renamed dpu_vig_sblk_x_y to dpu_vig_sblk_qseed3_1_2 (Abhinav) Note: I've choosen _qseed3_ instead of the suggested _scaler_, as there are other scaler types which might have their own versioning scheme - Dropped the DPU_SSPP_SCALER and DPU_SSPP_CSC_ANY defines (Abhinav) Changes since v3: - Proprely describe dpu_scaler_blk::version field as the register value (Marijn) - Picked up Marijn's prior art patches (sorry, missed them while preparing v3) (Marijn) Changes since v2: - Reworked the VIG SBLK definitions to set the scaler version (Marijn, Abhinav) - Rebased the reset of the patches on top of this (intrusive) change. - Folded QSEED3LITE and QSEED4 feature bits into QSEED3 Dmitry Baryshkov (8): drm/msm/dpu: populate SSPP scaler block version drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO drm/msm/dpu: drop the `smart_dma_priority' field from struct dpu_sspp_sub_blks drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro drm/msm/dpu: rewrite scaler and CSC presense checks drm/msm/dpu: merge DPU_SSPP_SCALER_QSEED3, QSEED3LITE, QSEED4 drm/msm/gpu: drop duplicating VIG feature masks Marijn Suijten (2): drm/msm/dpu: Drop unused get_scaler_ver callback from SSPP drm/msm/dpu: Drop unused qseed_type from catalog dpu_caps .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 17 +- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 17 +- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 17 +- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 17 +- .../msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 8 +- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 25 ++- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 11 +- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 7 +- .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 11 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 4 +- .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 7 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 25 ++- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 9 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 25 ++- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 25 ++- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 29 ++-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 149 +++--- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 57 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 20 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 21 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 6 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 3 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 7 +- 23 files changed, 204 insertions(+), 313 deletions(-) -- 2.42.0
Re: [PATCH 1/6] Revert "drm/prime: Unexport helpers for fd/handle conversion"
Hi Alex, I'm about to push patches 1-3 to the rebased amd-staging-drm-next. It would be good to get patch 1 into drm-fixes so that Linux 6.6 will be the only kernel without these prime helpers. That would minimize the hassle for DKMS driver installations on future distros. Thanks, Felix On 2023-12-01 18:34, Felix Kuehling wrote: This reverts commit 71a7974ac7019afeec105a54447ae1dc7216cbb3. These helper functions are needed for KFD to export and import DMABufs the right way without duplicating the tracking of DMABufs associated with GEM objects while ensuring that move notifier callbacks are working as intended. Acked-by: Christian König Acked-by: Thomas Zimmermann Acked-by: Daniel Vetter Signed-off-by: Felix Kuehling --- drivers/gpu/drm/drm_prime.c | 33 ++--- include/drm/drm_prime.h | 7 +++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 63b709a67471..834a5e28abbe 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -278,7 +278,7 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) } EXPORT_SYMBOL(drm_gem_dmabuf_release); -/* +/** * drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers * @dev: drm_device to import into * @file_priv: drm file-private structure @@ -292,9 +292,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release); * * Returns 0 on success or a negative error code on failure. */ -static int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, - uint32_t *handle) +int drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, + uint32_t *handle) { struct dma_buf *dma_buf; struct drm_gem_object *obj; @@ -360,6 +360,7 @@ static int drm_gem_prime_fd_to_handle(struct drm_device *dev, dma_buf_put(dma_buf); return ret; } +EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -408,7 +409,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, return dmabuf; } -/* +/** * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers * @dev: dev to export the buffer from * @file_priv: drm file-private structure @@ -421,10 +422,10 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, * The actual exporting from GEM object to a dma-buf is done through the * _gem_object_funcs.export callback. */ -static int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, - uint32_t flags, - int *prime_fd) +int drm_gem_prime_handle_to_fd(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, + uint32_t flags, + int *prime_fd) { struct drm_gem_object *obj; int ret = 0; @@ -506,6 +507,7 @@ static int drm_gem_prime_handle_to_fd(struct drm_device *dev, return ret; } +EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -864,9 +866,9 @@ EXPORT_SYMBOL(drm_prime_get_contiguous_size); * @obj: GEM object to export * @flags: flags like DRM_CLOEXEC and DRM_RDWR * - * This is the implementation of the _gem_object_funcs.export functions - * for GEM drivers using the PRIME helpers. It is used as the default for - * drivers that do not set their own. + * This is the implementation of the _gem_object_funcs.export functions for GEM drivers + * using the PRIME helpers. It is used as the default in + * drm_gem_prime_handle_to_fd(). */ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, int flags) @@ -962,9 +964,10 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev); * @dev: drm_device to import into * @dma_buf: dma-buf object to import * - * This is the implementation of the gem_prime_import functions for GEM - * drivers using the PRIME helpers. It is the default for drivers that do - * not set their own _driver.gem_prime_import. + * This is the implementation of the gem_prime_import functions for GEM drivers + * using the PRIME helpers. Drivers can use this as their + * _driver.gem_prime_import implementation. It is used as the default + * implementation in drm_gem_prime_fd_to_handle(). * * Drivers must arrange to call drm_prime_gem_destroy() from their * _gem_object_funcs.free hook when using this function. diff
[PATCH 3/6] drm/amdkfd: Import DMABufs for interop through DRM
Use drm_gem_prime_fd_to_handle to import DMABufs for interop. This ensures that a GEM handle is created on import and that obj->dma_buf will be set and remain set as long as the object is imported into KFD. Signed-off-by: Felix Kuehling Reviewed-by: Ramesh Errabolu Reviewed-by: Xiaogang.Chen Acked-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h| 9 ++- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 64 +-- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 15 ++--- 3 files changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 02973f5c8caf..cf6ed5fce291 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -314,11 +314,10 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info, struct dma_fence **ef); int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev, struct kfd_vm_fault_info *info); -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, - struct dma_buf *dmabuf, - uint64_t va, void *drm_priv, - struct kgd_mem **mem, uint64_t *size, - uint64_t *mmap_offset); +int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd, +uint64_t va, void *drm_priv, +struct kgd_mem **mem, uint64_t *size, +uint64_t *mmap_offset); int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem, struct dma_buf **dmabuf); void amdgpu_amdkfd_debug_mem_fence(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index ae7dfaf59159..48697b789342 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1956,8 +1956,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( /* Free the BO*/ drm_vma_node_revoke(>bo->tbo.base.vma_node, drm_priv); - if (!mem->is_imported) - drm_gem_handle_delete(adev->kfd.client.file, mem->gem_handle); + drm_gem_handle_delete(adev->kfd.client.file, mem->gem_handle); if (mem->dmabuf) { dma_buf_put(mem->dmabuf); mem->dmabuf = NULL; @@ -2313,34 +2312,26 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev, return 0; } -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, - struct dma_buf *dma_buf, - uint64_t va, void *drm_priv, - struct kgd_mem **mem, uint64_t *size, - uint64_t *mmap_offset) +static int import_obj_create(struct amdgpu_device *adev, +struct dma_buf *dma_buf, +struct drm_gem_object *obj, +uint64_t va, void *drm_priv, +struct kgd_mem **mem, uint64_t *size, +uint64_t *mmap_offset) { struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); - struct drm_gem_object *obj; struct amdgpu_bo *bo; int ret; - obj = amdgpu_gem_prime_import(adev_to_drm(adev), dma_buf); - if (IS_ERR(obj)) - return PTR_ERR(obj); - bo = gem_to_amdgpu_bo(obj); if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM | - AMDGPU_GEM_DOMAIN_GTT))) { + AMDGPU_GEM_DOMAIN_GTT))) /* Only VRAM and GTT BOs are supported */ - ret = -EINVAL; - goto err_put_obj; - } + return -EINVAL; *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); - if (!*mem) { - ret = -ENOMEM; - goto err_put_obj; - } + if (!*mem) + return -ENOMEM; ret = drm_vma_node_allow(>vma_node, drm_priv); if (ret) @@ -2390,8 +2381,41 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, drm_vma_node_revoke(>vma_node, drm_priv); err_free_mem: kfree(*mem); + return ret; +} + +int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd, +uint64_t va, void *drm_priv, +struct kgd_mem **mem, uint64_t *size, +uint64_t *mmap_offset) +{ + struct drm_gem_object *obj; + uint32_t handle; + int ret; + + ret =
[PATCH 2/6] drm/amdkfd: Export DMABufs from KFD using GEM handles
Create GEM handles for exporting DMABufs using GEM-Prime APIs. The GEM handles are created in a drm_client_dev context to avoid exposing them in user mode contexts through a DMABuf import. Signed-off-by: Felix Kuehling Reviewed-by: Ramesh Errabolu --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c| 11 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h| 5 +++ .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 33 +++ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 4 +-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 2d22f7d45512..067690ba7bff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -142,6 +142,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) { int i; int last_valid_bit; + int ret; amdgpu_amdkfd_gpuvm_init_mem_limits(); @@ -160,6 +161,12 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) .enable_mes = adev->enable_mes, }; + ret = drm_client_init(>ddev, >kfd.client, "kfd", NULL); + if (ret) { + dev_err(adev->dev, "Failed to init DRM client: %d\n", ret); + return; + } + /* this is going to have a few of the MSBs set that we need to * clear */ @@ -198,6 +205,10 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev, _resources); + if (adev->kfd.init_complete) + drm_client_register(>kfd.client); + else + drm_client_release(>kfd.client); amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 16794c2eea35..02973f5c8caf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -33,6 +33,7 @@ #include #include #include +#include #include "amdgpu_sync.h" #include "amdgpu_vm.h" #include "amdgpu_xcp.h" @@ -83,6 +84,7 @@ struct kgd_mem { struct amdgpu_sync sync; + uint32_t gem_handle; bool aql_queue; bool is_imported; }; @@ -105,6 +107,9 @@ struct amdgpu_kfd_dev { /* HMM page migration MEMORY_DEVICE_PRIVATE mapping */ struct dev_pagemap pgmap; + + /* Client for KFD BO GEM handle allocations */ + struct drm_client_dev client; }; enum kgd_engine_type { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 73288f9ccaf8..ae7dfaf59159 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -806,13 +807,22 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem, static int kfd_mem_export_dmabuf(struct kgd_mem *mem) { if (!mem->dmabuf) { - struct dma_buf *ret = amdgpu_gem_prime_export( - >bo->tbo.base, + struct amdgpu_device *bo_adev; + struct dma_buf *dmabuf; + int r, fd; + + bo_adev = amdgpu_ttm_adev(mem->bo->tbo.bdev); + r = drm_gem_prime_handle_to_fd(_adev->ddev, bo_adev->kfd.client.file, + mem->gem_handle, mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ? - DRM_RDWR : 0); - if (IS_ERR(ret)) - return PTR_ERR(ret); - mem->dmabuf = ret; + DRM_RDWR : 0, ); + if (r) + return r; + dmabuf = dma_buf_get(fd); + close_fd(fd); + if (WARN_ON_ONCE(IS_ERR(dmabuf))) + return PTR_ERR(dmabuf); + mem->dmabuf = dmabuf; } return 0; @@ -1778,6 +1788,9 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( pr_debug("Failed to allow vma node access. ret %d\n", ret); goto err_node_allow; } + ret = drm_gem_handle_create(adev->kfd.client.file, gobj, &(*mem)->gem_handle); + if (ret) + goto err_gem_handle_create; bo = gem_to_amdgpu_bo(gobj); if (bo_type == ttm_bo_type_sg) { bo->tbo.sg = sg; @@ -1829,6 +1842,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( err_pin_bo: err_validate_bo: remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); + drm_gem_handle_delete(adev->kfd.client.file,
[PATCH 5/6] drm/amdgpu: Auto-validate DMABuf imports in compute VMs
DMABuf imports in compute VMs are not wrapped in a kgd_mem object on the process_info->kfd_bo_list. There is no explicit KFD API call to validate them or add eviction fences to them. This patch automatically validates and fences dymanic DMABuf imports when they are added to a compute VM. Revalidation after evictions is handled in the VM code. Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h| 3 + .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 45 --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 4 + drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 26 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c| 122 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h| 12 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 12 +- 8 files changed, 196 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index cf6ed5fce291..f2e920734c98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -182,6 +182,9 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev, struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context, struct mm_struct *mm, struct svm_range_bo *svm_bo); +int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo, + uint32_t domain, + struct dma_fence *fence); #if defined(CONFIG_DEBUG_FS) int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 48697b789342..7d91f99acb59 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -426,9 +426,9 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, return ret; } -static int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo, - uint32_t domain, - struct dma_fence *fence) +int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo, + uint32_t domain, + struct dma_fence *fence) { int ret = amdgpu_bo_reserve(bo, false); @@ -464,13 +464,16 @@ static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) * again. Page directories are only updated after updating page * tables. */ -static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm) +static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm, +struct ww_acquire_ctx *ticket) { struct amdgpu_bo *pd = vm->root.bo; struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev); int ret; - ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate_vm_bo, NULL); + ret = amdgpu_vm_validate_evicted_bos(adev, vm, ticket, +amdgpu_amdkfd_validate_vm_bo, +NULL); if (ret) { pr_err("failed to validate PT BOs\n"); return ret; @@ -1310,14 +1313,15 @@ static int map_bo_to_gpuvm(struct kgd_mem *mem, return ret; } -static int process_validate_vms(struct amdkfd_process_info *process_info) +static int process_validate_vms(struct amdkfd_process_info *process_info, + struct ww_acquire_ctx *ticket) { struct amdgpu_vm *peer_vm; int ret; list_for_each_entry(peer_vm, _info->vm_list_head, vm_list_node) { - ret = vm_validate_pt_pd_bos(peer_vm); + ret = vm_validate_pt_pd_bos(peer_vm, ticket); if (ret) return ret; } @@ -1402,7 +1406,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, ret = amdgpu_bo_reserve(vm->root.bo, true); if (ret) goto reserve_pd_fail; - ret = vm_validate_pt_pd_bos(vm); + ret = vm_validate_pt_pd_bos(vm, NULL); if (ret) { pr_err("validate_pt_pd_bos() failed\n"); goto validate_pd_fail; @@ -2043,7 +2047,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( bo->tbo.resource->mem_type == TTM_PL_SYSTEM) is_invalid_userptr = true; - ret = vm_validate_pt_pd_bos(avm); + ret = vm_validate_pt_pd_bos(avm, NULL); if (unlikely(ret)) goto out_unreserve; @@ -2122,7 +2126,7 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( goto unreserve_out; } - ret = vm_validate_pt_pd_bos(avm); + ret = vm_validate_pt_pd_bos(avm,
[PATCH 6/6] drm/amdkfd: Bump KFD ioctl version
This is not strictly a change in the IOCTL API. This version bump is meant to indicate to user mode the presence of a number of changes and fixes that enable the management of VA mappings in compute VMs using the GEM_VA ioctl for DMABufs exported from KFD. Signed-off-by: Felix Kuehling --- include/uapi/linux/kfd_ioctl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index f0ed68974c54..9ce46edc62a5 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -40,9 +40,10 @@ * - 1.12 - Add DMA buf export ioctl * - 1.13 - Add debugger API * - 1.14 - Update kfd_event_data + * - 1.15 - Enable managing mappings in compute VMs with GEM_VA ioctl */ #define KFD_IOCTL_MAJOR_VERSION 1 -#define KFD_IOCTL_MINOR_VERSION 14 +#define KFD_IOCTL_MINOR_VERSION 15 struct kfd_ioctl_get_version_args { __u32 major_version;/* from KFD */ -- 2.34.1
[PATCH 4/6] drm/amdgpu: New VM state for evicted user BOs
Create a new VM state to track user BOs that are in the system domain. In the next patch this will be used do conditionally re-validate them in amdgpu_vm_handle_moved. Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 5 - 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 7da71b6a9dc6..a748e17ff031 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -233,6 +233,22 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo) spin_unlock(_bo->vm->status_lock); } +/** + * amdgpu_vm_bo_evicted_user - vm_bo is evicted + * + * @vm_bo: vm_bo which is evicted + * + * State for BOs used by user mode queues which are not at the location they + * should be. + */ +static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo) +{ + vm_bo->moved = true; + spin_lock(_bo->vm->status_lock); + list_move(_bo->vm_status, _bo->vm->evicted_user); + spin_unlock(_bo->vm->status_lock); +} + /** * amdgpu_vm_bo_relocated - vm_bo is reloacted * @@ -2195,6 +2211,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) vm->reserved_vmid[i] = NULL; INIT_LIST_HEAD(>evicted); + INIT_LIST_HEAD(>evicted_user); INIT_LIST_HEAD(>relocated); INIT_LIST_HEAD(>moved); INIT_LIST_HEAD(>idle); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index b6cd565562ad..9156ed22abe7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -288,9 +288,12 @@ struct amdgpu_vm { /* Lock to protect vm_bo add/del/move on all lists of vm */ spinlock_t status_lock; - /* BOs who needs a validation */ + /* Per VM and PT BOs who needs a validation */ struct list_headevicted; + /* BOs for user mode queues that need a validation */ + struct list_headevicted_user; + /* PT BOs which relocated and their parent need an update */ struct list_headrelocated; -- 2.34.1
[PATCH 1/6] Revert "drm/prime: Unexport helpers for fd/handle conversion"
This reverts commit 71a7974ac7019afeec105a54447ae1dc7216cbb3. These helper functions are needed for KFD to export and import DMABufs the right way without duplicating the tracking of DMABufs associated with GEM objects while ensuring that move notifier callbacks are working as intended. Acked-by: Christian König Acked-by: Thomas Zimmermann Acked-by: Daniel Vetter Signed-off-by: Felix Kuehling --- drivers/gpu/drm/drm_prime.c | 33 ++--- include/drm/drm_prime.h | 7 +++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 63b709a67471..834a5e28abbe 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -278,7 +278,7 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) } EXPORT_SYMBOL(drm_gem_dmabuf_release); -/* +/** * drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers * @dev: drm_device to import into * @file_priv: drm file-private structure @@ -292,9 +292,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release); * * Returns 0 on success or a negative error code on failure. */ -static int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, - uint32_t *handle) +int drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, + uint32_t *handle) { struct dma_buf *dma_buf; struct drm_gem_object *obj; @@ -360,6 +360,7 @@ static int drm_gem_prime_fd_to_handle(struct drm_device *dev, dma_buf_put(dma_buf); return ret; } +EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -408,7 +409,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, return dmabuf; } -/* +/** * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers * @dev: dev to export the buffer from * @file_priv: drm file-private structure @@ -421,10 +422,10 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, * The actual exporting from GEM object to a dma-buf is done through the * _gem_object_funcs.export callback. */ -static int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, - uint32_t flags, - int *prime_fd) +int drm_gem_prime_handle_to_fd(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, + uint32_t flags, + int *prime_fd) { struct drm_gem_object *obj; int ret = 0; @@ -506,6 +507,7 @@ static int drm_gem_prime_handle_to_fd(struct drm_device *dev, return ret; } +EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -864,9 +866,9 @@ EXPORT_SYMBOL(drm_prime_get_contiguous_size); * @obj: GEM object to export * @flags: flags like DRM_CLOEXEC and DRM_RDWR * - * This is the implementation of the _gem_object_funcs.export functions - * for GEM drivers using the PRIME helpers. It is used as the default for - * drivers that do not set their own. + * This is the implementation of the _gem_object_funcs.export functions for GEM drivers + * using the PRIME helpers. It is used as the default in + * drm_gem_prime_handle_to_fd(). */ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, int flags) @@ -962,9 +964,10 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev); * @dev: drm_device to import into * @dma_buf: dma-buf object to import * - * This is the implementation of the gem_prime_import functions for GEM - * drivers using the PRIME helpers. It is the default for drivers that do - * not set their own _driver.gem_prime_import. + * This is the implementation of the gem_prime_import functions for GEM drivers + * using the PRIME helpers. Drivers can use this as their + * _driver.gem_prime_import implementation. It is used as the default + * implementation in drm_gem_prime_fd_to_handle(). * * Drivers must arrange to call drm_prime_gem_destroy() from their * _gem_object_funcs.free hook when using this function. diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index a7abf9f3e697..2a1d01e5b56b 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -60,12 +60,19 @@ enum dma_data_direction; struct drm_device; struct drm_gem_object; +struct drm_file; /* core prime functions */ struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
Re: [git pull] drm fixes for 6.7-rc4
The pull request you sent on Fri, 1 Dec 2023 16:41:39 +1000: > git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2023-12-01 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/b1e51588aa50287c3d33e14969d47ccdd403ad80 Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
Re: [PATCH 11/17] drm/msm/mdp4: use bulk regulators API for LCDC encoder
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Switch mdp4_lcdc_encoder to using regulator_bulk_* API instead of enumerating regulators by hand. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 51 ++- 1 file changed, 15 insertions(+), 36 deletions(-) Reviewed-by: Abhinav Kumar
[PATCH v2 5/6] drm/vmwgfx: Use vmware_hypercall API
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API. Eliminate arch specific code. drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant of vmware_hypercall here for now. The move of these functions to arch/arm64/include/asm/vmware.h as well as removal of drivers/gpu/drm/vmwgfx/vmwgfx_msg_{x86,arm64}.h header files will be performed in the follow up patchset. Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit Reviewed-by: Zack Rusin --- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 173 +++ drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h | 185 3 files changed, 197 insertions(+), 358 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 2651fe0ef518..1f15990d3934 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -48,8 +48,6 @@ #define RETRIES 3 -#define VMW_HYPERVISOR_MAGIC0x564D5868 - #define VMW_PORT_CMD_MSG30 #define VMW_PORT_CMD_HB_MSG 0 #define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG) @@ -104,20 +102,18 @@ static const char* const mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] = */ static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol) { - unsigned long eax, ebx, ecx, edx, si = 0, di = 0; + u32 ecx, edx, esi, edi; - VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL, - (protocol | GUESTMSG_FLAG_COOKIE), si, di, - 0, - VMW_HYPERVISOR_MAGIC, - eax, ebx, ecx, edx, si, di); + vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL, + (protocol | GUESTMSG_FLAG_COOKIE), 0, + , , , ); if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) return -EINVAL; channel->channel_id = HIGH_WORD(edx); - channel->cookie_high = si; - channel->cookie_low = di; + channel->cookie_high = esi; + channel->cookie_low = edi; return 0; } @@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol) */ static int vmw_close_channel(struct rpc_channel *channel) { - unsigned long eax, ebx, ecx, edx, si, di; - - /* Set up additional parameters */ - si = channel->cookie_high; - di = channel->cookie_low; + u32 ecx; - VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL, - 0, si, di, - channel->channel_id << 16, - VMW_HYPERVISOR_MAGIC, - eax, ebx, ecx, edx, si, di); + vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL, + 0, channel->channel_id << 16, + channel->cookie_high, + channel->cookie_low, + ); if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) return -EINVAL; @@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel) static unsigned long vmw_port_hb_out(struct rpc_channel *channel, const char *msg, bool hb) { - unsigned long si, di, eax, ebx, ecx, edx; + u32 ebx, ecx; unsigned long msg_len = strlen(msg); /* HB port can't access encrypted memory. */ if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) { - unsigned long bp = channel->cookie_high; - u32 channel_id = (channel->channel_id << 16); - - si = (uintptr_t) msg; - di = channel->cookie_low; - - VMW_PORT_HB_OUT( + vmware_hypercall_hb_out( (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, - msg_len, si, di, - VMWARE_HYPERVISOR_HB | channel_id | - VMWARE_HYPERVISOR_OUT, - VMW_HYPERVISOR_MAGIC, bp, - eax, ebx, ecx, edx, si, di); + msg_len, + channel->channel_id << 16, + (uintptr_t) msg, channel->cookie_low, + channel->cookie_high, + ); return ebx; } @@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel, memcpy(, msg, bytes); msg_len -= bytes; msg += bytes; - si = channel->cookie_high; - di = channel->cookie_low; - - VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16), -word, si, di, -channel->channel_id << 16, -VMW_HYPERVISOR_MAGIC, -eax, ebx, ecx, edx, si, di); + + vmware_hypercall5(VMW_PORT_CMD_MSG | + (MSG_TYPE_SENDPAYLOAD << 16), +
[PATCH v2 2/6] x86/vmware: Introduce vmware_hypercall API
Introducing vmware_hypercall family of functions as a common implementation to be used by the VMware guest code and virtual device drivers in architecture independent manner. By analogy with KVM hypercall API, vmware_hypercallX and vmware_hypercall_hb_{out,in} set of functions was added to achieve that. Architecture specific implementation should be hidden inside. It will simplify future enhancements in VMware hypercalls such as SEV-ES and TDX related changes without needs to modify a caller in device drivers code. Current implementation extends an idea from commit bac7b4e84323 ("x86/vmware: Update platform detection code for VMCALL/VMMCALL hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL earlier during the boot when alternatives are not yet applied. This logic was inherited from VMWARE_CMD from the commit mentioned above. Default alternative code was optimized by size to reduce excessive nop alignment once alternatives are applied. Total default code size is 26 bytes, in worse case (3 bytes alternative) remaining 23 bytes will be aligned by only 3 long NOP instructions. Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit Reviewed-by: Jeff Sipek --- arch/x86/include/asm/vmware.h | 262 ++ arch/x86/kernel/cpu/vmware.c | 35 ++--- 2 files changed, 220 insertions(+), 77 deletions(-) diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index 8cabf4a577bf..17091eba68cb 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h @@ -40,69 +40,219 @@ extern u8 vmware_hypercall_mode; -/* The low bandwidth call. The low word of edx is presumed clear. */ -#define VMWARE_HYPERCALL \ - ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \ - "inl (%%dx), %%eax", \ - "vmcall", X86_FEATURE_VMCALL, \ - "vmmcall", X86_FEATURE_VMW_VMMCALL) - /* - * The high bandwidth out call. The low word of edx is presumed to have the - * HB and OUT bits set. + * The low bandwidth call. The low word of edx is presumed to have OUT bit + * set. The high word of edx may contain input data from the caller. */ -#define VMWARE_HYPERCALL_HB_OUT \ - ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \ - "rep outsb", \ +#define VMWARE_HYPERCALL \ + ALTERNATIVE_3("cmpb $" \ + __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL) \ + ", %[mode]\n\t" \ + "jg 2f\n\t" \ + "je 1f\n\t" \ + "movw %[port], %%dx\n\t" \ + "inl (%%dx), %%eax\n\t" \ + "jmp 3f\n\t" \ + "1: vmmcall\n\t" \ + "jmp 3f\n\t" \ + "2: vmcall\n\t" \ + "3:\n\t", \ + "movw %[port], %%dx\n\t" \ + "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR, \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) +static inline +unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1) +{ + unsigned long out0; + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + [mode] "m" (vmware_hypercall_mode), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (0) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1, + uint32_t *out1, uint32_t *out2) +{ + unsigned long out0; + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=b" (*out1), "=c" (*out2) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + [mode] "m" (vmware_hypercall_mode), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (0) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1, + uint32_t
[PATCH v2 4/6] input/vmmouse: Use vmware_hypercall API
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API. Eliminate arch specific code. No functional changes intended. Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit Reviewed-by: Zack Rusin Acked-by: Dmitry Torokhov --- drivers/input/mouse/vmmouse.c | 76 ++- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c index ea9eff7c8099..fb1d986a6895 100644 --- a/drivers/input/mouse/vmmouse.c +++ b/drivers/input/mouse/vmmouse.c @@ -21,19 +21,16 @@ #include "psmouse.h" #include "vmmouse.h" -#define VMMOUSE_PROTO_MAGIC0x564D5868U - /* * Main commands supported by the vmmouse hypervisor port. */ -#define VMMOUSE_PROTO_CMD_GETVERSION 10 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS40 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41 -#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86 +#define VMWARE_CMD_ABSPOINTER_DATA 39 +#define VMWARE_CMD_ABSPOINTER_STATUS 40 +#define VMWARE_CMD_ABSPOINTER_COMMAND 41 +#define VMWARE_CMD_ABSPOINTER_RESTRICT 86 /* - * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND + * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND */ #define VMMOUSE_CMD_ENABLE 0x45414552U #define VMMOUSE_CMD_DISABLE0x00f5U @@ -76,28 +73,6 @@ struct vmmouse_data { char dev_name[128]; }; -/* - * Hypervisor-specific bi-directional communication channel - * implementing the vmmouse protocol. Should never execute on - * bare metal hardware. - */ -#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ -({ \ - unsigned long __dummy1, __dummy2; \ - __asm__ __volatile__ (VMWARE_HYPERCALL :\ - "=a"(out1), \ - "=b"(out2), \ - "=c"(out3), \ - "=d"(out4), \ - "=S"(__dummy1), \ - "=D"(__dummy2) :\ - "a"(VMMOUSE_PROTO_MAGIC), \ - "b"(in1), \ - "c"(VMMOUSE_PROTO_CMD_##cmd), \ - "d"(0) :\ - "memory"); \ -}) - /** * vmmouse_report_button - report button state on the correct input device * @@ -145,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse) struct input_dev *abs_dev = priv->abs_dev; struct input_dev *pref_dev; u32 status, x, y, z; - u32 dummy1, dummy2, dummy3; unsigned int queue_length; unsigned int count = 255; while (count--) { /* See if we have motion data. */ - VMMOUSE_CMD(ABSPOINTER_STATUS, 0, - status, dummy1, dummy2, dummy3); + status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0); if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) { psmouse_err(psmouse, "failed to fetch status data\n"); /* @@ -172,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse) } /* Now get it */ - VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z); + status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4, + , , ); /* * And report what we've got. Prefer to report button @@ -247,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse) static void vmmouse_disable(struct psmouse *psmouse) { u32 status; - u32 dummy1, dummy2, dummy3, dummy4; - - VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE, - dummy1, dummy2, dummy3, dummy4); - VMMOUSE_CMD(ABSPOINTER_STATUS, 0, - status, dummy1, dummy2, dummy3); + vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE); + status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0); if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR) psmouse_warn(psmouse, "failed to disable vmmouse device\n"); } @@ -271,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse) static int vmmouse_enable(struct psmouse *psmouse) { u32 status, version; - u32 dummy1, dummy2, dummy3, dummy4; /* * Try enabling the device. If successful, we should be able to * read valid version ID back from it. */ - VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE, - dummy1, dummy2, dummy3, dummy4); +
[PATCH v2 6/6] x86/vmware: Add TDX hypercall support
VMware hypercalls use I/O port, VMCALL or VMMCALL instructions. Add __tdx_hypercall path to support TDX guests. No change in high bandwidth hypercalls, as only low bandwidth ones are supported for TDX guests. Co-developed-by: Tim Merrifield Signed-off-by: Tim Merrifield Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit --- arch/x86/include/asm/vmware.h | 72 +++ arch/x86/kernel/cpu/vmware.c | 9 + 2 files changed, 81 insertions(+) diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index 17091eba68cb..cd58ff8ef1af 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h @@ -40,6 +40,54 @@ extern u8 vmware_hypercall_mode; +#define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL +#define VMWARE_TDX_HCALL_FUNC 1 + +extern void vmware_tdx_hypercall_args(struct tdx_module_args *args); + +/* + * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of + * rbp (arg6) is discouraged by the TDX specification. Therefore, we + * remap those registers to r12, r13 and r14, respectively. + */ +static inline +unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1, + unsigned long in3, unsigned long in4, + unsigned long in5, unsigned long in6, + uint32_t *out1, uint32_t *out2, + uint32_t *out3, uint32_t *out4, + uint32_t *out5, uint32_t *out6) +{ + struct tdx_module_args args = { + .r10 = VMWARE_TDX_VENDOR_LEAF, + .r11 = VMWARE_TDX_HCALL_FUNC, + .r12 = VMWARE_HYPERVISOR_MAGIC, + .r13 = cmd, + .rbx = in1, + .rdx = in3, + .rsi = in4, + .rdi = in5, + .r14 = in6, + }; + + vmware_tdx_hypercall_args(); + + if (out1) + *out1 = args.rbx; + if (out2) + *out2 = args.r13; + if (out3) + *out3 = args.rdx; + if (out4) + *out4 = args.rsi; + if (out5) + *out5 = args.rdi; + if (out6) + *out6 = args.r14; + + return args.r12; +} + /* * The low bandwidth call. The low word of edx is presumed to have OUT bit * set. The high word of edx may contain input data from the caller. @@ -67,6 +115,10 @@ unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1) { unsigned long out0; + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, NULL, NULL, + NULL, NULL, NULL, NULL); + asm_inline volatile (VMWARE_HYPERCALL : "=a" (out0) : [port] "i" (VMWARE_HYPERVISOR_PORT), @@ -85,6 +137,10 @@ unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1, { unsigned long out0; + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2, + NULL, NULL, NULL, NULL); + asm_inline volatile (VMWARE_HYPERCALL : "=a" (out0), "=b" (*out1), "=c" (*out2) : [port] "i" (VMWARE_HYPERVISOR_PORT), @@ -104,6 +160,10 @@ unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1, { unsigned long out0; + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2, + out3, NULL, NULL, NULL); + asm_inline volatile (VMWARE_HYPERCALL : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3) : [port] "i" (VMWARE_HYPERVISOR_PORT), @@ -123,6 +183,10 @@ unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1, { unsigned long out0; + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, 0, NULL, + out2, NULL, NULL, NULL, NULL); + asm_inline volatile (VMWARE_HYPERCALL : "=a" (out0), "=c" (*out2) : [port] "i" (VMWARE_HYPERVISOR_PORT), @@ -145,6 +209,10 @@ unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1, { unsigned long out0; + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, in3, 0, 0, 0, NULL, out2, + out3, out4, out5, NULL); + asm_inline volatile (VMWARE_HYPERCALL : "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4), "=D" (*out5) @@ -166,6 +234,10 @@ unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1, { unsigned long out0; + if
[PATCH v2 3/6] ptp/vmware: Use vmware_hypercall API
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API. Eliminate arch specific code. No functional changes intended. Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit Reviewed-by: Jeff Sipek --- drivers/ptp/ptp_vmw.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c index 27c5547aa8a9..e5bb521b9b82 100644 --- a/drivers/ptp/ptp_vmw.c +++ b/drivers/ptp/ptp_vmw.c @@ -14,7 +14,6 @@ #include #include -#define VMWARE_MAGIC 0x564D5868 #define VMWARE_CMD_PCLK(nr) ((nr << 16) | 97) #define VMWARE_CMD_PCLK_GETTIME VMWARE_CMD_PCLK(0) @@ -24,15 +23,10 @@ static struct ptp_clock *ptp_vmw_clock; static int ptp_vmw_pclk_read(u64 *ns) { - u32 ret, nsec_hi, nsec_lo, unused1, unused2, unused3; - - asm volatile (VMWARE_HYPERCALL : - "=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1), - "=S"(unused2), "=D"(unused3) : - "a"(VMWARE_MAGIC), "b"(0), - "c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) : - "memory"); + u32 ret, nsec_hi, nsec_lo; + ret = vmware_hypercall3(VMWARE_CMD_PCLK_GETTIME, 0, + _hi, _lo); if (ret == 0) *ns = ((u64)nsec_hi << 32) | nsec_lo; return ret; -- 2.39.0
[PATCH v2 0/6] VMware hypercalls enhancements
From: Alexey Makhalov VMware hypercalls invocations were all spread out across the kernel implementing same ABI as in-place asm-inline. With encrypted memory and confidential computing it became harder to maintain every changes in these hypercall implementations. Intention of this patchset is to introduce arch independent VMware hypercall API layer other subsystems such as device drivers can call to, while hiding architecture specific implementation behind. Second patch introduces the vmware_hypercall low and high bandwidth families of functions, with little enhancements there. Sixth patch adds tdx hypercall support arm64 implementation of vmware_hypercalls is in drivers/gpu/drm/ vmwgfx/vmwgfx_msg_arm64.h and going to be moved to arch/arm64 with a separate patchset with the introduction of VMware Linux guest support for arm64. No functional changes in drivers/input/mouse/vmmouse.c and drivers/ptp/ptp_vmw.c v1->v2 changes (no functional changes): - Improved commit message in patches 2 and 5. - Added Reviewed-by for all patches. - Added Ack from Dmitry Torokhov in patch 4. No fixes regarding reported by Simon Horman gcc error in this patch. x86 maintainers, please consider merging this patch set in your branch. Alexey Makhalov (6): x86/vmware: Move common macros to vmware.h x86/vmware: Introduce vmware_hypercall API ptp/vmware: Use vmware_hypercall API input/vmmouse: Use vmware_hypercall API drm/vmwgfx: Use vmware_hypercall API x86/vmware: Add TDX hypercall support arch/x86/include/asm/vmware.h | 327 -- arch/x86/kernel/cpu/vmware.c | 101 ++- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 173 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 + drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h | 185 drivers/input/mouse/vmmouse.c | 76 ++--- drivers/ptp/ptp_vmw.c | 12 +- 7 files changed, 551 insertions(+), 520 deletions(-) -- 2.39.0
[PATCH v2 1/6] x86/vmware: Move common macros to vmware.h
Move VMware hypercall macros to vmware.h as a preparation step for the next commit. No functional changes besides exporting vmware_hypercall_mode symbol. Signed-off-by: Alexey Makhalov Reviewed-by: Nadav Amit --- arch/x86/include/asm/vmware.h | 69 ++- arch/x86/kernel/cpu/vmware.c | 57 +++-- 2 files changed, 66 insertions(+), 60 deletions(-) diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index ac9fc51e2b18..8cabf4a577bf 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h @@ -8,25 +8,37 @@ /* * The hypercall definitions differ in the low word of the %edx argument - * in the following way: the old port base interface uses the port - * number to distinguish between high- and low bandwidth versions. + * in the following way: the old I/O port based interface uses the port + * number to distinguish between high- and low bandwidth versions, and + * uses IN/OUT instructions to define transfer direction. * * The new vmcall interface instead uses a set of flags to select * bandwidth mode and transfer direction. The flags should be loaded * into %dx by any user and are automatically replaced by the port - * number if the VMWARE_HYPERVISOR_PORT method is used. + * number if the I/O port method is used. * * In short, new driver code should strictly use the new definition of * %dx content. */ -/* Old port-based version */ -#define VMWARE_HYPERVISOR_PORT0x5658 -#define VMWARE_HYPERVISOR_PORT_HB 0x5659 +#define VMWARE_HYPERVISOR_HB BIT(0) +#define VMWARE_HYPERVISOR_OUT BIT(1) -/* Current vmcall / vmmcall version */ -#define VMWARE_HYPERVISOR_HB BIT(0) -#define VMWARE_HYPERVISOR_OUT BIT(1) +#define VMWARE_HYPERVISOR_PORT 0x5658 +#define VMWARE_HYPERVISOR_PORT_HB (VMWARE_HYPERVISOR_PORT | \ +VMWARE_HYPERVISOR_HB) + +#define VMWARE_HYPERVISOR_MAGIC0x564D5868U + +#define VMWARE_CMD_GETVERSION 10 +#define VMWARE_CMD_GETHZ 45 +#define VMWARE_CMD_GETVCPU_INFO68 +#define VMWARE_CMD_STEALCLOCK 91 + +#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0) +#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1) + +extern u8 vmware_hypercall_mode; /* The low bandwidth call. The low word of edx is presumed clear. */ #define VMWARE_HYPERCALL \ @@ -54,4 +66,43 @@ "rep insb", \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) + +#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ + __asm__("inl (%%dx), %%eax" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :\ + "memory") + +#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \ + __asm__("vmcall" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(0), "b"(UINT_MAX) : \ + "memory") + +#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \ + __asm__("vmmcall" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(0), "b"(UINT_MAX) : \ + "memory") + +#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \ + switch (vmware_hypercall_mode) {\ + case CPUID_VMWARE_FEATURES_ECX_VMCALL: \ + VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \ + break; \ + case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \ + VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);\ + break; \ + default:\ + VMWARE_PORT(cmd, eax, ebx, ecx, edx); \ + break; \ + } \ + } while (0) + #endif diff --git
Re: [PATCH 10/17] drm/msm/mdp5: use drmm-managed allocation for mdp5_plane
On 7/7/2023 6:04 PM, Dmitry Baryshkov wrote: Change struct mdp5_plane allocation to use drmm_plane_alloc(). This removes the need to perform any actions on plane destruction. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 40 -- 1 file changed, 6 insertions(+), 34 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH v9 0/3] dma-fence: Deadline awareness (uabi edition)
On Wed, 23 Aug 2023 14:54:53 -0700, Rob Clark wrote: > This is a re-post of the remaining patches from: > https://patchwork.freedesktop.org/series/114490/ > > Part of the hold-up of the remaining uabi patches was compositor > support, but now an MR for kwin exists: > > https://invent.kde.org/plasma/kwin/-/merge_requests/4358 > > [...] Applied to drm-misc-next, thanks! [1/3] drm/syncobj: Add deadline support for syncobj waits commit: 8570c27932e132d2663e8120311891deb2a853de [2/3] dma-buf/sync_file: Add SET_DEADLINE ioctl commit: 63ee44540205d993854f143a5ab1d7d9e63ffcf1 [3/3] dma-buf/sw_sync: Add fence deadline support commit: 70e67aaec2f4706df0006423eebca813b00f5840 Best regards, -- Dmitry Baryshkov
[PATCH v9 5/7] drm/msm/dp: incorporate pm_runtime framework into DP driver
Currently DP driver is executed independent of PM runtime framework. This leads msm eDP panel can not being detected by edp_panel driver during generic_edp_panel_probe() due to AUX DPCD read failed at edp panel driver. Incorporate PM runtime framework into DP driver so that host controller's power and clocks are enable/disable through PM runtime mechanism. Once PM runtime framework is incorporated into DP driver, waking up device from power up path is not necessary. Hence remove it. After incorporating pm_runtime framework into eDP/DP driver, dp_pm_suspend() to handle power off both DP phy and controller during suspend and dp_pm_resume() to handle power on both DP phy and controller during resume are not necessary. Therefore both dp_pm_suspend() and dp_pm_resume() are dropped and replace with dp_pm_runtime_suspend() and dp_pm_runtime_resume() respectively. Changes in v9: -- silent compiler warning message at dp_power_init() and dp_power_deinit() with W1 flag Changes in v7: -- add comments to dp_pm_runtime_resume() -- add comments to dp_bridge_hpd_enable() -- delete dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_notify() Changes in v6: -- delete dp_power_client_deinit(dp->power); -- remove if (!dp->dp_display.is_edp) condition checkout at plug_handle() -- remove if (!dp->dp_display.is_edp) condition checkout at unplug_handle() -- add IRQF_NO_AUTOEN to devm_request_irq() -- add enable_irq() and disable_irq() to pm_runtime_resume()/suspend() -- del dp->hpd_state = ST_DISCONNECTED from dp_bridge_hpd_disable() Changes in v5: -- remove pm_runtime_put_autosuspend feature, use pm_runtime_put_sync() -- squash add pm_runtime_force_suspend()/resume() patch into this patch Changes in v4: -- reworded commit text to explain why pm_framework is required for edp panel -- reworded commit text to explain autosuspend is choiced -- delete EV_POWER_PM_GET and PM_EV_POWER_PUT from changes #3 -- delete dp_display_pm_get() and dp_display_pm_Put() from changes #3 -- return value from pm_runtime_resume_and_get() directly -- check return value of devm_pm_runtime_enable() -- delete pm_runtime_xxx from dp_display_remove() -- drop dp_display_host_init() from EV_HPD_INIT_SETUP -- drop both dp_pm_prepare() and dp_pm_compete() from this change -- delete ST_SUSPENDED state -- rewording commit text to add more details regrading the purpose of this change Changes in v3: -- incorporate removing pm_runtime_xx() from dp_pwer.c to this patch -- use pm_runtime_resume_and_get() instead of pm_runtime_get() -- error checking pm_runtime_resume_and_get() return value -- add EV_POWER_PM_GET and PM_EV_POWER_PUT to handle HPD_GPIO case -- replace dp_pm_suspend() with pm_runtime_force_suspend() -- replace dp_pm_resume() with pm_runtime_force_resume() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_aux.c | 5 + drivers/gpu/drm/msm/dp/dp_display.c | 181 ++-- drivers/gpu/drm/msm/dp/dp_power.c | 32 +-- drivers/gpu/drm/msm/dp/dp_power.h | 11 --- 4 files changed, 77 insertions(+), 152 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c index 8e3b677..10b6eeb 100644 --- a/drivers/gpu/drm/msm/dp/dp_aux.c +++ b/drivers/gpu/drm/msm/dp/dp_aux.c @@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, return -EINVAL; } + ret = pm_runtime_resume_and_get(dp_aux->dev); + if (ret) + return ret; + mutex_lock(>mutex); if (!aux->initted) { ret = -EIO; @@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, exit: mutex_unlock(>mutex); + pm_runtime_put_sync(dp_aux->dev); return ret; } diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index a99a786..9520d83 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -49,7 +49,6 @@ enum { ST_CONNECTED, ST_DISCONNECT_PENDING, ST_DISPLAY_OFF, - ST_SUSPENDED, }; enum { @@ -309,10 +308,6 @@ static void dp_display_unbind(struct device *dev, struct device *master, struct dp_display_private *dp = dev_get_dp_display_private(dev); struct msm_drm_private *priv = dev_get_drvdata(master); - /* disable all HPD interrupts */ - if (dp->core_initialized) - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); - kthread_stop(dp->ev_tsk); of_dp_aux_depopulate_bus(dp->aux); @@ -542,6 +537,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) { u32 state; int ret; + struct platform_device *pdev = dp->dp_display.pdev; mutex_lock(>event_mutex); @@ -549,7 +545,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
[PATCH v9 7/7] drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()
Currently eDP population is done at msm_dp_modeset_init() which happen at binding time. Move eDP population to be done at display probe time so that probe deferral cases can be handled effectively. wait_for_hpd_asserted callback is added during drm_dp_aux_init() to ensure eDP's HPD is up before proceeding eDP population. Changes in v5: -- inline dp_display_auxbus_population() and delete it Changes in v4: -- delete duplicate initialize code to dp_aux before drm_dp_aux_register() -- delete of_get_child_by_name(dev->of_node, "aux-bus") and inline the function -- not initialize rc = 0 Changes in v3: -- add done_probing callback into devm_of_dp_aux_populate_bus() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_aux.c | 34 - drivers/gpu/drm/msm/dp/dp_display.c | 59 +++-- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c index 10b6eeb..03f4951 100644 --- a/drivers/gpu/drm/msm/dp/dp_aux.c +++ b/drivers/gpu/drm/msm/dp/dp_aux.c @@ -479,7 +479,6 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux) int dp_aux_register(struct drm_dp_aux *dp_aux) { - struct dp_aux_private *aux; int ret; if (!dp_aux) { @@ -487,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux) return -EINVAL; } - aux = container_of(dp_aux, struct dp_aux_private, dp_aux); - - aux->dp_aux.name = "dpu_dp_aux"; - aux->dp_aux.dev = aux->dev; - aux->dp_aux.transfer = dp_aux_transfer; - ret = drm_dp_aux_register(>dp_aux); + ret = drm_dp_aux_register(dp_aux); if (ret) { DRM_ERROR("%s: failed to register drm aux: %d\n", __func__, ret); @@ -507,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux) drm_dp_aux_unregister(dp_aux); } +static int dp_wait_hpd_asserted(struct drm_dp_aux *dp_aux, +unsigned long wait_us) +{ + int ret; + struct dp_aux_private *aux; + + aux = container_of(dp_aux, struct dp_aux_private, dp_aux); + + pm_runtime_get_sync(aux->dev); + ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog); + pm_runtime_put_sync(aux->dev); + + return ret; +} + struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, bool is_edp) { @@ -530,6 +539,17 @@ struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, aux->catalog = catalog; aux->retry_cnt = 0; + /* +* Use the drm_dp_aux_init() to use the aux adapter +* before registering AUX with the DRM device so that +* msm eDP panel can be detected by generic_dep_panel_probe(). +*/ + aux->dp_aux.name = "dpu_dp_aux"; + aux->dp_aux.dev = dev; + aux->dp_aux.transfer = dp_aux_transfer; + aux->dp_aux.wait_hpd_asserted = dp_wait_hpd_asserted; + drm_dp_aux_init(>dp_aux); + return >dp_aux; } diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 6693582..cfbc610 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1199,6 +1199,17 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde return NULL; } +static int dp_auxbus_done_probe(struct drm_dp_aux *aux) +{ + int rc; + + rc = component_add(aux->dev, _display_comp_ops); + if (rc) + DRM_ERROR("eDP component add failed, rc=%d\n", rc); + + return rc; +} + static int dp_display_probe(struct platform_device *pdev) { int rc = 0; @@ -1264,10 +1275,18 @@ static int dp_display_probe(struct platform_device *pdev) if (rc) goto err; - rc = component_add(>dev, _display_comp_ops); - if (rc) { - DRM_ERROR("component add failed, rc=%d\n", rc); - goto err; + if (dp->dp_display.is_edp) { + rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe); + if (rc) { + DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc); + goto err; + } + } else { + rc = component_add(>dev, _display_comp_ops); + if (rc) { + DRM_ERROR("component add failed, rc=%d\n", rc); + goto err; + } } return rc; @@ -1283,7 +1302,6 @@ static void dp_display_remove(struct platform_device *pdev) component_del(>dev, _display_comp_ops); dp_display_deinit_sub_modules(dp); - platform_set_drvdata(pdev, NULL); } @@ -1389,29 +1407,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) { int rc; struct dp_display_private *dp_priv; - struct
[PATCH v9 4/7] drm/msm/dp: move parser->parse() and dp_power_client_init() to probe
Original both parser->parse() and dp_power_client_init() are done at dp_display_bind() since eDP population is done at binding time. In the preparation of having eDP population done at probe() time, move both function from dp_display_bind() to dp_display_probe(). Changes in v6: -- move dp_power_client_deinit() to remove() Changes in v5: -- explain why parser->parse() and dp_power_client_init() are moved to probe time -- tear down sub modules if failed Changes in v4: -- split this patch out of "incorporate pm_runtime framework into DP driver" patch Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 24 +--- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index c2e3247..a99a786 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -275,11 +275,6 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser); - if (rc) { - DRM_ERROR("device tree parsing failed\n"); - goto end; - } dp->drm_dev = drm; @@ -290,11 +285,6 @@ static int dp_display_bind(struct device *dev, struct device *master, goto end; } - rc = dp_power_client_init(dp->power); - if (rc) { - DRM_ERROR("Power client create failed\n"); - goto end; - } rc = dp_register_audio_driver(dev, dp->audio); if (rc) { @@ -327,7 +317,6 @@ static void dp_display_unbind(struct device *dev, struct device *master, of_dp_aux_depopulate_bus(dp->aux); - dp_power_client_deinit(dp->power); dp_unregister_audio_driver(dev, dp->audio); dp_aux_unregister(dp->aux); dp->drm_dev = NULL; @@ -1241,6 +1230,18 @@ static int dp_display_probe(struct platform_device *pdev) return -EPROBE_DEFER; } + rc = dp->parser->parse(dp->parser); + if (rc) { + DRM_ERROR("device tree parsing failed\n"); + goto err; + } + + rc = dp_power_client_init(dp->power); + if (rc) { + DRM_ERROR("Power client create failed\n"); + goto err; + } + /* setup event q */ mutex_init(>event_mutex); init_waitqueue_head(>event_q); @@ -1275,6 +1276,7 @@ static void dp_display_remove(struct platform_device *pdev) struct dp_display_private *dp = dev_get_dp_display_private(>dev); component_del(>dev, _display_comp_ops); + dp_power_client_deinit(dp->power); dp_display_deinit_sub_modules(dp); platform_set_drvdata(pdev, NULL); -- 2.7.4
[PATCH v9 0/7] incorporate pm runtime framework and eDP clean up
The purpose of this patch series is to incorporate pm runtime framework into MSM eDP/DP driver so that eDP panel can be detected by DRM eDP panel driver during system probe time. During incorporating procedure, original customized pm realted fucntions, such as dp_pm_prepare(), dp_pm_suspend(), dp_pm_resume() and dp_pm_prepare(), are removed and replaced with functions provided by pm runtiem framework such as pm_runtime_force_suspend() and pm_runtime_force_resume(). In addition, both eDP aux-bus and irq handler are bound at system probe time too. Please be noted that v9 patches are rebased on top of latest msm-next branch Kuogee Hsieh (7): drm/msm/dp: tie dp_display_irq_handler() with dp driver drm/msm/dp: rename is_connected with link_ready drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes drm/msm/dp: move parser->parse() and dp_power_client_init() to probe drm/msm/dp: incorporate pm_runtime framework into DP driver drm/msm/dp: delete EV_HPD_INIT_SETUP drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe() drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 - drivers/gpu/drm/msm/dp/dp_aux.c | 39 +++- drivers/gpu/drm/msm/dp/dp_display.c | 337 drivers/gpu/drm/msm/dp/dp_display.h | 3 +- drivers/gpu/drm/msm/dp/dp_drm.c | 14 +- drivers/gpu/drm/msm/dp/dp_power.c | 32 +-- drivers/gpu/drm/msm/dp/dp_power.h | 11 -- drivers/gpu/drm/msm/msm_drv.h | 5 - 8 files changed, 166 insertions(+), 279 deletions(-) -- 2.7.4
[PATCH v9 1/7] drm/msm/dp: tie dp_display_irq_handler() with dp driver
Currently the dp_display_request_irq() is executed at msm_dp_modeset_init() which ties irq registering to the DPU device's life cycle, while depending on resources that are released as the DP device is torn down. Move register DP driver irq handler to dp_display_probe() to have dp_display_irq_handler() IRQ tied with DP device. In addition, use platform_get_irq() to retrieve irq number from platform device directly. Changes in v5: -- reworded commit text as review comments at change #4 -- tear down component if failed at dp_display_request_irq() Changes in v4: -- delete dp->irq check at dp_display_request_irq() Changes in v3: -- move calling dp_display_irq_handler() to probe Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 32 +--- drivers/gpu/drm/msm/dp/dp_display.h | 1 - 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index e329e03..2110862 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1184,26 +1184,18 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) return ret; } -int dp_display_request_irq(struct msm_dp *dp_display) +static int dp_display_request_irq(struct dp_display_private *dp) { int rc = 0; - struct dp_display_private *dp; - - if (!dp_display) { - DRM_ERROR("invalid input\n"); - return -EINVAL; - } - - dp = container_of(dp_display, struct dp_display_private, dp_display); + struct platform_device *pdev = dp->dp_display.pdev; - dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0); + dp->irq = platform_get_irq(pdev, 0); if (!dp->irq) { DRM_ERROR("failed to get irq\n"); return -EINVAL; } - rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq, - dp_display_irq_handler, + rc = devm_request_irq(>dev, dp->irq, dp_display_irq_handler, IRQF_TRIGGER_HIGH, "dp_display_isr", dp); if (rc < 0) { DRM_ERROR("failed to request IRQ%u: %d\n", @@ -1278,13 +1270,21 @@ static int dp_display_probe(struct platform_device *pdev) platform_set_drvdata(pdev, >dp_display); + rc = dp_display_request_irq(dp); + if (rc) + goto err; + rc = component_add(>dev, _display_comp_ops); if (rc) { DRM_ERROR("component add failed, rc=%d\n", rc); - dp_display_deinit_sub_modules(dp); + goto err; } return rc; + +err: + dp_display_deinit_sub_modules(dp); + return rc; } static void dp_display_remove(struct platform_device *pdev) @@ -1537,12 +1537,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, dp_priv = container_of(dp_display, struct dp_display_private, dp_display); - ret = dp_display_request_irq(dp_display); - if (ret) { - DRM_ERROR("request_irq failed, ret=%d\n", ret); - return ret; - } - ret = dp_display_get_next_bridge(dp_display); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index f66cdbc..15dbd2f 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -36,7 +36,6 @@ struct msm_dp { int dp_display_set_plugged_cb(struct msm_dp *dp_display, hdmi_codec_plugged_cb fn, struct device *codec_dev); int dp_display_get_modes(struct msm_dp *dp_display); -int dp_display_request_irq(struct msm_dp *dp_display); bool dp_display_check_video_test(struct msm_dp *dp_display); int dp_display_get_test_bpp(struct msm_dp *dp_display); void dp_display_signal_audio_start(struct msm_dp *dp_display); -- 2.7.4
[PATCH v9 6/7] drm/msm/dp: delete EV_HPD_INIT_SETUP
EV_HPD_INIT_SETUP flag is used to trigger the initialization of external DP host controller. Since external DP host controller initialization had been incorporated into pm_runtime_resume(), this flag became obsolete. msm_dp_irq_postinstall() which triggers EV_HPD_INIT_SETUP event is obsoleted accordingly. Changes in v4: -- reworded commit text -- drop EV_HPD_INIT_SETUP -- drop msm_dp_irq_postinstall() Changes in v3: -- drop EV_HPD_INIT_SETUP and msm_dp_irq_postinstall() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 drivers/gpu/drm/msm/dp/dp_display.c | 16 drivers/gpu/drm/msm/msm_drv.h | 5 - 3 files changed, 25 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index fe7267b..5d5a045 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -856,7 +856,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) { struct msm_drm_private *priv; struct dpu_kms *dpu_kms = to_dpu_kms(kms); - int i; if (!dpu_kms || !dpu_kms->dev) return -EINVAL; @@ -865,9 +864,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) if (!priv) return -EINVAL; - for (i = 0; i < ARRAY_SIZE(priv->dp); i++) - msm_dp_irq_postinstall(priv->dp[i]); - return 0; } diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 9520d83..6693582 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -54,7 +54,6 @@ enum { enum { EV_NO_EVENT, /* hpd events */ - EV_HPD_INIT_SETUP, EV_HPD_PLUG_INT, EV_IRQ_HPD_INT, EV_HPD_UNPLUG_INT, @@ -1079,8 +1078,6 @@ static int hpd_event_thread(void *data) spin_unlock_irqrestore(_priv->event_lock, flag); switch (todo->event_id) { - case EV_HPD_INIT_SETUP: - break; case EV_HPD_PLUG_INT: dp_hpd_plug_handle(dp_priv, todo->data); break; @@ -1360,19 +1357,6 @@ void __exit msm_dp_unregister(void) platform_driver_unregister(_display_driver); } -void msm_dp_irq_postinstall(struct msm_dp *dp_display) -{ - struct dp_display_private *dp; - - if (!dp_display) - return; - - dp = container_of(dp_display, struct dp_display_private, dp_display); - - if (!dp_display->is_edp) - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0); -} - bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) { struct dp_display_private *dp; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index cd5bf65..e79b93b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -386,7 +386,6 @@ int __init msm_dp_register(void); void __exit msm_dp_unregister(void); int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, struct drm_encoder *encoder); -void msm_dp_irq_postinstall(struct msm_dp *dp_display); void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display); void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor); @@ -407,10 +406,6 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display, return -EINVAL; } -static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display) -{ -} - static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display) { } -- 2.7.4
[PATCH v9 3/7] drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes
Currently DP driver use drm_helper_hpd_irq_event(), bypassing drm bridge framework, to report HPD status changes to user space frame work. Replace it with drm_bridge_hpd_notify() since DP driver is part of drm bridge. Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 20 ++-- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 56f8d91..c2e3247 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -340,26 +340,10 @@ static const struct component_ops dp_display_comp_ops = { .unbind = dp_display_unbind, }; -static void dp_display_send_hpd_event(struct msm_dp *dp_display) -{ - struct dp_display_private *dp; - struct drm_connector *connector; - - dp = container_of(dp_display, struct dp_display_private, dp_display); - - connector = dp->dp_display.connector; - drm_helper_hpd_irq_event(connector->dev); -} - static int dp_display_send_hpd_notification(struct dp_display_private *dp, bool hpd) { - if ((hpd && dp->dp_display.link_ready) || - (!hpd && !dp->dp_display.link_ready)) { - drm_dbg_dp(dp->drm_dev, "HPD already %s\n", - (hpd ? "on" : "off")); - return 0; - } + struct drm_bridge *bridge = dp->dp_display.bridge; /* reset video pattern flag on disconnect */ if (!hpd) { @@ -373,7 +357,7 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n", dp->dp_display.connector_type, hpd); - dp_display_send_hpd_event(>dp_display); + drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready); return 0; } -- 2.7.4
[PATCH v9 2/7] drm/msm/dp: rename is_connected with link_ready
The is_connected flag is set to true after DP mainlink successfully finishes link training to enter into ST_MAINLINK_READY state rather than being set after the DP dongle is connected. Rename the is_connected flag with link_ready flag to match the state of DP driver's state machine. Changes in v5: -- reworded commit text according to review comments from change #4 Changes in v4: -- reworded commit text Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 19 +-- drivers/gpu/drm/msm/dp/dp_display.h | 2 +- drivers/gpu/drm/msm/dp/dp_drm.c | 14 +++--- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 2110862..56f8d91 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -351,12 +351,11 @@ static void dp_display_send_hpd_event(struct msm_dp *dp_display) drm_helper_hpd_irq_event(connector->dev); } - static int dp_display_send_hpd_notification(struct dp_display_private *dp, bool hpd) { - if ((hpd && dp->dp_display.is_connected) || - (!hpd && !dp->dp_display.is_connected)) { + if ((hpd && dp->dp_display.link_ready) || + (!hpd && !dp->dp_display.link_ready)) { drm_dbg_dp(dp->drm_dev, "HPD already %s\n", (hpd ? "on" : "off")); return 0; @@ -370,7 +369,7 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, dp->panel->dpcd, dp->panel->downstream_ports); } - dp->dp_display.is_connected = hpd; + dp->dp_display.link_ready = hpd; drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n", dp->dp_display.connector_type, hpd); @@ -913,7 +912,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display, dp_display->plugged_cb = fn; dp_display->codec_dev = codec_dev; - plugged = dp_display->is_connected; + plugged = dp_display->link_ready; dp_display_handle_plugged_change(dp_display, plugged); return 0; @@ -1344,16 +1343,16 @@ static int dp_pm_resume(struct device *dev) * also only signal audio when disconnected */ if (dp->link->sink_count) { - dp->dp_display.is_connected = true; + dp->dp_display.link_ready = true; } else { - dp->dp_display.is_connected = false; + dp->dp_display.link_ready = false; dp_display_handle_plugged_change(dp_display, false); } drm_dbg_dp(dp->drm_dev, "After, type=%d sink=%d conn=%d core_init=%d phy_init=%d power=%d\n", dp->dp_display.connector_type, dp->link->sink_count, - dp->dp_display.is_connected, dp->core_initialized, + dp->dp_display.link_ready, dp->core_initialized, dp->phy_initialized, dp_display->power_on); mutex_unlock(>event_mutex); @@ -1741,8 +1740,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge, return; } - if (!dp_display->is_connected && status == connector_status_connected) + if (!dp_display->link_ready && status == connector_status_connected) dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0); - else if (dp_display->is_connected && status == connector_status_disconnected) + else if (dp_display->link_ready && status == connector_status_disconnected) dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0); } diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index 15dbd2f..46780af 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -17,7 +17,7 @@ struct msm_dp { struct drm_bridge *bridge; struct drm_connector *connector; struct drm_bridge *next_bridge; - bool is_connected; + bool link_ready; bool audio_enabled; bool power_on; unsigned int connector_type; diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 40e7344..f18cb6f 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -24,10 +24,10 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge) dp = to_dp_bridge(bridge)->dp_display; - drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", - (dp->is_connected) ? "true" : "false"); + drm_dbg_dp(dp->drm_dev, "link_ready = %s\n", + (dp->link_ready) ? "true" : "false"); - return (dp->is_connected) ? connector_status_connected : + return (dp->link_ready) ? connector_status_connected : connector_status_disconnected; } @@ -40,8 +40,8 @@ static
Re: [PATCH 09/17] drm/msm/mdp5: use drmm-managed allocation for mdp5_encoder
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Change struct mdp5_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on encoder destruction. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c | 29 +++- 1 file changed, 4 insertions(+), 25 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 08/17] drm/msm/mdp5: use drmm-managed allocation for mdp5_crtc
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Change struct mdp5_crtc allocation to use drmm_crtc_alloc(). This removes the need to perform any actions on CRTC destruction. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 30 +++ 1 file changed, 15 insertions(+), 15 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 07/17] drm/msm/mdp5: use devres-managed allocation for INTF data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create INTF data structure. This allows us to remove corresponding kfree() call. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 06/17] drm/msm/mdp5: use devres-managed allocation for SMP data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create SMP data structure. This allows us to remove corresponding kfree and drop mdp5_smp_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 3 --- drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c | 19 --- drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.h | 1 - 3 files changed, 4 insertions(+), 19 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 05/17] drm/msm/mdp5: use devres-managed allocation for pipe data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create pipe data structure. This allows us to remove corresponding kfree and drop mdp5_pipe_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 6 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 10 +++--- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h | 4 ++-- 3 files changed, 6 insertions(+), 14 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 04/17] drm/msm/mdp5: use devres-managed allocation for mixer data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create mixer data structure. This allows us to remove corresponding kfree and drop mdp5_mixer_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 5 + drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 10 +++--- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h | 4 ++-- 3 files changed, 6 insertions(+), 13 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 03/17] drm/msm/mdp5: use devres-managed allocation for CTL manager data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create CTL manager data structure. This allows us to remove corresponding kfree and drop mdp5_ctlm_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 21 - drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.h | 1 - drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 -- 3 files changed, 4 insertions(+), 20 deletions(-) Reviewed-by: Abhinav Kumar
Re: [PATCH 03/17] drm/msm/mdp5: use devres-managed allocation for CTL manager data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create CTL manager data structure. This allows us to remove corresponding kfree and drop mdp5_ctlm_destroy() function. Signed-off-by: Dmitry Baryshkov --- Reviewed-by: Abhinav Kumar
Re: [Freedreno] [PATCH 02/17] drm/msm/mdp5: use devres-managed allocation for configuration data
On 7/7/2023 6:03 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create configuration data structure. This allows us to remove corresponding kfree and drop mdp5_cfg_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 24 +--- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h | 1 - drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 -- 3 files changed, 5 insertions(+), 22 deletions(-) Reviewed-by: Abhinav Kumar
[PATCH RESEND] drm/atomic-helper: rename drm_atomic_helper_check_wb_encoder_state
The drm_atomic_helper_check_wb_encoder_state() function doesn't use encoder for anything other than getting the drm_device instance. The function's description talks about checking the writeback connector state, not the encoder state. Moreover, there is no such thing as an encoder state, encoders generally do not have a state on their own. Drop the first argument and rename the function to drm_atomic_helper_check_wb_connector_state(). Signed-off-by: Dmitry Baryshkov --- Resending, no reaction for two months --- drivers/gpu/drm/drm_atomic_helper.c | 10 -- drivers/gpu/drm/vkms/vkms_writeback.c | 2 +- include/drm/drm_atomic_helper.h | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2444fc33dd7c..d69591381f00 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -795,8 +795,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, EXPORT_SYMBOL(drm_atomic_helper_check_modeset); /** - * drm_atomic_helper_check_wb_encoder_state() - Check writeback encoder state - * @encoder: encoder state to check + * drm_atomic_helper_check_wb_connector_state() - Check writeback connector state * @conn_state: connector state to check * * Checks if the writeback connector state is valid, and returns an error if it @@ -806,8 +805,7 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset); * Zero for success or -errno */ int -drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, -struct drm_connector_state *conn_state) +drm_atomic_helper_check_wb_connector_state(struct drm_connector_state *conn_state) { struct drm_writeback_job *wb_job = conn_state->writeback_job; struct drm_property_blob *pixel_format_blob; @@ -827,11 +825,11 @@ drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, if (fb->format->format == formats[i]) return 0; - drm_dbg_kms(encoder->dev, "Invalid pixel format %p4cc\n", >format->format); + drm_dbg_kms(conn_state->connector->dev, "Invalid pixel format %p4cc\n", >format->format); return -EINVAL; } -EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state); +EXPORT_SYMBOL(drm_atomic_helper_check_wb_connector_state); /** * drm_atomic_helper_check_plane_state() - Check plane state for validity diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c index d7e63aa14663..56edec6f1634 100644 --- a/drivers/gpu/drm/vkms/vkms_writeback.c +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -48,7 +48,7 @@ static int vkms_wb_encoder_atomic_check(struct drm_encoder *encoder, return -EINVAL; } - ret = drm_atomic_helper_check_wb_encoder_state(encoder, conn_state); + ret = drm_atomic_helper_check_wb_connector_state(conn_state); if (ret < 0) return ret; diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 536a0b0091c3..742ccbcd7809 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -50,8 +50,7 @@ struct drm_private_state; int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state); int -drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, -struct drm_connector_state *conn_state); +drm_atomic_helper_check_wb_connector_state(struct drm_connector_state *conn_state); int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, const struct drm_crtc_state *crtc_state, int min_scale, -- 2.42.0
Re: [PATCH 2/3] drm/msm/adreno: Add A305B support
On 30.11.2023 21:35, Luca Weiss wrote: > Add support for the Adreno 305B GPU that is found in MSM8226(v2) SoC. > Previously this was mistakenly claimed to be supported but using wrong > a configuration. > > In MSM8226v1 there's also a A305B but with chipid 0x03000510 which > should work with the same configuration but due to lack of hardware for > testing this is not added. > > Signed-off-by: Luca Weiss > --- > drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 15 --- > drivers/gpu/drm/msm/adreno/adreno_device.c | 15 +++ > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > 3 files changed, 28 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c > b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c > index c86b377f6f0d..5fc29801c4c7 100644 > --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c > @@ -134,6 +134,13 @@ static int a3xx_hw_init(struct msm_gpu *gpu) > /* Set up AOOO: */ > gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x003c); > gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c); > + } else if (adreno_is_a305b(adreno_gpu)) { > + gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x00181818); > + gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x00181818); > + gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x0018); > + gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x0018); > + gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0303); > + gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); > } else if (adreno_is_a306(adreno_gpu)) { > gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); > gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x000a); > @@ -230,7 +237,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) > gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x0001); > > /* Enable Clock gating: */ > - if (adreno_is_a306(adreno_gpu)) > + if (adreno_is_a305b(adreno_gpu)) > + gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0x); > + else if (adreno_is_a306(adreno_gpu)) > gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0x); ||? [...] Otherwise looks in line with msm-3.10 Reviewed-by: Konrad Dybcio Konrad
epoll + dmabuf + close = Kernel BUG NULL pointer dereference
Hello! I was rewriting the code in our compositor for Steam Deck, Gamescope, to use epoll for dmabuf image waits. I found out that using epoll + dmabufs + close(...) while it is added to the epoll causes a NULL pointer dereference BUG in the kernel. Using epoll_ctl with EPOLL_CTL_DEL before 'close' works fine, but close-ing the file descriptor to remove it from the epoll while epoll_wait results in the NULL pointer BUG. I am currently on 6.5.9, but the same happens on 6.1. I am also using AMDGPU. Let me know I can get more info on the crash, it also should be easy to reproduce using Gamescope at this commit sha: https://github.com/ValveSoftware/gamescope/commit/9a53b6eb37817ef403c89c104bcb73e617799114 Just run `gamescope -- glxgears` (probably only works properly on AMD, just a fyi). You should see either your system reboot or the BUG depending on your kernel build. dmesg log: [ 2829.171327] BUG: kernel NULL pointer dereference, address: [ 2829.171332] #PF: supervisor read access in kernel mode [ 2829.171333] #PF: error_code(0x) - not-present page [ 2829.171334] PGD 0 P4D 0 [ 2829.171336] Oops: [#2] PREEMPT SMP NOPTI [ 2829.171337] CPU: 11 PID: 14976 Comm: gamescope_img Tainted: G D 6.5.9-273-tkg-linux-tkg #1 1f8f4cb3cfc2d3f65b6974868e524278dc3e7e95 [ 2829.171339] Hardware name: Gigabyte Technology Co., Ltd. X670 AORUS ELITE AX/X670 AORUS ELITE AX, BIOS F7a 11/14/2022 [ 2829.171340] RIP: 0010:__ep_remove+0x8d/0x220 [ 2829.171344] Code: 8d 5e 10 48 89 df e8 f2 b8 a1 00 0f b6 45 3c 83 f0 01 44 08 e8 0f 84 70 01 00 00 49 8b b6 d0 00 00 00 48 8b 45 50 48 8d 55 50 <48> 39 16 0f 84 d6 00 00 00 48 8b 55 58 48 89 02 48 85 c0 74 04 48 [ 2829.171345] RSP: 0018:aa25551cbe40 EFLAGS: 00010202 [ 2829.171346] RAX: RBX: 94b0094c3910 RCX: [ 2829.171347] RDX: 94afe23e3f50 RSI: RDI: 94b0094c3910 [ 2829.171347] RBP: 94afe23e3f00 R08: 94ac88e85200 R09: [ 2829.171348] R10: R11: R12: 94ac88e85200 [ 2829.171348] R13: 0001 R14: 94b0094c3900 R15: [ 2829.171349] FS: 7f1bc502a6c0() GS:94cb7dac() knlGS: [ 2829.171349] CS: 0010 DS: ES: CR0: 80050033 [ 2829.171350] CR2: CR3: 00045101 CR4: 00750ee0 [ 2829.171350] PKRU: 5554 [ 2829.171351] Call Trace: [ 2829.171352] [ 2829.171355] ? __die+0x23/0x70 [ 2829.171358] ? page_fault_oops+0x171/0x4e0 [ 2829.171361] ? ep_poll_callback+0x246/0x290 [ 2829.171362] ? exc_page_fault+0x7f/0x180 [ 2829.171364] ? asm_exc_page_fault+0x26/0x30 [ 2829.171368] ? __ep_remove+0x8d/0x220 [ 2829.171369] eventpoll_release_file+0x5b/0xa0 [ 2829.171370] __fput+0x223/0x290 [ 2829.171373] task_work_run+0x5a/0x90 [ 2829.171375] exit_to_user_mode_prepare+0x123/0x140 [ 2829.171378] syscall_exit_to_user_mode+0x1b/0x40 [ 2829.171379] do_syscall_64+0x6c/0x90 [ 2829.171381] ? do_syscall_64+0x6c/0x90 [ 2829.171382] ? do_syscall_64+0x6c/0x90 [ 2829.171383] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 2829.171384] RIP: 0033:0x7f1bc5841bf6 [ 2829.171406] Code: 10 89 7c 24 0c 89 4c 24 1c e8 96 81 f7 ff 44 8b 54 24 1c 8b 54 24 18 41 89 c0 48 8b 74 24 10 8b 7c 24 0c b8 e8 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 32 44 89 c7 89 44 24 0c e8 e6 81 f7 ff 8b 44 [ 2829.171407] RSP: 002b:7f1bc5026a40 EFLAGS: 0293 ORIG_RAX: 00e8 [ 2829.171408] RAX: 0003 RBX: 55e4732d55e0 RCX: 7f1bc5841bf6 [ 2829.171408] RDX: 0400 RSI: 7f1bc5026aa0 RDI: 0005 [ 2829.171408] RBP: 7f1bc5029ab0 R08: R09: [ 2829.171409] R10: R11: 0293 R12: fd98 [ 2829.171409] R13: R14: 7ffe4af5e240 R15: 7f1bc482a000 [ 2829.171410] [ 2829.171411] Modules linked in: uinput nf_conntrack_netlink xt_addrtype br_netfilter rfcomm snd_seq_dummy snd_hrtimer snd_seq xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp nft_compat nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 bridge stp llc overlay cmac algif_hash algif_skcipher af_alg bnep nf_tables joydev mousedev btusb btrtl btbcm btintel btmtk bluetooth intel_rapl_msr intel_rapl_common ecdh_generic vfat fat amdgpu edac_mce_amd snd_hda_codec_realtek kvm_amd snd_hda_codec_generic ledtrig_audio kvm mt7921e snd_hda_codec_hdmi mt7921_common snd_usb_audio crct10dif_pclmul mt76_connac_lib snd_hda_intel crc32_pclmul amdxcp polyval_clmulni mt76 snd_usbmidi_lib snd_intel_dspcfg snd_ump drm_buddy snd_intel_sdw_acpi polyval_generic snd_rawmidi gf128mul snd_hda_codec gpu_sched ghash_clmulni_intel snd_seq_device mac80211 snd_hda_core i2c_algo_bit sha512_ssse3 mc drm_suballoc_helper snd_hwdep aesni_intel drm_ttm_helper snd_pcm r8169 ttm libarc4 ucsi_ccg crypto_simd snd_timer [
Re: [PATCH 2/2] drm/msm/dpu: Set input_sel bit for INTF
On 11/30/2023 11:36 PM, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 03:31, Jessica Zhang wrote: Set the input_sel bit for encoders as it was missed in the initial implementation. Reported-by: Rob Clark Fixes: 91143873a05d ("drm/msm/dpu: Add MISR register support for interface") Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/39 Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 7 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 3442cf65b86f..d0884997ecb7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -320,7 +320,7 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) { - dpu_hw_setup_misr(>hw, INTF_MISR_CTRL); + dpu_hw_setup_misr(>hw, INTF_MISR_CTRL, true); } static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index f38473e68f79..77b14107c84a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -83,7 +83,7 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) { - dpu_hw_setup_misr(>hw, LM_MISR_CTRL); + dpu_hw_setup_misr(>hw, LM_MISR_CTRL, false); } static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index a8a0a4e76b94..f441df47fdde 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -481,7 +481,8 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); } -void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset) +void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, + bool set_input_sel) { u32 config = 0; @@ -491,6 +492,10 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset) wmb(); config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; + + if (set_input_sel) + config |= MISR_CTRL_INPUT_SEL; + DPU_REG_WRITE(c, misr_ctrl_offset, config); } 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 bb496ebe283b..793670d62414 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -17,6 +17,7 @@ #define MISR_CTRL_ENABLEBIT(8) #define MISR_CTRL_STATUSBIT(9) #define MISR_CTRL_STATUS_CLEAR BIT(10) +#define MISR_CTRL_INPUT_SEL BIT(24) The public apq8916 TRM documents this as a 4-bit field. I think this was followed into the later generations. Can we please document it correctly and use an uint instead of just bool for set_input_sel? Can you pls point us to this document you are referring? I was not aware that bit level details are revealed in external documents :) Even though its a 4-bit field, it only takes a 0 or 1 as others are undefined. Exposing all the bits will only cause more confusion like it did for others thinking that input select is actually configurable when its not. I think what we should do is just pass "misr_type" to this API to tell whether its lm misr or intf misr and set BIT(24) based on that. #define MISR_CTRL_FREE_RUN_MASK BIT(31) /* @@ -357,7 +358,8 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, bool qos_8lvl, const struct dpu_hw_qos_cfg *cfg); -void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset); +void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, + bool set_input_sel); int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, -- 2.43.0
Re: [RFC PATCH 0/6] Supporting GMEM (generalized memory management) for external memory devices
On Fri, 2023-12-01 at 02:37 +, zhuweixi wrote: > From your argument on KVM I can see that the biggest miscommunication > between us is that you believed that GMEM wanted to share the whole > address space. No, it is not the case. GMEM is only providing > coordination via certain mmap() calls. So you are raising a case > supporting GMEM again -- passthrough part of the CPU addresses space > instead of passthrough the whole CPU address space, is exactly what > GMEM can do. On the other side, the IOMMU SVA feature wildly binds > the whole address space -- since the hardware feature is to directly > share the whole CPU page table. > > "We really should never ever encourage people to bind their device > address space to the CPU address space. This is a very special use > case and limits the driver design to only this use case. > We have exercised this approach to a rather extreme degree with KFD > and I can clearly say that doing this was a really big mistake. > As far as I can see you are about to repeat that mistake and even > encourage others to do so as well." > > -- The behavior of internally "attach device context to mm_struct" in > GMEM is ultimately a different approach to coordinate CPU and > devices. I want to replace MMU notifiers with this approach because I > want to protect core MM from random interactions with external driver > MMs. Both GMEM and MMU notifiers are binding device contexts to the > CPU context, not putting them in the same address space. If someone > is against GMEM's approach for binding CPU and device context, then > someone should be against MMU notifiers as well. > > Currently, from our discussion I think I received two messages: > 1. The original AMDKFD design was rejected because of > inserting vendor-specific stuff to the generic core MM. > 2. The rejection from #1 led to your opinion that anyone > cannot mix device and core MM together. That's precisely not what Christian wrote: "KFD was meant to be a vendor agnostic framework, very similar to what you propose here. It's just that it was seen as vendor specific because nobody else actually wanted to design the their drivers this way." It may be that the original discussion about AMDKFD could hint at #1, but the one here certainly does not ;) P. > > I think #1 really encouraged me that GMEM could help the AMDKFD > driver. However I am also confused that why GMEM must be compared > with a vendor-specific driver. AMDKFD was only considering a very > special use case: AMD GPUs using AMD IOMMU. > However, GMEM is trying to consider all generalized cases of memory > devices. The device can be Nvidia's GPU and Huawei's NPU that use > their own MMUs, or AMD/Intel GPUs that use IOMMUs, or other hundreds > of new accelerator vendors. > > -Weixi > > -Original Message- > From: Christian König > Sent: Thursday, November 30, 2023 9:05 PM > To: zhuweixi ; Dave Airlie > Cc: linux...@kvack.org; linux-ker...@vger.kernel.org; > a...@linux-foundation.org; weixi@openeuler.sh; mgor...@suse.de; > jgli...@redhat.com; rcampb...@nvidia.com; jhubb...@nvidia.com; > apop...@nvidia.com; mhairgr...@nvidia.com; z...@nvidia.com; > alexander.deuc...@amd.com; xinhui@amd.com; > amd-...@lists.freedesktop.org; felix.kuehl...@amd.com; > ogab...@kernel.org; dri-devel@lists.freedesktop.org; j...@nvidia.com; > leo...@nvidia.com; zhen...@linux.intel.com; zhi.a.w...@intel.com; > intel-gvt-...@lists.freedesktop.org; intel-...@lists.freedesktop.org; > jani.nik...@linux.intel.com; joonas.lahti...@linux.intel.com; > rodrigo.v...@intel.com; tvrtko.ursu...@linux.intel.com; Danilo > Krummrich ; Daniel Vetter ; Zeng, > Oak > Subject: Re: [RFC PATCH 0/6] Supporting GMEM (generalized memory > management) for external memory devices > > Am 30.11.23 um 08:22 schrieb zhuweixi: > > Add @Oak to the KFD discussion. I will reply separately elaborating > > your questions on GMEM's difference from HMM/MMU notifiers. > > > > Christian, thanks for pointing me to that AMDKFD discussion. I have > > read the discussion around the AMDKFD skeleton patch and found the > > previous discussion in the following URLs: > > https://lore.kernel.org/dri-devel/1405028848-5660-1-git-send-email-ode > > d.gab...@amd.com/#r > > https://lore.kernel.org/dri-devel/20140711154231.gb1...@gmail.com/ > > > > I believe AMDKFD's original patch was rejected mostly because of > > inserting vendor-specific stuff to the generic core MM. Jérôme has > > clearly stated this issue in the second URL. If the code is vendor- > > specific then it has no place in core MM, period. > > > > But why does that vendor-specific solution relate to a generalized > > solution like GMEM? The initial AMDKFD patch doesn't work for > > Nvidia or Intel. > > KFD was meant to be a vendor agnostic framework, very similar to what > you propose here. > > It's just that it was seen as vendor specific because nobody else > actually wanted to design the their drivers this way. > > >
[PATCH v4 11/13] drm/msm/dpu: use drmm-managed allocation for dpu_encoder_phys
Change struct allocation of encoder's phys backend data to use drmm_kzalloc(). This removes the need to perform any actions on encoder destruction. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 8 --- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 15 - .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 21 --- 5 files changed, 22 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1cf7ff6caff4..fdbaa92ec1ad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2173,6 +2173,7 @@ static void dpu_encoder_early_unregister(struct drm_encoder *encoder) } static int dpu_encoder_virt_add_phys_encs( + struct drm_device *dev, struct msm_display_info *disp_info, struct dpu_encoder_virt *dpu_enc, struct dpu_enc_phys_init_params *params) @@ -2194,7 +2195,7 @@ static int dpu_encoder_virt_add_phys_encs( if (disp_info->intf_type == INTF_WB) { - enc = dpu_encoder_phys_wb_init(params); + enc = dpu_encoder_phys_wb_init(dev, params); if (IS_ERR(enc)) { DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", @@ -2205,7 +2206,7 @@ static int dpu_encoder_virt_add_phys_encs( dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; ++dpu_enc->num_phys_encs; } else if (disp_info->is_cmd_mode) { - enc = dpu_encoder_phys_cmd_init(params); + enc = dpu_encoder_phys_cmd_init(dev, params); if (IS_ERR(enc)) { DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n", @@ -2216,7 +2217,7 @@ static int dpu_encoder_virt_add_phys_encs( dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; ++dpu_enc->num_phys_encs; } else { - enc = dpu_encoder_phys_vid_init(params); + enc = dpu_encoder_phys_vid_init(dev, params); if (IS_ERR(enc)) { DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n", @@ -2305,7 +2306,7 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, break; } - ret = dpu_encoder_virt_add_phys_encs(disp_info, + ret = dpu_encoder_virt_add_phys_encs(dpu_kms->dev, disp_info, dpu_enc, _params); if (ret) { DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); 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 6f04c3d56e77..5dc53b65040e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -281,22 +281,24 @@ struct dpu_encoder_wait_info { * @p: Pointer to init params structure * Return: Error code or newly allocated encoder */ -struct dpu_encoder_phys *dpu_encoder_phys_vid_init( +struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); /** * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder + * @dev: Corresponding device for devres management * @p: Pointer to init params structure * Return: Error code or newly allocated encoder */ -struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( +struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); /** * dpu_encoder_phys_wb_init - initialize writeback encoder + * @dev: Corresponding device for devres management * @init: Pointer to init info structure with initialization params */ -struct dpu_encoder_phys *dpu_encoder_phys_wb_init( +struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); /** 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 be185fe69793..d24f45d1f654 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 @@ -13,6 +13,8 @@ #include "dpu_trace.h" #include "disp/msm_disp_snapshot.h" +#include + #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ (e) && (e)->base.parent ? \ (e)->base.parent->base.id : -1, \ @@ -558,14 +560,6 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) phys_enc->enable_state = DPU_ENC_DISABLED; } -static void dpu_encoder_phys_cmd_destroy(struct
[PATCH v4 12/13] drm/msm/dpu: drop dpu_encoder_phys_ops::destroy
Drop the dpu_encoder_phys_ops' destroy() callback. No phys backend implements it anymore, so it is useless. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 18 -- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 -- 2 files changed, 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index fdbaa92ec1ad..0dc74e315a9f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -452,24 +452,6 @@ static void dpu_encoder_destroy(struct drm_encoder *drm_enc) dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); - mutex_lock(_enc->enc_lock); - - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (phys->ops.destroy) { - phys->ops.destroy(phys); - --dpu_enc->num_phys_encs; - dpu_enc->phys_encs[i] = NULL; - } - } - - if (dpu_enc->num_phys_encs) - DPU_ERROR_ENC(dpu_enc, "expected 0 num_phys_encs not %d\n", - dpu_enc->num_phys_encs); - dpu_enc->num_phys_encs = 0; - mutex_unlock(_enc->enc_lock); - drm_encoder_cleanup(drm_enc); mutex_destroy(_enc->enc_lock); } 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 5dc53b65040e..b6b48e2c63ef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -72,7 +72,6 @@ struct dpu_encoder_phys; * @enable:DRM Call. Enable a DRM mode. * @disable: DRM Call. Disable mode. * @atomic_check: DRM Call. Atomic check new DRM state. - * @destroy: DRM Call. Destroy and release resources. * @control_vblank_irq Register/Deregister for VBLANK IRQ * @wait_for_commit_done: Wait for hardware to have flushed the * current pending frames to hardware @@ -102,7 +101,6 @@ struct dpu_encoder_phys_ops { int (*atomic_check)(struct dpu_encoder_phys *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state); - void (*destroy)(struct dpu_encoder_phys *encoder); int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); -- 2.39.2
[PATCH v4 13/13] drm/msm/dpu: use drmm-managed allocation for dpu_encoder_virt
It is incorrect to use devm-managed memory allocations for DRM data structures exposed to userspace. They should use drmm_ allocations. Change struct dpu_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on encoder destruction. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 50 + 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 0dc74e315a9f..3383ab708ec4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -439,23 +439,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) return linecount; } -static void dpu_encoder_destroy(struct drm_encoder *drm_enc) -{ - struct dpu_encoder_virt *dpu_enc = NULL; - int i = 0; - - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - - dpu_enc = to_dpu_encoder_virt(drm_enc); - DPU_DEBUG_ENC(dpu_enc, "\n"); - - drm_encoder_cleanup(drm_enc); - mutex_destroy(_enc->enc_lock); -} - void dpu_encoder_helper_split_config( struct dpu_encoder_phys *phys_enc, enum dpu_intf interface) @@ -2337,7 +2320,6 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { }; static const struct drm_encoder_funcs dpu_encoder_funcs = { - .destroy = dpu_encoder_destroy, .late_register = dpu_encoder_late_register, .early_unregister = dpu_encoder_early_unregister, }; @@ -2348,20 +2330,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, { struct msm_drm_private *priv = dev->dev_private; struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); - struct drm_encoder *drm_enc = NULL; - struct dpu_encoder_virt *dpu_enc = NULL; - int ret = 0; + struct dpu_encoder_virt *dpu_enc; + int ret; - dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); - if (!dpu_enc) - return ERR_PTR(-ENOMEM); - - ret = drm_encoder_init(dev, _enc->base, _encoder_funcs, - drm_enc_mode, NULL); - if (ret) { - devm_kfree(dev->dev, dpu_enc); - return ERR_PTR(ret); - } + dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base, +_encoder_funcs, drm_enc_mode, NULL); + if (IS_ERR(dpu_enc)) + return ERR_CAST(dpu_enc); drm_encoder_helper_add(_enc->base, _encoder_helper_funcs); @@ -2371,8 +2346,10 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, mutex_init(_enc->rc_lock); ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); - if (ret) - goto fail; + if (ret) { + DPU_ERROR("failed to setup encoder\n"); + return ERR_PTR(-ENOMEM); + } atomic_set(_enc->frame_done_timeout_ms, 0); timer_setup(_enc->frame_done_timer, @@ -2387,13 +2364,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, DPU_DEBUG_ENC(dpu_enc, "created\n"); return _enc->base; - -fail: - DPU_ERROR("failed to create encoder\n"); - if (drm_enc) - dpu_encoder_destroy(drm_enc); - - return ERR_PTR(ret); } int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, -- 2.39.2
[PATCH v4 10/13] drm/msm/dpu: use drmm-managed allocation for dpu_crtc
Change struct dpu_crtc allocation to use drmm_crtc_alloc_with_planes(). This removes the need to perform any actions on CRTC destruction. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 25 +++- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 3c475f8042b0..a798c10036e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -51,17 +51,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) return to_dpu_kms(priv->kms); } -static void dpu_crtc_destroy(struct drm_crtc *crtc) -{ - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); - - if (!crtc) - return; - - drm_crtc_cleanup(crtc); - kfree(dpu_crtc); -} - static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -1435,7 +1424,6 @@ static int dpu_crtc_late_register(struct drm_crtc *crtc) static const struct drm_crtc_funcs dpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, - .destroy = dpu_crtc_destroy, .page_flip = drm_atomic_helper_page_flip, .reset = dpu_crtc_reset, .atomic_duplicate_state = dpu_crtc_duplicate_state, @@ -1469,9 +1457,13 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct dpu_crtc *dpu_crtc; int i, ret; - dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL); - if (!dpu_crtc) - return ERR_PTR(-ENOMEM); + dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base, + plane, cursor, + _crtc_funcs, + NULL); + + if (IS_ERR(dpu_crtc)) + return ERR_CAST(dpu_crtc); crtc = _crtc->base; crtc->dev = dev; @@ -1491,9 +1483,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, dpu_crtc_frame_event_work); } - drm_crtc_init_with_planes(dev, crtc, plane, cursor, _crtc_funcs, - NULL); - drm_crtc_helper_add(crtc, _crtc_helper_funcs); if (dpu_kms->catalog->dspp_count) -- 2.39.2
[PATCH v4 07/13] drm/msm/dpu: drop unused dpu_plane::lock
The field dpu_plane::lock was never used for protecting any kind of data. Drop it now. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 3eef5e025e12..20908f3d8f81 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -78,8 +78,6 @@ static const uint32_t qcom_compressed_supported_formats[] = { struct dpu_plane { struct drm_plane base; - struct mutex lock; - enum dpu_sspp pipe; uint32_t color_fill; @@ -1227,8 +1225,6 @@ static void dpu_plane_destroy(struct drm_plane *plane) if (pstate->r_pipe.sspp) _dpu_plane_set_qos_ctrl(plane, >r_pipe, false); - mutex_destroy(>lock); - /* this will destroy the states as well */ drm_plane_cleanup(plane); @@ -1488,8 +1484,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, /* success! finalize initialization */ drm_plane_helper_add(plane, _plane_helper_funcs); - mutex_init(>lock); - DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, pipe, plane->base.id); return plane; -- 2.39.2
[PATCH v4 02/13] drm/msm/dpu: remove IS_ERR_OR_NULL for dpu_hw_intr_init() error handling
Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If the value is NULL, then the function will return 0 instead of a proper return code. Replace IS_ERR_OR_NULL() with IS_ERR() in the dpu_hw_intr_init() error check. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 3b6ed60e1143..8fa1f8f52e70 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1150,7 +1150,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) } dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); - if (IS_ERR_OR_NULL(dpu_kms->hw_intr)) { + if (IS_ERR(dpu_kms->hw_intr)) { rc = PTR_ERR(dpu_kms->hw_intr); DPU_ERROR("hw_intr init failed: %d\n", rc); dpu_kms->hw_intr = NULL; -- 2.39.2
[PATCH v4 08/13] drm/msm/dpu: remove QoS teardown on plane destruction
There is little point in disabling QoS on plane destruction: it happens during DPU device destruction process, after which there will be no running planes. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 20908f3d8f81..ab9f93f15536 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1214,17 +1214,10 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, static void dpu_plane_destroy(struct drm_plane *plane) { struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL; - struct dpu_plane_state *pstate; DPU_DEBUG_PLANE(pdpu, "\n"); if (pdpu) { - pstate = to_dpu_plane_state(plane->state); - _dpu_plane_set_qos_ctrl(plane, >pipe, false); - - if (pstate->r_pipe.sspp) - _dpu_plane_set_qos_ctrl(plane, >r_pipe, false); - /* this will destroy the states as well */ drm_plane_cleanup(plane); -- 2.39.2
[PATCH v4 09/13] drm/msm/dpu: use drmm-managed allocation for dpu_plane
Change struct dpu_plane allocation to use drmm_universal_plane_alloc(). This removes the need to perform any actions on plane destruction. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 46 +-- 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ab9f93f15536..32b4b08ffe35 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1211,20 +1211,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, } } -static void dpu_plane_destroy(struct drm_plane *plane) -{ - struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL; - - DPU_DEBUG_PLANE(pdpu, "\n"); - - if (pdpu) { - /* this will destroy the states as well */ - drm_plane_cleanup(plane); - - kfree(pdpu); - } -} - static void dpu_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { @@ -1394,7 +1380,6 @@ static bool dpu_plane_format_mod_supported(struct drm_plane *plane, static const struct drm_plane_funcs dpu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .destroy = dpu_plane_destroy, .reset = dpu_plane_reset, .atomic_duplicate_state = dpu_plane_duplicate_state, .atomic_destroy_state = dpu_plane_destroy_state, @@ -1422,35 +1407,28 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, struct dpu_hw_sspp *pipe_hw; uint32_t num_formats; uint32_t supported_rotations; - int ret = -EINVAL; - - /* create and zero local structure */ - pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL); - if (!pdpu) { - DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe); - ret = -ENOMEM; - return ERR_PTR(ret); - } - - /* cache local stuff for later */ - plane = >base; - pdpu->pipe = pipe; + int ret; /* initialize underlying h/w driver */ pipe_hw = dpu_rm_get_sspp(>rm, pipe); if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { DPU_ERROR("[%u]SSPP is invalid\n", pipe); - goto clean_plane; + return ERR_PTR(-EINVAL); } format_list = pipe_hw->cap->sblk->format_list; num_formats = pipe_hw->cap->sblk->num_formats; - ret = drm_universal_plane_init(dev, plane, 0xff, _plane_funcs, + pdpu = drmm_universal_plane_alloc(dev, struct dpu_plane, base, + 0xff, _plane_funcs, format_list, num_formats, supported_format_modifiers, type, NULL); - if (ret) - goto clean_plane; + if (IS_ERR(pdpu)) + return ERR_CAST(pdpu); + + /* cache local stuff for later */ + plane = >base; + pdpu->pipe = pipe; pdpu->catalog = kms->catalog; @@ -1480,8 +1458,4 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, pipe, plane->base.id); return plane; - -clean_plane: - kfree(pdpu); - return ERR_PTR(ret); } -- 2.39.2
[PATCH v4 04/13] drm/msm/dpu: use devres-managed allocation for VBIF data
Use devm_kzalloc to create VBIF data structure. This allows us to remove corresponding kfree and drop dpu_hw_vbif_destroy() function. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 14 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 11 +++ 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c index a5121a50b2bb..98e34afde2d2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c @@ -2,6 +2,8 @@ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ +#include + #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_vbif.h" @@ -211,12 +213,13 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, ops->set_write_gather_en = dpu_hw_set_write_gather_en; } -struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, - void __iomem *addr) +struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, +const struct dpu_vbif_cfg *cfg, +void __iomem *addr) { struct dpu_hw_vbif *c; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); @@ -234,8 +237,3 @@ struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, return c; } - -void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif) -{ - kfree(vbif); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h index 7e10d2a172b4..e2b4307500e4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h @@ -108,12 +108,12 @@ struct dpu_hw_vbif { /** * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed * VBIF catalog entry. + * @dev: Corresponding device for devres management * @cfg: VBIF catalog entry for which driver object is required * @addr: Mapped register io address of MDSS */ -struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, - void __iomem *addr); - -void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif); +struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, +const struct dpu_vbif_cfg *cfg, +void __iomem *addr); #endif /*_DPU_HW_VBIF_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0afaea894b31..e1fbac351fc2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -811,13 +811,8 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) /* safe to call these more than once during shutdown */ _dpu_kms_mmu_destroy(dpu_kms); - if (dpu_kms->catalog) { - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i]) { - dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); - dpu_kms->hw_vbif[i] = NULL; - } - } + for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { + dpu_kms->hw_vbif[i] = NULL; } if (dpu_kms->rm_init) @@ -1124,7 +1119,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) struct dpu_hw_vbif *hw; const struct dpu_vbif_cfg *vbif = _kms->catalog->vbif[i]; - hw = dpu_hw_vbif_init(vbif, dpu_kms->vbif[vbif->id]); + hw = dpu_hw_vbif_init(dev, vbif, dpu_kms->vbif[vbif->id]); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); -- 2.39.2
[PATCH v4 06/13] drm/msm/dpu: use devres-managed allocation for HW blocks
Use devm_kzalloc to create HW block structure. This allows us to remove corresponding kfree and drop all dpu_hw_*_destroy() functions as well as dpu_rm_destroy(), which becomes empty afterwards. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c| 19 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h| 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c| 12 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h| 10 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c| 7 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h | 12 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 13 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 12 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c| 14 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h| 13 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 15 ++-- .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 17 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 15 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 13 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 90 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 11 +-- 23 files changed, 127 insertions(+), 247 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 86182c734606..e7b680a151d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -4,6 +4,9 @@ */ #include + +#include + #include "dpu_hwio.h" #include "dpu_hw_ctl.h" #include "dpu_kms.h" @@ -680,14 +683,15 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; }; -struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, - void __iomem *addr, - u32 mixer_count, - const struct dpu_lm_cfg *mixer) +struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, + const struct dpu_ctl_cfg *cfg, + void __iomem *addr, + u32 mixer_count, + const struct dpu_lm_cfg *mixer) { struct dpu_hw_ctl *c; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); @@ -702,8 +706,3 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, return c; } - -void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx) -{ - kfree(ctx); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 1c242298ff2e..279ebd8dfbff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -274,20 +274,16 @@ static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw) /** * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. * Should be called before accessing any ctl_path register. + * @dev: Corresponding device for devres management * @cfg: ctl_path catalog entry for which driver object is required * @addr: mapped register io address of MDP * @mixer_count: Number of mixers in @mixer * @mixer: Pointer to an array of Layer Mixers defined in the catalog */ -struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, - void __iomem *addr, - u32 mixer_count, - const struct dpu_lm_cfg *mixer); - -/** - * dpu_hw_ctl_destroy(): Destroys ctl driver context - * should be called to free the context - */ -void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx); +struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, + const struct dpu_ctl_cfg *cfg, + void __iomem *addr, + u32 mixer_count, + const struct dpu_lm_cfg *mixer); #endif /*_DPU_HW_CTL_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 509dbaa51d87..5e9aad1b2aa2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -3,6 +3,8 @@ * Copyright (c) 2020-2022, Linaro Limited */ +#include + #include #include "dpu_kms.h" @@ -188,12 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk; }; -struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
[PATCH v4 05/13] drm/msm/dpu: use devres-managed allocation for MDP TOP
Use devm_kzalloc to create MDP TOP structure. This allows us to remove corresponding kfree and drop dpu_hw_mdp_destroy() function. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 17 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 8 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 5 ++--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index 24e734768a72..05e48cf4ec1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -2,6 +2,8 @@ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ +#include + #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_top.h" @@ -247,16 +249,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->intf_audio_select = dpu_hw_intf_audio_select; } -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m) { struct dpu_hw_mdp *mdp; if (!addr) return ERR_PTR(-EINVAL); - mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); + mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); if (!mdp) return ERR_PTR(-ENOMEM); @@ -271,9 +274,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, return mdp; } - -void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp) -{ - kfree(mdp); -} - diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 8b1463d2b2f0..6f3dc98087df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -145,13 +145,15 @@ struct dpu_hw_mdp { /** * dpu_hw_mdptop_init - initializes the top driver for the passed config + * @dev: Corresponding device for devres management * @cfg: MDP TOP configuration from catalog * @addr: Mapped register io address of MDP * @m:Pointer to mdss catalog data */ -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m); void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index e1fbac351fc2..c675c9a76c74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -821,8 +821,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_kms->catalog = NULL; - if (dpu_kms->hw_mdp) - dpu_hw_mdp_destroy(dpu_kms->hw_mdp); dpu_kms->hw_mdp = NULL; } @@ -1105,7 +1103,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->rm_init = true; - dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp, + dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev, +dpu_kms->catalog->mdp, dpu_kms->mmio, dpu_kms->catalog); if (IS_ERR(dpu_kms->hw_mdp)) { -- 2.39.2
[PATCH v4 03/13] drm/msm/dpu: use devres-managed allocation for interrupts data
Use devm_kzalloc to create interrupts data structure. This allows us to remove corresponding kfree and drop dpu_hw_intr_destroy() function. Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 14 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 11 --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 +--- 3 files changed, 11 insertions(+), 18 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 088807db2c83..946dd0135dff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -6,6 +6,8 @@ #include #include +#include + #include "dpu_core_irq.h" #include "dpu_kms.h" #include "dpu_hw_interrupts.h" @@ -472,8 +474,9 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, return intr_status; } -struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, +void __iomem *addr, +const struct dpu_mdss_cfg *m) { struct dpu_hw_intr *intr; unsigned int i; @@ -481,7 +484,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, if (!addr || !m) return ERR_PTR(-EINVAL); - intr = kzalloc(sizeof(*intr), GFP_KERNEL); + intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL); if (!intr) return ERR_PTR(-ENOMEM); @@ -512,11 +515,6 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, return intr; } -void dpu_hw_intr_destroy(struct dpu_hw_intr *intr) -{ - kfree(intr); -} - int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, unsigned int irq_idx, void (*irq_cb)(void *arg), 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 53a21ebc57e8..564b750a28fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -70,15 +70,12 @@ struct dpu_hw_intr { /** * dpu_hw_intr_init(): Initializes the interrupts hw object + * @dev: Corresponding device for devres management * @addr: mapped register io address of MDP * @m:pointer to MDSS catalog data */ -struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, +void __iomem *addr, +const struct dpu_mdss_cfg *m); -/** - * dpu_hw_intr_destroy(): Cleanup interrutps hw object - * @intr: pointer to interrupts hw object - */ -void dpu_hw_intr_destroy(struct dpu_hw_intr *intr); #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 8fa1f8f52e70..0afaea894b31 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -806,8 +806,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) { int i; - if (dpu_kms->hw_intr) - dpu_hw_intr_destroy(dpu_kms->hw_intr); dpu_kms->hw_intr = NULL; /* safe to call these more than once during shutdown */ @@ -1149,7 +1147,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) goto err_pm_put; } - dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); + dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog); if (IS_ERR(dpu_kms->hw_intr)) { rc = PTR_ERR(dpu_kms->hw_intr); DPU_ERROR("hw_intr init failed: %d\n", rc); -- 2.39.2
[PATCH v4 01/13] drm/msm/dpu: cleanup dpu_kms_hw_init error path
It was noticed that dpu_kms_hw_init()'s error path contains several labels which point to the same code path. Replace all of them with a single label. Suggested-by: Konrad Dybcio Reviewed-by: Jessica Zhang Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 25 +++-- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index fe7267b3bff5..3b6ed60e1143 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1078,7 +1078,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (!dpu_kms->catalog) { DPU_ERROR("device config not known!\n"); rc = -EINVAL; - goto power_error; + goto err_pm_put; } /* @@ -1088,26 +1088,26 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_mmu_init(dpu_kms); if (rc) { DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent); if (IS_ERR(dpu_kms->mdss)) { rc = PTR_ERR(dpu_kms->mdss); DPU_ERROR("failed to get MDSS data: %d\n", rc); - goto power_error; + goto err_pm_put; } if (!dpu_kms->mdss) { rc = -EINVAL; DPU_ERROR("NULL MDSS data\n"); - goto power_error; + goto err_pm_put; } rc = dpu_rm_init(_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio); if (rc) { DPU_ERROR("rm init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } dpu_kms->rm_init = true; @@ -1119,7 +1119,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_mdp); DPU_ERROR("failed to get hw_mdp: %d\n", rc); dpu_kms->hw_mdp = NULL; - goto power_error; + goto err_pm_put; } for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { @@ -1130,7 +1130,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); - goto power_error; + goto err_pm_put; } dpu_kms->hw_vbif[vbif->id] = hw; @@ -1146,7 +1146,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = dpu_core_perf_init(_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); if (rc) { DPU_ERROR("failed to init perf %d\n", rc); - goto perf_err; + goto err_pm_put; } dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); @@ -1154,7 +1154,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_intr); DPU_ERROR("hw_intr init failed: %d\n", rc); dpu_kms->hw_intr = NULL; - goto hw_intr_init_err; + goto err_pm_put; } dev->mode_config.min_width = 0; @@ -1179,7 +1179,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_drm_obj_init(dpu_kms); if (rc) { DPU_ERROR("modeset init failed: %d\n", rc); - goto drm_obj_init_err; + goto err_pm_put; } dpu_vbif_init_memtypes(dpu_kms); @@ -1188,10 +1188,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) return 0; -drm_obj_init_err: -hw_intr_init_err: -perf_err: -power_error: +err_pm_put: pm_runtime_put_sync(_kms->pdev->dev); error: _dpu_kms_hw_destroy(dpu_kms); -- 2.39.2
[PATCH v4 00/13] drm/msm/dpu: use managed memory allocations
In a lots of places in DPU driver memory is allocated by using the kzalloc and then manually freed using kfree. However thes memory chunks have a well-defined life cycle. They are either a part of the driver's runtime and can be devm_kzalloc'ed or are exposed to userspace via the DRM objects and thus can be drmm_alloc'ed. Implement corresponding runtime resource manangement for the DPU driver. Changes since v3: - Rebased on top of msm-next Changes since v2: - Added missing dependencies to the cover letter (Jessica) - Fixed commit message for patch 4 (Jessica) Changes since v1: - Fix error handling for some of drmm_foo_alloc() functions, which return error pointer in case of an error rather than typical NULL. Dmitry Baryshkov (13): drm/msm/dpu: cleanup dpu_kms_hw_init error path drm/msm/dpu: remove IS_ERR_OR_NULL for dpu_hw_intr_init() error handling drm/msm/dpu: use devres-managed allocation for interrupts data drm/msm/dpu: use devres-managed allocation for VBIF data drm/msm/dpu: use devres-managed allocation for MDP TOP drm/msm/dpu: use devres-managed allocation for HW blocks drm/msm/dpu: drop unused dpu_plane::lock drm/msm/dpu: remove QoS teardown on plane destruction drm/msm/dpu: use drmm-managed allocation for dpu_plane drm/msm/dpu: use drmm-managed allocation for dpu_crtc drm/msm/dpu: use drmm-managed allocation for dpu_encoder_phys drm/msm/dpu: drop dpu_encoder_phys_ops::destroy drm/msm/dpu: use drmm-managed allocation for dpu_encoder_virt drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 25 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 77 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 10 +-- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 15 +--- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 +-- .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 21 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c| 19 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h| 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c| 12 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h| 10 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c| 7 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h | 12 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 14 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 11 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 13 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 12 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c| 14 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h| 13 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 15 ++-- .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 17 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c| 17 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h| 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 15 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 13 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 55 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 59 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 90 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 11 +-- 36 files changed, 226 insertions(+), 487 deletions(-) -- 2.39.2
Re: [Freedreno] [PATCH 11/16] drm/msm/dpu: add an API to setup the CDM block for writeback
On Fri, 1 Dec 2023 at 21:04, Abhinav Kumar wrote: > > > > On 11/30/2023 11:20 PM, Dmitry Baryshkov wrote: > > On Fri, 1 Dec 2023 at 02:41, Abhinav Kumar > > wrote: > >> > >> > >> > >> On 8/30/2023 5:11 PM, Dmitry Baryshkov wrote: > >>> On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar > >>> wrote: > > Add an API dpu_encoder_helper_phys_setup_cdm() which can be used by > the writeback encoder to setup the CDM block. > > Currently, this is defined and used within the writeback's physical > encoder layer however, the function can be modified to be used to setup > the CDM block even for non-writeback interfaces. > > Until those modifications are planned and made, keep it local to > writeback. > > Signed-off-by: Abhinav Kumar > --- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 + > .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 123 +- > 2 files changed, 125 insertions(+), 1 deletion(-) > > 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 510c1c41ddbc..93a8ae67beff 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > @@ -16,6 +16,7 @@ > #include "dpu_hw_pingpong.h" > #include "dpu_hw_ctl.h" > #include "dpu_hw_top.h" > +#include "dpu_hw_cdm.h" > #include "dpu_encoder.h" > #include "dpu_crtc.h" > > @@ -209,6 +210,7 @@ static inline int > dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) > * @wbirq_refcount: Reference count of writeback interrupt > * @wb_done_timeout_cnt: number of wb done irq timeout errors > * @wb_cfg: writeback block config to store fb related details > + * @cdm_cfg: cdm block config needed to store writeback block's CDM > configuration > * @wb_conn: backpointer to writeback connector > * @wb_job: backpointer to current writeback job > * @dest: dpu buffer layout for current writeback output buffer > @@ -218,6 +220,7 @@ struct dpu_encoder_phys_wb { > atomic_t wbirq_refcount; > int wb_done_timeout_cnt; > struct dpu_hw_wb_cfg wb_cfg; > + struct dpu_hw_cdm_cfg cdm_cfg; > struct drm_writeback_connector *wb_conn; > struct drm_writeback_job *wb_job; > struct dpu_hw_fmt_layout dest; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > index 4c2736c3ee6d..11935aac9fd5 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > @@ -24,6 +24,20 @@ > #define to_dpu_encoder_phys_wb(x) \ > container_of(x, struct dpu_encoder_phys_wb, base) > > +#define TO_S15D16(_x_)((_x_) << 7) > + > +static struct dpu_csc_cfg dpu_encoder_phys_wb_rgb2yuv_601l = { > + { > + TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), > + TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), > + TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) > + }, > + { 0x00, 0x00, 0x00 }, > + { 0x0040, 0x0200, 0x0200 }, > + { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, > + { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, > +}; > >>> > >>> Nit: we probably need to have a single place with all dpu_csc_cfg entries. > >>> > >> > >> hmmm ... so we have YUV2RGB matrices for dpu plane and RGB2YUV matrices > >> for WB and DP. > >> > >> We can move all this to dpu_hw_util.c but lets do that in the DP series > >> as that completes the consumer list of these matrices. > > > > Doing it earlier is usually better. Can we please do it as a part of > > this series? > > > > Would be strange as RGB2YUV matrix is not used by anyone other than WB > till DP lands. > > If you are fine with that anomaly, no concerns. Yes. Because it keeps all instances in a single place. > > >> > + > /** > * dpu_encoder_phys_wb_is_master - report wb always as master encoder > * @phys_enc: Pointer to physical encoder > @@ -225,6 +239,112 @@ static void dpu_encoder_phys_wb_setup_ctl(struct > dpu_encoder_phys *phys_enc) > } > } > > +/** > + * dpu_encoder_phys_wb_setup_cdp - setup chroma down sampling block > + * @phys_enc:Pointer to physical encoder > + */ > +static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys > *phys_enc) > +{ > + struct dpu_hw_cdm *hw_cdm; > + struct dpu_hw_cdm_cfg *cdm_cfg; > + struct dpu_hw_pingpong *hw_pp; > + struct
Re: [PATCH v3 1/2] drm/msm/dpu: Modify vblank_refcount if error in callback
On Fri, 1 Dec 2023 at 21:14, Abhinav Kumar wrote: > > > > On 11/30/2023 11:45 PM, Dmitry Baryshkov wrote: > > On Fri, 1 Dec 2023 at 03:41, Paloma Arellano > > wrote: > >> > >> When the irq callback returns a value other than zero, > >> modify vblank_refcount by performing the inverse > >> operation of its corresponding if-else condition. > > > > I think it might be better to follow Bjorn's suggestion: once we have > > the lock, we don't need atomics at all. > > Then you rearrange the code to set the new value after getting return > > code from dpu_core_irq_register_callback() / > > dpu_core_irq_unregister_callback(). > > > > Even if we drop the atomics, we will have to replace it with a simple > refcount. The refcount checks will be before calling > dpu_core_irq_register_callback() / dpu_core_irq_unregister_callback(). > > So we will still need the corresponding inverse refcount when either of > those calls fail but just that they wont be atomics. Within the critical section you can check the value before register_callback and increment it afterwards if registration succeeds. > > Am I missing something here? > > >> > >> Signed-off-by: Paloma Arellano > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 9 +++-- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 9 +++-- > >> 2 files changed, 14 insertions(+), 4 deletions(-) > > -- With best wishes Dmitry
Re: [PATCH 06/16] drm/msm/dpu: add dpu_hw_cdm abstraction for CDM block
On Fri, 1 Dec 2023 at 20:19, Abhinav Kumar wrote: > > > > On 11/30/2023 11:05 PM, Dmitry Baryshkov wrote: > > On Fri, 1 Dec 2023 at 01:36, Abhinav Kumar > > wrote: > >> > >> > >> > >> On 8/30/2023 5:00 PM, Dmitry Baryshkov wrote: > >>> On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar > >>> wrote: > > CDM block comes with its own set of registers and operations > which can be done. In-line with other hardware sub-blocks, this > change adds the dpu_hw_cdm abstraction for the CDM block. > > Signed-off-by: Abhinav Kumar > --- > drivers/gpu/drm/msm/Makefile| 1 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 272 > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h | 135 ++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 + > 4 files changed, 409 insertions(+) > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > index 8d02d8c33069..2010cb1ca995 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ > disp/dpu1/dpu_encoder_phys_wb.o \ > disp/dpu1/dpu_formats.o \ > disp/dpu1/dpu_hw_catalog.o \ > + disp/dpu1/dpu_hw_cdm.o \ > disp/dpu1/dpu_hw_ctl.o \ > disp/dpu1/dpu_hw_dsc.o \ > disp/dpu1/dpu_hw_dsc_1_2.o \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c > new file mode 100644 > index ..a2f7ee8f54e4 > --- /dev/null > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c > @@ -0,0 +1,272 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2023, The Linux Foundation. All rights reserved. > + */ > + > +#include > + > +#include "dpu_hw_mdss.h" > +#include "dpu_hw_util.h" > +#include "dpu_hw_catalog.h" > +#include "dpu_hw_cdm.h" > +#include "dpu_kms.h" > + > +#define CDM_CSC_10_OPMODE 0x000 > +#define CDM_CSC_10_BASE0x004 > + > +#define CDM_CDWN2_OP_MODE 0x100 > +#define CDM_CDWN2_CLAMP_OUT0x104 > +#define CDM_CDWN2_PARAMS_3D_0 0x108 > +#define CDM_CDWN2_PARAMS_3D_1 0x10C > +#define CDM_CDWN2_COEFF_COSITE_H_0 0x110 > +#define CDM_CDWN2_COEFF_COSITE_H_1 0x114 > +#define CDM_CDWN2_COEFF_COSITE_H_2 0x118 > +#define CDM_CDWN2_COEFF_OFFSITE_H_00x11C > +#define CDM_CDWN2_COEFF_OFFSITE_H_10x120 > +#define CDM_CDWN2_COEFF_OFFSITE_H_20x124 > +#define CDM_CDWN2_COEFF_COSITE_V 0x128 > +#define CDM_CDWN2_COEFF_OFFSITE_V 0x12C > +#define CDM_CDWN2_OUT_SIZE 0x130 > + > +#define CDM_HDMI_PACK_OP_MODE 0x200 > +#define CDM_CSC_10_MATRIX_COEFF_0 0x004 > + > +#define CDM_MUX0x224 > + > +/** > + * Horizontal coefficients for cosite chroma downscale > + * s13 representation of coefficients > + */ > +static u32 cosite_h_coeff[] = {0x0016, 0x01cc, 0x019e}; > + > +/** > + * Horizontal coefficients for offsite chroma downscale > + */ > +static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; > + > +/** > + * Vertical coefficients for cosite chroma downscale > + */ > +static u32 cosite_v_coeff[] = {0x00080004}; > +/** > + * Vertical coefficients for offsite chroma downscale > + */ > +static u32 offsite_v_coeff[] = {0x00060002}; > + > +static int dpu_hw_cdm_setup_csc_10bit(struct dpu_hw_cdm *ctx, struct > dpu_csc_cfg *data) > +{ > + dpu_hw_csc_setup(>hw, CDM_CSC_10_MATRIX_COEFF_0, data, > true); > >>> > >>> Where was this defined? > >>> > >> > >> Its in this file itself > >> > >> +#define CDM_CSC_10_MATRIX_COEFF_0 0x004 > >> > + > + return 0; > +} > + > +static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct > dpu_hw_cdm_cfg *cfg) > +{ > + struct dpu_hw_blk_reg_map *c = >hw; > + u32 opmode = 0; > + u32 out_size = 0; > + > + if (cfg->output_bit_depth == CDM_CDWN_OUTPUT_10BIT) > + opmode &= ~BIT(7); > + else > + opmode |= BIT(7); > + > + /* ENABLE DWNS_H bit */ > + opmode |= BIT(1); > + > + switch (cfg->h_cdwn_type) { > + case CDM_CDWN_DISABLE: > + /* CLEAR
Re: [PATCH v3 0/2] Stabilize use of vblank_refcount
On 11/30/2023 11:41 PM, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 03:41, Paloma Arellano wrote: There is currently a race condition occuring when accessing vblank_refcount. Therefore, vblank irq timeouts may occur. Avoid any vblank irq timeouts by stablizing the use of vblank_refcount. Changes from prior versions: v2: - Slightly changed wording of patch #2 commit message v3: - Mistakenly did not change wording of patch #2 in last version. It is done now. Usually sending a series once a day is enough. If you have any pending changes, it might be better to reply to your patch stating that you want to do this and that, while still allowing reviewers to respond (and thus you can incorporate their review in the next iteration). Ack. Good to know. Thank you, Paloma Paloma Arellano (2): drm/msm/dpu: Modify vblank_refcount if error in callback drm/msm/dpu: Add mutex lock in control vblank irq drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 6 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 11 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 11 +-- 4 files changed, 30 insertions(+), 4 deletions(-) -- 2.41.0
Re: [PATCH v3 08/13] drm/msm/dpu: remove QoS teardown on plane destruction
On 7/29/2023 6:19 PM, Dmitry Baryshkov wrote: There is little point in disabling QoS on plane destruction: it happens during DPU device destruction process, after which there will be no running planes. Signed-off-by: Dmitry Baryshkov Reviewed-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index aba5185e1d66..f114efee1b57 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1173,17 +1173,10 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, static void dpu_plane_destroy(struct drm_plane *plane) { struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL; - struct dpu_plane_state *pstate; DPU_DEBUG_PLANE(pdpu, "\n"); if (pdpu) { - pstate = to_dpu_plane_state(plane->state); - _dpu_plane_set_qos_ctrl(plane, >pipe, false); - - if (pstate->r_pipe.sspp) - _dpu_plane_set_qos_ctrl(plane, >r_pipe, false); - /* this will destroy the states as well */ drm_plane_cleanup(plane); -- 2.39.2
Re: [PATCH v3 2/2] drm/msm/dpu: Add mutex lock in control vblank irq
On 12/1/2023 8:22 AM, Bjorn Andersson wrote: On Fri, Dec 01, 2023 at 10:34:50AM +0200, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 05:47, Bjorn Andersson wrote: On Thu, Nov 30, 2023 at 05:40:55PM -0800, Paloma Arellano wrote: [..] @@ -2386,6 +2390,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, dpu_enc->enabled = false; mutex_init(_enc->enc_lock); mutex_init(_enc->rc_lock); + mutex_init(_enc->vblank_ctl_lock); Is this somehow propagated to multiple different dpu_encoder_phys instances, or why do you need to initialize it here and pass the pointer through 2 different intermediate structures before assigning it to phys_enc->vblank_ctl_lock below? Yes, there can be two phys_enc instances for a single encoder, so this part is fine. Thanks for the clarification, Dmitry. Sounds like it make sense then. But, if I read the code correctly the two instances will have separate vblank_refcount copies, and the dpu_core_irq_*() interface does mutual exclusion within. So why do we need shared mutual exclusion between the two? (This is where a proper description of the problem in the commit message would have been very helpful) Are you suggesting we just have one vblank_ctl_lock per encoder and not have one vblank_ctl_lock per phys encoder? I cannot think of a display specific reason for that other than just the SW layout. The reason its like this today is that control_vblank_irq is an encoder phys op because it does different things based on the type of encoder. Because its an encoder phys op, it has the vblank_ctl_lock at the phys structure and not the encoder one. Its just more about how the phys op is defined that each phys op operates on its phys's structure. Generally, if we have one encoder with two physical encoders we anyways bail out early for the other encoder so this is mostly a no-op for the slave phys encoder. Please take a look at below return point. 715 /* Slave encoders don't report vblank */ 716 if (!sde_encoder_phys_vid_is_master(phys_enc)) 717 goto end; 718 So technically its still providing protection for the same phys encoder but the catch is this control_vblank_irq can get called from different threads hence we need exclusion. Regards, Bjorn
Re: [PATCH v3 13/13] drm/msm/dpu: use drmm-managed allocation for dpu_encoder_virt
On 7/29/2023 6:19 PM, Dmitry Baryshkov wrote: It is incorrect to use devm-managed memory allocations for DRM data structures exposed to userspace. They should use drmm_ allocations. Change struct dpu_encoder allocation to use drmm_encoder_alloc(). This removes the need to perform any actions on encoder destruction. Signed-off-by: Dmitry Baryshkov Reviewed-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 50 + 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 2b94ff3d08a1..6d9ec3ac065c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -443,23 +443,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) return linecount; } -static void dpu_encoder_destroy(struct drm_encoder *drm_enc) -{ - struct dpu_encoder_virt *dpu_enc = NULL; - int i = 0; - - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - - dpu_enc = to_dpu_encoder_virt(drm_enc); - DPU_DEBUG_ENC(dpu_enc, "\n"); - - drm_encoder_cleanup(drm_enc); - mutex_destroy(_enc->enc_lock); -} - void dpu_encoder_helper_split_config( struct dpu_encoder_phys *phys_enc, enum dpu_intf interface) @@ -2381,7 +2364,6 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { }; static const struct drm_encoder_funcs dpu_encoder_funcs = { - .destroy = dpu_encoder_destroy, .late_register = dpu_encoder_late_register, .early_unregister = dpu_encoder_early_unregister, }; @@ -2392,20 +2374,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, { struct msm_drm_private *priv = dev->dev_private; struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); - struct drm_encoder *drm_enc = NULL; - struct dpu_encoder_virt *dpu_enc = NULL; - int ret = 0; + struct dpu_encoder_virt *dpu_enc; + int ret; - dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); - if (!dpu_enc) - return ERR_PTR(-ENOMEM); - - ret = drm_encoder_init(dev, _enc->base, _encoder_funcs, - drm_enc_mode, NULL); - if (ret) { - devm_kfree(dev->dev, dpu_enc); - return ERR_PTR(ret); - } + dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base, +_encoder_funcs, drm_enc_mode, NULL); + if (IS_ERR(dpu_enc)) + return ERR_CAST(dpu_enc); drm_encoder_helper_add(_enc->base, _encoder_helper_funcs); @@ -2415,8 +2390,10 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, mutex_init(_enc->rc_lock); ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); - if (ret) - goto fail; + if (ret) { + DPU_ERROR("failed to setup encoder\n"); + return ERR_PTR(-ENOMEM); + } atomic_set(_enc->frame_done_timeout_ms, 0); timer_setup(_enc->frame_done_timer, @@ -2442,13 +2419,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, DPU_DEBUG_ENC(dpu_enc, "created\n"); return _enc->base; - -fail: - DPU_ERROR("failed to create encoder\n"); - if (drm_enc) - dpu_encoder_destroy(drm_enc); - - return ERR_PTR(ret); } int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, -- 2.39.2
Re: [PATCH v3 1/2] drm/msm/dpu: Modify vblank_refcount if error in callback
On 11/30/2023 11:45 PM, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 03:41, Paloma Arellano wrote: When the irq callback returns a value other than zero, modify vblank_refcount by performing the inverse operation of its corresponding if-else condition. I think it might be better to follow Bjorn's suggestion: once we have the lock, we don't need atomics at all. Then you rearrange the code to set the new value after getting return code from dpu_core_irq_register_callback() / dpu_core_irq_unregister_callback(). Even if we drop the atomics, we will have to replace it with a simple refcount. The refcount checks will be before calling dpu_core_irq_register_callback() / dpu_core_irq_unregister_callback(). So we will still need the corresponding inverse refcount when either of those calls fail but just that they wont be atomics. Am I missing something here? Signed-off-by: Paloma Arellano --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 9 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 9 +++-- 2 files changed, 14 insertions(+), 4 deletions(-)
Re: [Freedreno] [PATCH v3 01/13] drm/msm/dpu: cleanup dpu_kms_hw_init error path
On 7/29/2023 6:19 PM, Dmitry Baryshkov wrote: It was noticed that dpu_kms_hw_init()'s error path contains several labels which point to the same code path. Replace all of them with a single label. Suggested-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Reviewed-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 + 1 file changed, 9 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 31782a6d821f..77a79bc42492 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1077,7 +1077,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (!dpu_kms->catalog) { DPU_ERROR("device config not known!\n"); rc = -EINVAL; - goto power_error; + goto err_pm_put; } /* @@ -1087,13 +1087,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_mmu_init(dpu_kms); if (rc) { DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } rc = dpu_rm_init(_kms->rm, dpu_kms->catalog, dpu_kms->mmio); if (rc) { DPU_ERROR("rm init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } dpu_kms->rm_init = true; @@ -1105,7 +1105,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_mdp); DPU_ERROR("failed to get hw_mdp: %d\n", rc); dpu_kms->hw_mdp = NULL; - goto power_error; + goto err_pm_put; } for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { @@ -1116,7 +1116,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); - goto power_error; + goto err_pm_put; } dpu_kms->hw_vbif[vbif->id] = hw; @@ -1132,7 +1132,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = dpu_core_perf_init(_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); if (rc) { DPU_ERROR("failed to init perf %d\n", rc); - goto perf_err; + goto err_pm_put; } dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); @@ -1140,7 +1140,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_intr); DPU_ERROR("hw_intr init failed: %d\n", rc); dpu_kms->hw_intr = NULL; - goto hw_intr_init_err; + goto err_pm_put; } dev->mode_config.min_width = 0; @@ -1165,7 +1165,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_drm_obj_init(dpu_kms); if (rc) { DPU_ERROR("modeset init failed: %d\n", rc); - goto drm_obj_init_err; + goto err_pm_put; } dpu_vbif_init_memtypes(dpu_kms); @@ -1174,10 +1174,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) return 0; -drm_obj_init_err: -hw_intr_init_err: -perf_err: -power_error: +err_pm_put: pm_runtime_put_sync(_kms->pdev->dev); error: _dpu_kms_hw_destroy(dpu_kms); -- 2.39.2
Re: [PATCH 11/16] drm/msm/dpu: add an API to setup the CDM block for writeback
On 11/30/2023 11:20 PM, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 02:41, Abhinav Kumar wrote: On 8/30/2023 5:11 PM, Dmitry Baryshkov wrote: On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar wrote: Add an API dpu_encoder_helper_phys_setup_cdm() which can be used by the writeback encoder to setup the CDM block. Currently, this is defined and used within the writeback's physical encoder layer however, the function can be modified to be used to setup the CDM block even for non-writeback interfaces. Until those modifications are planned and made, keep it local to writeback. Signed-off-by: Abhinav Kumar --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 + .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 123 +- 2 files changed, 125 insertions(+), 1 deletion(-) 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 510c1c41ddbc..93a8ae67beff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -16,6 +16,7 @@ #include "dpu_hw_pingpong.h" #include "dpu_hw_ctl.h" #include "dpu_hw_top.h" +#include "dpu_hw_cdm.h" #include "dpu_encoder.h" #include "dpu_crtc.h" @@ -209,6 +210,7 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) * @wbirq_refcount: Reference count of writeback interrupt * @wb_done_timeout_cnt: number of wb done irq timeout errors * @wb_cfg: writeback block config to store fb related details + * @cdm_cfg: cdm block config needed to store writeback block's CDM configuration * @wb_conn: backpointer to writeback connector * @wb_job: backpointer to current writeback job * @dest: dpu buffer layout for current writeback output buffer @@ -218,6 +220,7 @@ struct dpu_encoder_phys_wb { atomic_t wbirq_refcount; int wb_done_timeout_cnt; struct dpu_hw_wb_cfg wb_cfg; + struct dpu_hw_cdm_cfg cdm_cfg; struct drm_writeback_connector *wb_conn; struct drm_writeback_job *wb_job; struct dpu_hw_fmt_layout dest; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 4c2736c3ee6d..11935aac9fd5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -24,6 +24,20 @@ #define to_dpu_encoder_phys_wb(x) \ container_of(x, struct dpu_encoder_phys_wb, base) +#define TO_S15D16(_x_)((_x_) << 7) + +static struct dpu_csc_cfg dpu_encoder_phys_wb_rgb2yuv_601l = { + { + TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), + TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), + TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) + }, + { 0x00, 0x00, 0x00 }, + { 0x0040, 0x0200, 0x0200 }, + { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, + { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, +}; Nit: we probably need to have a single place with all dpu_csc_cfg entries. hmmm ... so we have YUV2RGB matrices for dpu plane and RGB2YUV matrices for WB and DP. We can move all this to dpu_hw_util.c but lets do that in the DP series as that completes the consumer list of these matrices. Doing it earlier is usually better. Can we please do it as a part of this series? Would be strange as RGB2YUV matrix is not used by anyone other than WB till DP lands. If you are fine with that anomaly, no concerns. + /** * dpu_encoder_phys_wb_is_master - report wb always as master encoder * @phys_enc: Pointer to physical encoder @@ -225,6 +239,112 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc) } } +/** + * dpu_encoder_phys_wb_setup_cdp - setup chroma down sampling block + * @phys_enc:Pointer to physical encoder + */ +static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc) +{ + struct dpu_hw_cdm *hw_cdm; + struct dpu_hw_cdm_cfg *cdm_cfg; + struct dpu_hw_pingpong *hw_pp; + struct dpu_encoder_phys_wb *wb_enc; + const struct msm_format *format; + const struct dpu_format *dpu_fmt; + struct drm_writeback_job *wb_job; + int ret; + + if (!phys_enc) + return; + + wb_enc = to_dpu_encoder_phys_wb(phys_enc); + cdm_cfg = _enc->cdm_cfg; + hw_pp = phys_enc->hw_pp; + hw_cdm = phys_enc->hw_cdm; + wb_job = wb_enc->wb_job; + + format = msm_framebuffer_format(wb_enc->wb_job->fb); + dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier); + + if (!hw_cdm) + return; + + if (!DPU_FORMAT_IS_YUV(dpu_fmt)) { + DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent), + dpu_fmt->base.pixel_format); + if (hw_cdm->ops.disable) +
Re: [PATCH v3 05/13] drm/msm/dpu: use devres-managed allocation for MDP TOP
On 8/16/2023 12:27 AM, Dmitry Baryshkov wrote: Hi Jessica, On Tue, 15 Aug 2023 at 23:17, Jessica Zhang wrote: On 7/29/2023 6:19 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create MDP TOP structure. This allows us to remove corresponding kfree and drop dpu_hw_mdp_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 17 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 8 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 5 ++--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index cff48763ce25..481b373d9ccb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -2,6 +2,8 @@ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ +#include Hi Dmitry, Is it possible to put this #include in a common header? Since it seems that this is a common change for a lot of patches in this series. I personally do not like putting unused includes into common headers. Each file should contain includes that are used by the particular file only. Header should include only the files required to process definitions in this header. Acked. In that case, the rest of this LGTM: Reviewed-by: Jessica Zhang Thanks, Jessica Zhang Thanks, Jessica Zhang + #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_top.h" @@ -268,16 +270,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->intf_audio_select = dpu_hw_intf_audio_select; } -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m) { struct dpu_hw_mdp *mdp; if (!addr) return ERR_PTR(-EINVAL); - mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); + mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); if (!mdp) return ERR_PTR(-ENOMEM); @@ -292,9 +295,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, return mdp; } - -void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp) -{ - kfree(mdp); -} - diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 8b1463d2b2f0..6f3dc98087df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -145,13 +145,15 @@ struct dpu_hw_mdp { /** * dpu_hw_mdptop_init - initializes the top driver for the passed config + * @dev: Corresponding device for devres management * @cfg: MDP TOP configuration from catalog * @addr: Mapped register io address of MDP * @m:Pointer to mdss catalog data */ -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m); void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 6e0643ea4868..d4f4cb402663 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -820,8 +820,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_kms->catalog = NULL; - if (dpu_kms->hw_mdp) - dpu_hw_mdp_destroy(dpu_kms->hw_mdp); dpu_kms->hw_mdp = NULL; } @@ -1091,7 +1089,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->rm_init = true; - dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp, + dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev, + dpu_kms->catalog->mdp, dpu_kms->mmio, dpu_kms->catalog); if (IS_ERR(dpu_kms->hw_mdp)) { -- 2.39.2 -- With best wishes Dmitry
Re: [PATCH 06/16] drm/msm/dpu: add dpu_hw_cdm abstraction for CDM block
On 11/30/2023 11:05 PM, Dmitry Baryshkov wrote: On Fri, 1 Dec 2023 at 01:36, Abhinav Kumar wrote: On 8/30/2023 5:00 PM, Dmitry Baryshkov wrote: On Thu, 31 Aug 2023 at 01:50, Abhinav Kumar wrote: CDM block comes with its own set of registers and operations which can be done. In-line with other hardware sub-blocks, this change adds the dpu_hw_cdm abstraction for the CDM block. Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 272 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h | 135 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 + 4 files changed, 409 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 8d02d8c33069..2010cb1ca995 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_encoder_phys_wb.o \ disp/dpu1/dpu_formats.o \ disp/dpu1/dpu_hw_catalog.o \ + disp/dpu1/dpu_hw_cdm.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ disp/dpu1/dpu_hw_dsc_1_2.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c new file mode 100644 index ..a2f7ee8f54e4 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023, The Linux Foundation. All rights reserved. + */ + +#include + +#include "dpu_hw_mdss.h" +#include "dpu_hw_util.h" +#include "dpu_hw_catalog.h" +#include "dpu_hw_cdm.h" +#include "dpu_kms.h" + +#define CDM_CSC_10_OPMODE 0x000 +#define CDM_CSC_10_BASE0x004 + +#define CDM_CDWN2_OP_MODE 0x100 +#define CDM_CDWN2_CLAMP_OUT0x104 +#define CDM_CDWN2_PARAMS_3D_0 0x108 +#define CDM_CDWN2_PARAMS_3D_1 0x10C +#define CDM_CDWN2_COEFF_COSITE_H_0 0x110 +#define CDM_CDWN2_COEFF_COSITE_H_1 0x114 +#define CDM_CDWN2_COEFF_COSITE_H_2 0x118 +#define CDM_CDWN2_COEFF_OFFSITE_H_00x11C +#define CDM_CDWN2_COEFF_OFFSITE_H_10x120 +#define CDM_CDWN2_COEFF_OFFSITE_H_20x124 +#define CDM_CDWN2_COEFF_COSITE_V 0x128 +#define CDM_CDWN2_COEFF_OFFSITE_V 0x12C +#define CDM_CDWN2_OUT_SIZE 0x130 + +#define CDM_HDMI_PACK_OP_MODE 0x200 +#define CDM_CSC_10_MATRIX_COEFF_0 0x004 + +#define CDM_MUX0x224 + +/** + * Horizontal coefficients for cosite chroma downscale + * s13 representation of coefficients + */ +static u32 cosite_h_coeff[] = {0x0016, 0x01cc, 0x019e}; + +/** + * Horizontal coefficients for offsite chroma downscale + */ +static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; + +/** + * Vertical coefficients for cosite chroma downscale + */ +static u32 cosite_v_coeff[] = {0x00080004}; +/** + * Vertical coefficients for offsite chroma downscale + */ +static u32 offsite_v_coeff[] = {0x00060002}; + +static int dpu_hw_cdm_setup_csc_10bit(struct dpu_hw_cdm *ctx, struct dpu_csc_cfg *data) +{ + dpu_hw_csc_setup(>hw, CDM_CSC_10_MATRIX_COEFF_0, data, true); Where was this defined? Its in this file itself +#define CDM_CSC_10_MATRIX_COEFF_0 0x004 + + return 0; +} + +static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cfg) +{ + struct dpu_hw_blk_reg_map *c = >hw; + u32 opmode = 0; + u32 out_size = 0; + + if (cfg->output_bit_depth == CDM_CDWN_OUTPUT_10BIT) + opmode &= ~BIT(7); + else + opmode |= BIT(7); + + /* ENABLE DWNS_H bit */ + opmode |= BIT(1); + + switch (cfg->h_cdwn_type) { + case CDM_CDWN_DISABLE: + /* CLEAR METHOD_H field */ + opmode &= ~(0x18); + /* CLEAR DWNS_H bit */ + opmode &= ~BIT(1); + break; + case CDM_CDWN_PIXEL_DROP: + /* Clear METHOD_H field (pixel drop is 0) */ + opmode &= ~(0x18); + break; + case CDM_CDWN_AVG: + /* Clear METHOD_H field (Average is 0x1) */ + opmode &= ~(0x18); + opmode |= (0x1 << 0x3); + break; + case CDM_CDWN_COSITE: + /* Clear METHOD_H field (Average is 0x2) */ + opmode &= ~(0x18); + opmode |= (0x2 << 0x3); + /* Co-site horizontal coefficients */ + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0, + cosite_h_coeff[0]); + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1, + cosite_h_coeff[1]); +
[pull] amdgpu, amdkfd, radeon drm-next-6.8
Hi Dave, Sima, New stuff for 6.8. The following changes since commit e8c2d3e25b844ad8f7c8b269a7cfd65285329264: drm/amdgpu/gmc9: disable AGP aperture (2023-11-17 00:58:41 -0500) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-next-6.8-2023-12-01 for you to fetch changes up to b719a9c15d52d4f56bdea8241a5d90fd9197ce99: drm/amd/display: Fix NULL pointer dereference at hibernate (2023-11-30 18:26:31 -0500) amd-drm-next-6.8-2023-12-01: amdgpu: - Add new 64 bit sequence number infrastructure. This will ultimately be used for user queue synchronization. - GPUVM updates - Misc code cleanups - RAS updates - DCN 3.5 updates - Rework PCIe link speed handling - Document GPU reset types - DMUB fixes - eDP fixes - NBIO 7.9 updates - NBIO 7.11 updates - SubVP updates - DCN 3.1.4 fixes - ABM fixes - AGP aperture fix - DCN 3.1.5 fix - Fix some potential error path memory leaks - Enable PCIe PMEs - Add XGMI, PCIe state dumping for aqua vanjaram - GFX11 golden register updates - Misc display fixes amdkfd: - Migrate TLB flushing logic to amdgpu - Trap handler fixes - Fix restore workers handling on suspend and reset - Fix possible memory leak in pqm_uninit() radeon: - Fix some possible overflows in command buffer checking - Check for errors in ring_lock Abhinav Singh (1): drm/radeon: Fix warning using plain integer as NULL Alex Deucher (3): drm/amdgpu: add pm metrics structure definition drm/amdgpu: fix AGP addressing when GART is not at 0 drm/amdgpu: add amdgpu_reg_state.h Alex Sierra (1): drm/amdgpu: Force order between a read and write to the same address Alvin Lee (5): drm/amd/display: Include udelay when waiting for INBOX0 ACK drm/amd/display: Use DRAM speed from validation for dummy p-state drm/amd/display: Increase num voltage states to 40 drm/amd/display: Enable SubVP on 1080p60 displays drm/amd/display: If P-State is supported try SubVP for smaller vlevel André Almeida (1): drm/amd: Document device reset methods Anthony Koo (3): drm/amd/display: Add new command to disable replay timing resync drm/amd/display: [FW Promotion] Release 0.0.193.0 drm/amd/display: [FW Promotion] Release 0.0.194.0 Aric Cyr (3): drm/amd/display: Promote DC to 3.2.260 drm/amd/display: 3.2.261 drm/amd/display: Promote DAL to 3.2.262 Arunpravin Paneer Selvam (1): drm/amdgpu: Implement a new 64bit sequence memory driver Aurabindo Pillai (1): drm/amd/display: Fix a debugfs null pointer error Bhuvana Chandra Pinninti (1): drm/amd/display: Refactor DSC into component folder Camille Cho (1): drm/amd/display: Simplify brightness initialization Candice Li (1): drm/amdgpu: Update EEPROM I2C address for smu v13_0_0 Daniel Miess (1): drm/amd/display: Enable DCN clock gating for DCN35 David Yat Sin (1): drm/amdkfd: Copy HW exception data to user event Dennis Chan (2): drm/amd/display: Add new Replay command and Disabled Replay Timing Resync drm/amd/display: Disable Timing sync check in Full-Screen Video Case Dinghao Liu (1): drm/amd/pm: fix a memleak in aldebaran_tables_init Dmytro Laktyushkin (2): drm/amd/display: update dcn315 lpddr pstate latency drm/amd/display: block dcn315 dynamic crb allocation when unintended Duncan Ma (1): drm/amd/display: Add disable timeout option Fangzhi Zuo (1): drm/amd/display: Enable DSC Flag in MST Mode Validation Felix Kuehling (3): drm/amdgpu: update mappings not managed by KFD drm/amdkfd: Move TLB flushing logic into amdgpu drm/amdkfd: Run restore_workers on freezable WQs Gabe Teeger (1): Revert "drm/amd/display: Enable CM low mem power optimization" Hamza Mahfooz (2): drm/amd/display: add a debugfs interface for the DMUB trace mask drm/amd/display: fix ABM disablement Hawking Zhang (2): drm/amdgpu: Retire query/reset_ras_err_status from gfx_v9_4_3 drm/amdgpu: Do not issue gpu reset from nbio v7_9 bif interrupt Ian Chen (1): drm/amd/display: add skip_implict_edp_power_control flag for dce110 Ilya Bakoulin (2): drm/amd/display: Fix MPCC 1DLUT programming drm/amd/display: Add DSC granular throughput adjustment Jonathan Kim (1): drm/amdgpu: update xgmi num links info post gc9.4.2 Krunoslav Kovac (1): drm/amd/display: Send PQ bit in AMD VSIF Laurent Morichetti (1): drm/amdkfd: Clear the VALU exception state in the trap handler Li Ma (1): drm/amdgpu: add init_registers for nbio v7.11 Lijo Lazar (8): drm/amd/pm: Add support to fetch pm metrics sample drm/amd/pm: Add pm metrics support to SMU v13.0.6 drm/amd/pm: Add sysfs attribute to get pm metrics drm/amdgpu: Move mca debug mode decision to ras
Re: [PATCH] drm/doc: Define KMS atomic state set
On Fri, Dec 01, 2023 at 06:16:16PM +0200, Pekka Paalanen wrote: > On Fri, 1 Dec 2023 17:00:32 +0200 > Ville Syrjälä wrote: > > > On Thu, Nov 30, 2023 at 05:07:40PM -0300, André Almeida wrote: > > > From: Pekka Paalanen > > > > > > Specify how the atomic state is maintained between userspace and > > > kernel, plus the special case for async flips. > > > > > > Signed-off-by: Pekka Paalanen > > > Signed-off-by: André Almeida > > > --- > > > > > > This is a standalone patch from the following serie, the other patches are > > > already merged: > > > https://lore.kernel.org/lkml/20231122161941.320564-1-andrealm...@igalia.com/ > > > > > > Documentation/gpu/drm-uapi.rst | 47 ++ > > > 1 file changed, 47 insertions(+) > > > > > > diff --git a/Documentation/gpu/drm-uapi.rst > > > b/Documentation/gpu/drm-uapi.rst > > > index 370d820be248..d0693f902a5c 100644 > > > --- a/Documentation/gpu/drm-uapi.rst > > > +++ b/Documentation/gpu/drm-uapi.rst > > > @@ -570,3 +570,50 @@ dma-buf interoperability > > > > > > Please see Documentation/userspace-api/dma-buf-alloc-exchange.rst for > > > information on how dma-buf is integrated and exposed within DRM. > > > + > > > +KMS atomic state > > > + > > > + > > > +An atomic commit can change multiple KMS properties in an atomic fashion, > > > +without ever applying intermediate or partial state changes. Either the > > > whole > > > +commit succeeds or fails, and it will never be applied partially. This > > > is the > > > +fundamental improvement of the atomic API over the older non-atomic API > > > which is > > > +referred to as the "legacy API". Applying intermediate state could > > > unexpectedly > > > +fail, cause visible glitches, or delay reaching the final state. > > > + > > > +An atomic commit can be flagged with DRM_MODE_ATOMIC_TEST_ONLY, which > > > means the > > > +complete state change is validated but not applied. Userspace should > > > use this > > > +flag to validate any state change before asking to apply it. If > > > validation fails > > > +for any reason, userspace should attempt to fall back to another, perhaps > > > +simpler, final state. This allows userspace to probe for various > > > configurations > > > +without causing visible glitches on screen and without the need to undo a > > > +probing change. > > > + > > > +The changes recorded in an atomic commit apply on top the current KMS > > > state in > > > +the kernel. Hence, the complete new KMS state is the complete old KMS > > > state with > > > +the committed property settings done on top. The kernel will try to avoid > > > +no-operation changes, > > > > Not how things work. The driver may try to avoid some really > > expensive operations, but generally it will just blindly blast > > the full state to the hardware. > > > > IIRC this was discussed long ago when atomic was being designed > > and the general concensus was that the kernel shouldn't generally > > do this kind of stuff, and instead we just leave it to userspace > > to generate optimal commits. > > I don't think userspace ever got that memo. If I was cheeky, I could > ask where that is documented, so you could point at it and say "told > you so". Probably not docuemented anywhere. > > When I was working on Weston atomic KMS support many years ago, I > created a framework that emitted KMS property changes only when they > actually needed changing. By review feedback (*), all that machinery was > dropped in a re-design, and today Weston always emits all KMS > properties it knows to program for a specific CRTC update including all > relevant planes and connectors. > > (*) Why do we need to repeat the same state tracking that the kernel > does anyway, and also risk getting out of sync with the kernel due to > bugs which then become more difficult to diagnose. I guess (assumed) > kernel internals leaked to userspace. Oops. The kernel does track the full state sure, but it doesn't generally go out of its way to figure out what specifically changed in that state. Doing so would be a lot of extra checks, and kinda less convenient to do inside the driver since at that point the state is already spread all over the various structures. And the fact that those structures are a mismash of uapi and internal bits of state (and other metadata for the single commit that really shouldn't be stored there) doesn't help matters. I did propose to split the state cleanly into pure uapi vs. internal stuff but that didn't gain any traction unfortunately. So I think it might be simpler to do on the uapi property level. It may result in a somewhat coarser idea of what changed, but it avoids having to track down all the little bits of state everwhere that could have changed in response to a single property changing. The kernel could do that I suppose, but someone would need to come up with a good way to track that information. Currently there are a handful of foo_changed booleans
Re: [RFC] drm: enable W=1 warnings by default across the subsystem
On Thu, Nov 30, 2023 at 10:52:17AM +0200, Jani Nikula wrote: > On Wed, 29 Nov 2023, Hamza Mahfooz wrote: > > Cc: Nathan Chancellor > > > > On 11/29/23 13:12, Jani Nikula wrote: > >> At least the i915 and amd drivers enable a bunch more compiler warnings > >> than the kernel defaults. > >> > >> Extend the W=1 warnings to the entire drm subsystem by default. Use the > >> copy-pasted warnings from scripts/Makefile.extrawarn with > >> s/KBUILD_CFLAGS/subdir-ccflags-y/ to make it easier to compare and keep > >> up with them in the future. > >> > >> This is similar to the approach currently used in i915. > >> > >> Some of the -Wextra warnings do need to be disabled, just like in > >> Makefile.extrawarn, but take care to not disable them for W=2 or W=3 > >> builds, depending on the warning. > > > > I think this should go in after drm-misc-next has a clean build (for > > COMPILE_TEST builds) with this patch applied. Otherwise, it will break a > > lot of build configs. > > Oh, I'm absolutely not suggesting this should be merged before known > warnings have been addressed one way or another. Either by fixing them > or by disabling said warning in driver local Makefiles, depending on the > case. > > While I'm suggesting this, I obviously (I hope) can't take on fixing all > the warnings this exposes. One way to scale would be for folks to apply > this locally, see what it uncovers in their drivers, and fix some. > > As an intermediate step we might also apply this to a topic branch in > drm-tip, so you'd see the warnings when building drm-tip, but not in > indidual branches or in anything that's merged upstream. For what it's worth, I ran this through my personal build matrix with LLVM/clang and it only found a few instances of -Wunused-but-set-variable: drivers/gpu/drm/mediatek/mtk_disp_gamma.c:121:6: warning: variable 'cfg_val' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/nouveau/nouveau_svm.c:115:24: warning: variable 'priority' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/nouveau/nouveau_svm.c:929:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c:221:7: warning: variable 'loc' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/qxl/qxl_cmd.c:424:6: warning: variable 'count' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/qxl/qxl_ioctl.c:148:14: warning: variable 'num_relocs' set but not used [-Wunused-but-set-variable] I know that clang does not support all the warnings that are being enabled here but I suspect there won't be too many instances of the other warnings. -Wformat-overflow and -Wformat-truncation might be the big ones. I know -Wstringop-overflow is being turned on globally in -next so that is one that you shouldn't have to worry much about. Cheers, Nathan
Re: [PATCH 0/2] Convert to persistent DRM devices
On 11/17/2023 10:43 AM, Jeffrey Hugo wrote: The qaic driver currently creates and destroys the DRM devices when the qaic device is in an operational state for userspace. This does not match what other DRM drivers do, and leads to a few race conditions that need to be handled. Instead, create the DRM device when the underlying PCIe device is detected and destroy the DRM device when the underlying device disappears. Use KOBJ_ONLINE/OFFLINE udev events to signal to userspace when the underlying device is ready to accept requests, or has entered a reset state. Carl Vanderlip (2): accel/qaic: Increase number of in_reset states accel/qaic: Expand DRM device lifecycle Documentation/accel/qaic/qaic.rst | 9 +- drivers/accel/qaic/mhi_controller.c | 2 +- drivers/accel/qaic/qaic.h | 15 +++-- drivers/accel/qaic/qaic_control.c | 5 +-- drivers/accel/qaic/qaic_data.c | 16 - drivers/accel/qaic/qaic_drv.c | 50 - 6 files changed, 52 insertions(+), 45 deletions(-) Pushed to drm-misc-next -Jeff
Re: [PATCH 6/9] drm/panel: himax-hx8394: Add Support for Powkiddy X55 panel
On Thu, Nov 30, 2023 at 09:19:40PM -0600, Kendrick Curry wrote: > On Thu, Nov 30, 2023 at 09:56:21AM -0600, Chris Morgan wrote: > > From: Chris Morgan > > > > Add support for the Powkiddy X55 panel as used on the Powkiddy X55 > > handheld gaming console. This panel uses a Himax HX8394 display > > controller and requires a vendor provided init sequence. The display > > resolution is 720x1280 and is 67mm by 121mm as measured with calipers. > > > > Signed-off-by: Chris Morgan > > --- > > drivers/gpu/drm/panel/panel-himax-hx8394.c | 137 + > > 1 file changed, 137 insertions(+) > > > > diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c > b/drivers/gpu/drm/panel/panel-himax-hx8394.c > > index b68ea09f4725..4807ab1c10fe 100644 > > --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c > > +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c > > @@ -38,6 +38,7 @@ > > #define HX8394_CMD_SETMIPI 0xba > > #define HX8394_CMD_SETOTP 0xbb > > #define HX8394_CMD_SETREGBANK 0xbd > > +#define HX8394_CMD_UNKNOWN5 0xbf > > #define HX8394_CMD_UNKNOWN1 0xc0 > > #define HX8394_CMD_SETDGCLUT 0xc1 > > #define HX8394_CMD_SETID 0xc3 > > @@ -52,6 +53,7 @@ > > #define HX8394_CMD_SETGIP1 0xd5 > > #define HX8394_CMD_SETGIP2 0xd6 > > #define HX8394_CMD_SETGPO 0xd6 > > +#define HX8394_CMD_UNKNOWN4 0xd8 > > #define HX8394_CMD_SETSCALING 0xdd > > #define HX8394_CMD_SETIDLE 0xdf > > #define HX8394_CMD_SETGAMMA 0xe0 > > @@ -203,6 +205,140 @@ static const struct hx8394_panel_desc > hsd060bhw4_desc = { > > .init_sequence = hsd060bhw4_init_sequence, > > }; > > > > +static int powkiddy_x55_init_sequence(struct hx8394 *ctx) > > +{ > > + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); > > + > > + /* 5.19.8 SETEXTC: Set extension command (B9h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETEXTC, > > + 0xff, 0x83, 0x94); > > + > > + /* 5.19.9 SETMIPI: Set MIPI control (BAh) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETMIPI, > > + 0x63, 0x03, 0x68, 0x6b, 0xb2, 0xc0); > > + > > + /* 5.19.2 SETPOWER: Set power (B1h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER, > > + 0x48, 0x12, 0x72, 0x09, 0x32, 0x54, 0x71, 0x71, 0x57, > 0x47); > > + > > + /* 5.19.3 SETDISP: Set display related register (B2h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETDISP, > > + 0x00, 0x80, 0x64, 0x0c, 0x0d, 0x2f); > > + > > + /* 5.19.4 SETCYC: Set display waveform cycles (B4h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETCYC, > > + 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0c, 0x86, > 0x75, > > + 0x00, 0x3f, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, > 0x0c, > > + 0x86); > > + > > + /* 5.19.5 SETVCOM: Set VCOM voltage (B6h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETVCOM, > > + 0x6e, 0x6e); > > + > > + /* 5.19.19 SETGIP0: Set GIP Option0 (D3h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP0, > > + 0x00, 0x00, 0x07, 0x07, 0x40, 0x07, 0x0c, 0x00, 0x08, > 0x10, > > + 0x08, 0x00, 0x08, 0x54, 0x15, 0x0a, 0x05, 0x0a, 0x02, > 0x15, > > + 0x06, 0x05, 0x06, 0x47, 0x44, 0x0a, 0x0a, 0x4b, 0x10, > 0x07, > > + 0x07, 0x0c, 0x40); > > + > > + /* 5.19.20 Set GIP Option1 (D5h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP1, > > + 0x1c, 0x1c, 0x1d, 0x1d, 0x00, 0x01, 0x02, 0x03, 0x04, > 0x05, > > + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x24, 0x25, 0x18, > 0x18, > > + 0x26, 0x27, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, > 0x18, > > + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, > 0x21, > > + 0x18, 0x18, 0x18, 0x18); > > + > > + /* 5.19.21 Set GIP Option2 (D6h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP2, > > + 0x1c, 0x1c, 0x1d, 0x1d, 0x07, 0x06, 0x05, 0x04, 0x03, > 0x02, > > + 0x01, 0x00, 0x0b, 0x0a, 0x09, 0x08, 0x21, 0x20, 0x18, > 0x18, > > + 0x27, 0x26, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, > 0x18, > > + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x25, > 0x24, > > + 0x18, 0x18, 0x18, 0x18); > > + > > + /* 5.19.25 SETGAMMA: Set gamma curve related setting (E0h) */ > > + mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGAMMA, > > + 0x00, 0x0a, 0x15, 0x1b, 0x1e, 0x21, 0x24, 0x22, 0x47, > 0x56, > > + 0x65, 0x66, 0x6e, 0x82, 0x88, 0x8b, 0x9a, 0x9d, 0x98, > 0xa8, > > + 0xb9, 0x5d, 0x5c, 0x61, 0x66, 0x6a, 0x6f, 0x7f, 0x7f, > 0x00, > > + 0x0a, 0x15, 0x1b, 0x1e, 0x21, 0x24, 0x22, 0x47, 0x56, > 0x65, > > + 0x65, 0x6e, 0x81, 0x87, 0x8b, 0x98, 0x9d, 0x99, 0xa8, > 0xba, > > +
Re: Radeon regression in 6.6 kernel
Phillip, Can you test this patch? I was not able to repro the issue on the navi2x card I had handy, but I think it should fix it. Thanks, Alex On Wed, Nov 29, 2023 at 3:49 PM Alex Deucher wrote: > > On Wed, Nov 29, 2023 at 3:10 PM Alex Deucher wrote: > > > > Actually I think I see the problem. I'll try and send out a patch > > later today to test. > > Does the attached patch fix it? > > Alex > > > > > Alex > > > > On Wed, Nov 29, 2023 at 1:52 PM Alex Deucher wrote: > > > > > > On Wed, Nov 29, 2023 at 11:41 AM Luben Tuikov wrote: > > > > > > > > On 2023-11-29 10:22, Alex Deucher wrote: > > > > > On Wed, Nov 29, 2023 at 8:50 AM Alex Deucher > > > > > wrote: > > > > >> > > > > >> On Tue, Nov 28, 2023 at 11:45 PM Luben Tuikov > > > > >> wrote: > > > > >>> > > > > >>> On 2023-11-28 17:13, Alex Deucher wrote: > > > > On Mon, Nov 27, 2023 at 6:24 PM Phillip Susi > > > > wrote: > > > > > > > > > > Alex Deucher writes: > > > > > > > > > >>> In that case those are the already known problems with the > > > > >>> scheduler > > > > >>> changes, aren't they? > > > > >> > > > > >> Yes. Those changes went into 6.7 though, not 6.6 AFAIK. Maybe > > > > >> I'm > > > > >> misunderstanding what the original report was actually testing. > > > > >> If it > > > > >> was 6.7, then try reverting: > > > > >> 56e449603f0ac580700621a356d35d5716a62ce5 > > > > >> b70438004a14f4d0f9890b3297cd66248728546c > > > > > > > > > > At some point it was suggested that I file a gitlab issue, but I > > > > > took > > > > > this to mean it was already known and being worked on. -rc3 came > > > > > out > > > > > today and still has the problem. Is there a known issue I could > > > > > track? > > > > > > > > > > > > > At this point, unless there are any objections, I think we should > > > > just > > > > revert the two patches > > > > >>> Uhm, no. > > > > >>> > > > > >>> Why "the two" patches? > > > > >>> > > > > >>> This email, part of this thread, > > > > >>> > > > > >>> https://lore.kernel.org/all/87r0kircdo@vps.thesusis.net/ > > > > >>> > > > > >>> clearly states that reverting *only* this commit, > > > > >>> 56e449603f0ac5 drm/sched: Convert the GPU scheduler to variable > > > > >>> number of run-queues > > > > >>> *does not* mitigate the failed suspend. (Furthermore, this commit > > > > >>> doesn't really change > > > > >>> anything operational, other than using an allocated array, instead > > > > >>> of a static one, in DRM, > > > > >>> while the 2nd patch is solely contained within the amdgpu driver > > > > >>> code.) > > > > >>> > > > > >>> Leaving us with only this change, > > > > >>> b70438004a14f4 drm/amdgpu: move buffer funcs setting up a level > > > > >>> to be at fault, as the kernel log attached in the linked email > > > > >>> above shows. > > > > >>> > > > > >>> The conclusion is that only b70438004a14f4 needs reverting. > > > > >> > > > > >> b70438004a14f4 was a fix for 56e449603f0ac5. Without b70438004a14f4, > > > > >> 56e449603f0ac5 breaks amdgpu. > > > > > > > > > > We can try and re-enable it in the next kernel. I'm just not sure > > > > > we'll be able to fix this in time for 6.7 with the holidays and all > > > > > and I don't want to cause a lot of scheduler churn at the end of the > > > > > 6.7 cycle if we hold off and try and fix it. Reverting seems like the > > > > > best short term solution. > > > > > > > > A lot of subsequent code has come in since commit 56e449603f0ac5, as it > > > > opened > > > > the opportunity for a 1-to-1 relationship between an entity and a > > > > scheduler. > > > > (Should've always been the case, from the outset. Not sure why it was > > > > coded as > > > > a fixed-size array.) > > > > > > > > Given that commit 56e449603f0ac5 has nothing to do with amdgpu, and the > > > > problem > > > > is wholly contained in amdgpu, and no other driver has this problem, > > > > there is > > > > no reason to have to "churn", i.e. go back and forth in DRM, only to > > > > cover up > > > > an init bug in amdgpu. See the response I just sent in @this thread: > > > > https://lore.kernel.org/r/05007cb0-871e-4dc7-af58-1351f4ba4...@gmail.com > > > > > > > > And it's not like this issue is unknown. I first posted about it on > > > > 2023-10-16. > > > > > > > > Ideally, amdgpu would just fix their init code. > > > > > > You can't make changes to core code that break other drivers. > > > Arguably 56e449603f0ac5 should not have gone in in the first place if > > > it broke amdgpu. b70438004a14f4 was the code to fix amdgpu's init > > > code, but as a side effect it seems to have broken suspend for some > > > users. > > > > > > Alex
Re: [PATCH] drm/msm/dpu: Add missing safe_lut_tbl in sc8180x catalog
On Fri, Dec 01, 2023 at 09:06:45AM +0100, Johan Hovold wrote: > On Thu, Nov 30, 2023 at 04:35:01PM -0800, Bjorn Andersson wrote: > > Similar to SC8280XP, the misconfigured SAFE logic causes rather > > significant delays in __arm_smmu_tlb_sync(), resulting in poor > > performance for things such as USB. > > > > Introduce appropriate SAFE values for SC8180X to correct this. > > > > Fixes: f3af2d6ee9ab ("drm/msm/dpu: Add SC8180x to hw catalog") > > Missing CC stable tag? > I figured it doesn't matter in practice, there's still a few issues left preventing people from just running a stable kernel on this platform. But it would be the right thing to do... Cc: sta...@vger.kernel.org Regards, Bjorn > > Signed-off-by: Bjorn Andersson > > Johan >
Re: [PATCH] drm/i915/dsi: Use devm_gpiod_get() for all GPIOs
On Fri, Dec 01, 2023 at 05:11:30PM +0100, Hans de Goede wrote: > soc_gpio_set_value() already uses devm_gpiod_get(), lets be consistent > and use devm_gpiod_get() for all GPIOs. > > This allows removing the intel_dsi_vbt_gpio_cleanup() function, > which only function was to put the GPIO-descriptors. Fine by me, but I'm not to judge if it is a right approach or not. In my series I have reused existing call... Anyway, FWIW, Reviewed-by: Andy Shevchenko -- With Best Regards, Andy Shevchenko
Re: [PATCH v3 2/2] drm/msm/dpu: Add mutex lock in control vblank irq
On Fri, Dec 01, 2023 at 10:34:50AM +0200, Dmitry Baryshkov wrote: > On Fri, 1 Dec 2023 at 05:47, Bjorn Andersson > wrote: > > On Thu, Nov 30, 2023 at 05:40:55PM -0800, Paloma Arellano wrote: [..] > > > @@ -2386,6 +2390,7 @@ struct drm_encoder *dpu_encoder_init(struct > > > drm_device *dev, > > > dpu_enc->enabled = false; > > > mutex_init(_enc->enc_lock); > > > mutex_init(_enc->rc_lock); > > > + mutex_init(_enc->vblank_ctl_lock); > > > > Is this somehow propagated to multiple different dpu_encoder_phys > > instances, or why do you need to initialize it here and pass the pointer > > through 2 different intermediate structures before assigning it to > > phys_enc->vblank_ctl_lock below? > > Yes, there can be two phys_enc instances for a single encoder, so this > part is fine. > Thanks for the clarification, Dmitry. Sounds like it make sense then. But, if I read the code correctly the two instances will have separate vblank_refcount copies, and the dpu_core_irq_*() interface does mutual exclusion within. So why do we need shared mutual exclusion between the two? (This is where a proper description of the problem in the commit message would have been very helpful) Regards, Bjorn