Re: [PATCH] drm: a6xx: avoid excessive stack usage
On Fri, Oct 18, 2024 at 03:11:38PM +, Arnd Bergmann wrote: > From: Arnd Bergmann > > Clang-19 and above sometimes end up with multiple copies of the large > a6xx_hfi_msg_bw_table structure on the stack. The problem is that > a6xx_hfi_send_bw_table() calls a number of device specific functions to > fill the structure, but these create another copy of the structure on > the stack which gets copied to the first. > > If the functions get inlined, that busts the warning limit: > > drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size (1032) > exceeds limit (1024) in 'a6xx_hfi_send_bw_table' [-Werror,-Wframe-larger-than] Why does this warning says that the limit is 1024? 1024 bytes is too small, isn't it? -Akhil. > > Mark all of them as 'noinline_for_stack' ensure we only have one copy > of the structure per function. > > Signed-off-by: Arnd Bergmann > --- > drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 21 +++-- > 1 file changed, 11 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > index cdb3f6e74d3e..5699e0420eb8 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > @@ -259,7 +259,8 @@ static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu) > NULL, 0); > } > > -static void a618_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +/* noinline to avoid having multiple copies of 'msg' on stack */ > +static noinline_for_stack void a618_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* Send a single "off" entry since the 618 GMU doesn't do bus scaling */ > msg->bw_level_num = 1; > @@ -287,7 +288,7 @@ static void a618_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a619_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a619_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > msg->bw_level_num = 13; > > @@ -346,7 +347,7 @@ static void a619_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[0][0] = 0x4000; > } > > -static void a640_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a640_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* >* Send a single "off" entry just to get things running > @@ -385,7 +386,7 @@ static void a640_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][2] = 0x6001; > } > > -static void a650_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a650_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* >* Send a single "off" entry just to get things running > @@ -416,7 +417,7 @@ static void a650_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a690_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a690_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* >* Send a single "off" entry just to get things running > @@ -447,7 +448,7 @@ static void a690_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a660_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a660_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* >* Send a single "off" entry just to get things running > @@ -478,7 +479,7 @@ static void a660_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void adreno_7c3_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void adreno_7c3_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > /* >* Send a single "off" entry just to get things running > @@ -509,7 +510,7 @@ static void adreno_7c3_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a730_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a730_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > msg->bw_level_num = 12; > > @@ -565,7 +566,7 @@ static void a730_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a740_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a740_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > { > msg->bw_level_num = 1; > > @@ -590,7 +591,7 @@ static void a740_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > msg->cnoc_cmds_data[1][0] = 0x6001; > } > > -static void a6xx_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) > +static noinline_for_stack void a
Re: vc4: HDMI Sink doesn't support RGB, something's wrong.
Hi, Am 17.10.24 um 17:59 schrieb Maxime Ripard: On Thu, Oct 17, 2024 at 05:26:46PM GMT, Stefan Wahren wrote: Am 17.10.24 um 16:27 schrieb Maxime Ripard: On Wed, Oct 16, 2024 at 07:16:43PM GMT, Dave Stevenson wrote: Hi Stefan On Tue, 15 Oct 2024 at 22:13, Stefan Wahren wrote: Hi Dave, ... i prepared a branch for you, which contains the latest suspend2idle patches: https://github.com/lategoodbye/linux-dev/commits/v6.12-pm/ Steps: 1. Flash latest Raspberry Pi OS (32 bit) on SD card 2. Build Kernel from repo above with arm/multi_v7_defconfig 3. Replace Kernel, modules + DTB on SD card with build ones 4. add the following to confix.txt device_tree=bcm2837-rpi-3-b-plus.dtb enable_uart=1 5. change/add the following to cmdline.txt console=ttyS1,115200 no_console_suspend=1 6. connect the following devices to Raspberry Pi 3 B+ : USB mouse USB keyboard HDMI monitor Debug UART adapter (USB side to PC) 7. Power on board and boot into X11 8. Change to root 9. Enable wakeup for ttyS1 So I remember for next time echo enabled > /sys/class/tty/ttyS1/power/wakeup 10. Trigger suspend to idle via X11 (echo freeze > /sys/power/state) 11. Wakeup Raspberry Pi via Debug UART I don't get the error you are seeing, but I also don't get the display resuming. pm has obviously killed the power to the HDMI block, and it has the reset values in as can be seen via /sys/kernel/debug/dri/0/hdmi_regs. Nothing in the driver restores these registers, and I'm not sure if it is meant to do so. Run kmstest or similar from this state and the change of mode reprogrammes the blocks so we get the display back again. I've also enabled CONFIG_DRM_LOAD_EDID_FIRMWARE so that I can use your EDID, and get the same results. Knee-capping the HDMI block on suspend seems an unlikely mechanism to work reliably. On the more recent Pis there is a need to be quite careful in disabling the pipeline to avoid getting data stuck in FIFOs. I feel I must be missing something here. I think we're probably missing calls to drm_mode_config_helper_suspend and drm_mode_config_helper_resume. Okay, i tried this and it works better (HDMI resumes fast), but it also triggers a lot of WARN vc4_plane_reset deviates from the helper there: https://elixir.bootlin.com/linux/v6.11.3/source/drivers/gpu/drm/drm_atomic_state_helper.c#L326 We should adjust it. and the "doesn't support RGB ..." warnings are still there. I pushed my changes to the branch and attached the dmesg output. I can't help you there, it doesn't make sense to me. The EDID should be correct. Maybe I should clarify that I provided the EDID from the X11 log during normal boot (good case). I wasn't aware how to dump the EDID during the suspend. I tested with the new branch and these warning doesn't always occurs during resume. So it seems to be timing related. AFAIU the EDID is read via I2C DDC and the attached clock in this case is VPU clock. Correct? So I added the following to the config.txt force_turbo=1 After that I wasn't able to reproduce these HDMI Sink warnings. Is it possible that the I2C data get corrupted by VPU clock changes? Regards Maxime
Re: [PATCH RFC 3/3] arm64: dts: qcom: x1e80100: Add ACD levels for GPU
On Thu, Oct 17, 2024 at 09:05:50AM +0200, Krzysztof Kozlowski wrote: > On 17/10/2024 08:12, Akhil P Oommen wrote: > > On Wed, Oct 16, 2024 at 09:50:04AM +0200, Krzysztof Kozlowski wrote: > >> On 15/10/2024 21:35, Akhil P Oommen wrote: > >>> On Mon, Oct 14, 2024 at 09:40:13AM +0200, Krzysztof Kozlowski wrote: > On Sat, Oct 12, 2024 at 01:59:30AM +0530, Akhil P Oommen wrote: > > Update GPU node to include acd level values. > > > > Signed-off-by: Akhil P Oommen > > --- > > arch/arm64/boot/dts/qcom/x1e80100.dtsi | 11 ++- > > 1 file changed, 10 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > b/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > index a36076e3c56b..e6c500480eb1 100644 > > --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > @@ -3323,60 +3323,69 @@ zap-shader { > > }; > > > > gpu_opp_table: opp-table { > > - compatible = "operating-points-v2"; > > + compatible = > > "operating-points-v2-adreno"; > > This nicely breaks all existing users of this DTS. Sorry, no. We are way > past initial bringup/development. One year past. > > > > How do I identify when devicetree is considered stable? An arbitrary > > time period doesn't sound like a good idea. Is there a general consensus > > on this? > > > > X1E chipset is still considered under development at least till the end of > > this > > year, right? > > Stable could be when people already get their consumer/final product > with it. I got some weeks ago Lenovo T14s laptop and since yesterday > working fine with Ubuntu: > https://discourse.ubuntu.com/t/ubuntu-24-10-concept-snapdragon-x-elite/48800 > > All chipsets are under development, even old SM8450, but we avoid > breaking it while doing that. > I still have questions about the practicality especially in IoT/Auto chipsets, but I will try to get it clarified when I face them. I will go ahead and send out the v2 series addressing the suggestions. -Akhil. > > > Best regards, > Krzysztof >
Re: [PATCH 05/11] accel/ivpu: Unmap partially mapped BOs in case of errors
On 10/17/2024 8:58 AM, Jacek Lawrynowicz wrote: From: Karol Wachowski Ensure that all buffers that were created only partially through allocated scatter-gather table are unmapped from MMU600 in case of errors. Signed-off-by: Karol Wachowski Reviewed-by: Jacek Lawrynowicz Signed-off-by: Jacek Lawrynowicz Reviewed-by: Jeffrey Hugo
Re: [PATCH v2 1/2] drm: fsl-dcu: Use dev_err_probe
On Thu, 26 Sep 2024 07:55:50 +0200, Alexander Stein wrote: > fsl_dcu_drm_modeset_init can return -EPROBE_DEFER, so use dev_err_probe > to remove an invalid error message and add it to deferral description. > > Applied to drm-misc-next, thanks! [1/2] drm: fsl-dcu: Use dev_err_probe commit: 5b7abfb20ba15c0d6c52672874b99d9564ca876b [2/2] drm: fsl-dcu: enable PIXCLK on LS1021A commit: ffcde9e44d3e18fde3d18bfff8d9318935413bfd Best regards, -- With best wishes Dmitry
Re: [PATCH 0/6] drm: constify read-only regmap structs
On Wed, 25 Sep 2024 17:42:39 +0200, Javier Carrasco wrote: > This series adds the const modifier to the remaining regmap_bus and > regmap_config structs under drm/ that are effectively used as const > (i.e., only read after their declaration), but kept ad writtable data. > > Applied to drm-misc-next, thanks! [1/6] drm/bridge: dpc3433: Constify struct regmap_config commit: b895a1805e0b01d523afa71818cb97a5d2655fcf [2/6] drm/fsl-dcu: Constify struct regmap_config commit: 9239d961ce9d95ec13e241407d0320228e664d68 [3/6] drm/mediatek: dp: Constify struct regmap_config commit: 02f686d17c4305a0b5e2a9de749664dfe9c0f63e [4/6] drm/meson: Constify struct regmap_config commit: 0bcbddb7ef0edb8b4ca994033128e955bb8b1b74 [5/6] drm/panel: ili9322: Constify struct regmap_bus commit: 6a92271233fb4789f69a9ba9410b23e2e5ab30e2 [6/6] drm/sprd: Constify struct regmap_bus commit: 420fb223fe6049f5eecac0d28136df5bc5699ea2 Best regards, -- With best wishes Dmitry
Re: [PATCH] drm/fsl-dcu: Remove redundant dev_err()
On Wed, 18 Sep 2024 15:48:41 +0800, Chen Ni wrote: > There is no need to call the dev_err() function directly to print a > custom message when handling an error from platform_get_irq() function > as it is going to display an appropriate error message in case of a > failure. > > Applied to drm-misc-next, thanks! [1/1] drm/fsl-dcu: Remove redundant dev_err() commit: 4b173d34e35726d7727d3e5edc43bcab12654ab0 Best regards, -- With best wishes Dmitry
[PATCH v5 1/5] dt-bindings: display/msm: Document MDSS on SA8775P
Document the MDSS hardware found on the Qualcomm SA8775P platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Mahadevan --- .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 + 1 file changed, 241 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml new file mode 100644 index ..58f8a01f29c7aaa9dc943c232363075686c06a7c --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml @@ -0,0 +1,241 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,sa8775p-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SA87755P Display MDSS + +maintainers: + - Mahadevan + +description: + SA8775P MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like + DPU display controller, DP interfaces and EDP etc. + +$ref: /schemas/display/msm/mdss-common.yaml# + +properties: + compatible: +const: qcom,sa8775p-mdss + + clocks: +items: + - description: Display AHB + - description: Display hf AXI + - description: Display core + + iommus: +maxItems: 1 + + interconnects: +maxItems: 3 + + interconnect-names: +maxItems: 3 + +patternProperties: + "^display-controller@[0-9a-f]+$": +type: object +additionalProperties: true + +properties: + compatible: +const: qcom,sa8775p-dpu + + "^displayport-controller@[0-9a-f]+$": +type: object +additionalProperties: true + +properties: + compatible: +items: + - const: qcom,sa8775p-dp + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | +#include +#include +#include +#include +#include +#include + +display-subsystem@ae0 { +compatible = "qcom,sa8775p-mdss"; +reg = <0x0ae0 0x1000>; +reg-names = "mdss"; + +interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, +<&mmss_noc MASTER_MDP1 &mc_virt SLAVE_EBI1>, +<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; +interconnect-names = "mdp0-mem", + "mdp1-mem", + "cpu-cfg"; + + +resets = <&dispcc_core_bcr>; +power-domains = <&dispcc_gdsc>; + +clocks = <&dispcc_ahb_clk>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc_mdp_clk>; + +interrupts = ; +interrupt-controller; +#interrupt-cells = <1>; + +iommus = <&apps_smmu 0x1000 0x402>; + +#address-cells = <1>; +#size-cells = <1>; +ranges; + +display-controller@ae01000 { +compatible = "qcom,sa8775p-dpu"; +reg = <0x0ae01000 0x8f000>, + <0x0aeb 0x2008>; +reg-names = "mdp", "vbif"; + +clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc_ahb_clk>, + <&dispcc_mdp_lut_clk>, + <&dispcc_mdp_clk>, + <&dispcc_mdp_vsync_clk>; +clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + +assigned-clocks = <&dispcc_mdp_vsync_clk>; +assigned-clock-rates = <1920>; + +operating-points-v2 = <&mdss0_mdp_opp_table>; +power-domains = <&rpmhpd RPMHPD_MMCX>; + +interrupt-parent = <&mdss0>; +interrupts = <0>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +dpu_intf0_out: endpoint { + remote-endpoint = <&mdss0_dp0_in>; +}; +}; +}; + +mdss0_mdp_opp_table: opp-table { +compatible = "operating-points-v2"; + +opp-37500 { +opp-hz = /bits/ 64 <37500>; +required-opps = <&rpmhpd_opp_svs_l1>; +}; + +opp-5 { +opp-hz = /bits/ 64 <5>; +required-opps = <&rpmhpd_opp_nom>; +}; + +opp-57500 { +opp-hz = /bits/ 64 <57500>; +required-opps = <&rpmhpd_opp_turbo>; +}; + +opp-65000 { +opp-hz = /bits/ 64 <65000>; +required-opps = <&rpmhpd_opp_turbo_l1>; +}; +}; +}; + +displayport-controller@af54000 { +compatible = "qcom,sa8775p-dp"; + +pin
[PATCH v5 2/5] dt-bindings: display/msm: Document the DPU for SA8775P
Document the DPU for Qualcomm SA8775P platform. Signed-off-by: Mahadevan --- Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml index c4087cc5abbdd44885a6755e1facda767a16f35d..01cf79bd754b491349c52c5aef49ba06e835d0bf 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml @@ -14,6 +14,7 @@ $ref: /schemas/display/msm/dpu-common.yaml# properties: compatible: enum: + - qcom,sa8775p-dpu - qcom,sm8650-dpu - qcom,x1e80100-dpu -- 2.34.1
[PATCH v5 3/5] drm/msm: mdss: Add SA8775P support
Add Mobile Display Subsystem (MDSS) support for the SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/msm_mdss.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index faa88fd6eb4d6aec383a242b66a2b5125c91b3bc..8f1d42a43bd02dd79acf222a3423d11ff3b3cba3 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -573,6 +573,16 @@ static const struct msm_mdss_data qcm2290_data = { .reg_bus_bw = 76800, }; +static const struct msm_mdss_data sa8775p_data = { + .ubwc_enc_version = UBWC_4_0, + .ubwc_dec_version = UBWC_4_0, + .ubwc_swizzle = 4, + .ubwc_static = 1, + .highest_bank_bit = 0, + .macrotile_mode = 1, + .reg_bus_bw = 74000, +}; + static const struct msm_mdss_data sc7180_data = { .ubwc_enc_version = UBWC_2_0, .ubwc_dec_version = UBWC_2_0, @@ -710,6 +720,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,mdss" }, { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data }, { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data }, + { .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data }, { .compatible = "qcom,sdm670-mdss", .data = &sdm670_data }, { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data }, { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, -- 2.34.1
[PATCH v5 4/5] drm/msm/dpu: Add SA8775P support
Add definitions for the display hardware used on the Qualcomm SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + 4 files changed, 488 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h new file mode 100644 index ..907b4d7ceb470b0391d2bbbab3ce520efa2b3263 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -0,0 +1,485 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DPU_8_4_SA8775P_H +#define _DPU_8_4_SA8775P_H + +static const struct dpu_caps sa8775p_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_mdp_cfg sa8775p_mdp = { + .name = "top_0", + .base = 0x0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ +static const struct dpu_ctl_cfg sa8775p_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sa8775p_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_1", .id = SSPP_VIG1, + .base = 0x6000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 4, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG1, + }, { + .name = "sspp_2", .id = SSPP_VIG2, + .base = 0x8000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 8, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG2, + }, { + .name = "sspp_3", .id = SSPP_VIG3, + .base = 0xa000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_
[PATCH v4 1/5] dt-bindings: display/msm: Document MDSS on SA8775P
Document the MDSS hardware found on the Qualcomm SA8775P platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Mahadevan --- .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 + 1 file changed, 241 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml new file mode 100644 index ..58f8a01f29c7aaa9dc943c232363075686c06a7c --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml @@ -0,0 +1,241 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,sa8775p-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SA87755P Display MDSS + +maintainers: + - Mahadevan + +description: + SA8775P MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like + DPU display controller, DP interfaces and EDP etc. + +$ref: /schemas/display/msm/mdss-common.yaml# + +properties: + compatible: +const: qcom,sa8775p-mdss + + clocks: +items: + - description: Display AHB + - description: Display hf AXI + - description: Display core + + iommus: +maxItems: 1 + + interconnects: +maxItems: 3 + + interconnect-names: +maxItems: 3 + +patternProperties: + "^display-controller@[0-9a-f]+$": +type: object +additionalProperties: true + +properties: + compatible: +const: qcom,sa8775p-dpu + + "^displayport-controller@[0-9a-f]+$": +type: object +additionalProperties: true + +properties: + compatible: +items: + - const: qcom,sa8775p-dp + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | +#include +#include +#include +#include +#include +#include + +display-subsystem@ae0 { +compatible = "qcom,sa8775p-mdss"; +reg = <0x0ae0 0x1000>; +reg-names = "mdss"; + +interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, +<&mmss_noc MASTER_MDP1 &mc_virt SLAVE_EBI1>, +<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; +interconnect-names = "mdp0-mem", + "mdp1-mem", + "cpu-cfg"; + + +resets = <&dispcc_core_bcr>; +power-domains = <&dispcc_gdsc>; + +clocks = <&dispcc_ahb_clk>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc_mdp_clk>; + +interrupts = ; +interrupt-controller; +#interrupt-cells = <1>; + +iommus = <&apps_smmu 0x1000 0x402>; + +#address-cells = <1>; +#size-cells = <1>; +ranges; + +display-controller@ae01000 { +compatible = "qcom,sa8775p-dpu"; +reg = <0x0ae01000 0x8f000>, + <0x0aeb 0x2008>; +reg-names = "mdp", "vbif"; + +clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc_ahb_clk>, + <&dispcc_mdp_lut_clk>, + <&dispcc_mdp_clk>, + <&dispcc_mdp_vsync_clk>; +clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + +assigned-clocks = <&dispcc_mdp_vsync_clk>; +assigned-clock-rates = <1920>; + +operating-points-v2 = <&mdss0_mdp_opp_table>; +power-domains = <&rpmhpd RPMHPD_MMCX>; + +interrupt-parent = <&mdss0>; +interrupts = <0>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +dpu_intf0_out: endpoint { + remote-endpoint = <&mdss0_dp0_in>; +}; +}; +}; + +mdss0_mdp_opp_table: opp-table { +compatible = "operating-points-v2"; + +opp-37500 { +opp-hz = /bits/ 64 <37500>; +required-opps = <&rpmhpd_opp_svs_l1>; +}; + +opp-5 { +opp-hz = /bits/ 64 <5>; +required-opps = <&rpmhpd_opp_nom>; +}; + +opp-57500 { +opp-hz = /bits/ 64 <57500>; +required-opps = <&rpmhpd_opp_turbo>; +}; + +opp-65000 { +opp-hz = /bits/ 64 <65000>; +required-opps = <&rpmhpd_opp_turbo_l1>; +}; +}; +}; + +displayport-controller@af54000 { +compatible = "qcom,sa8775p-dp"; + +pin
[PATCH v4 3/5] drm/msm: mdss: Add SA8775P support
Add Mobile Display Subsystem (MDSS) support for the SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/msm_mdss.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index faa88fd6eb4d6aec383a242b66a2b5125c91b3bc..8f1d42a43bd02dd79acf222a3423d11ff3b3cba3 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -573,6 +573,16 @@ static const struct msm_mdss_data qcm2290_data = { .reg_bus_bw = 76800, }; +static const struct msm_mdss_data sa8775p_data = { + .ubwc_enc_version = UBWC_4_0, + .ubwc_dec_version = UBWC_4_0, + .ubwc_swizzle = 4, + .ubwc_static = 1, + .highest_bank_bit = 0, + .macrotile_mode = 1, + .reg_bus_bw = 74000, +}; + static const struct msm_mdss_data sc7180_data = { .ubwc_enc_version = UBWC_2_0, .ubwc_dec_version = UBWC_2_0, @@ -710,6 +720,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,mdss" }, { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data }, { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data }, + { .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data }, { .compatible = "qcom,sdm670-mdss", .data = &sdm670_data }, { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data }, { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, -- 2.34.1
Re: [PATCH] drm: xlnx: zynqmp_dpsub: also call drm_helper_hpd_irq_event
On Wed, Oct 09, 2024 at 04:28:26PM +0200, Steffen Dirkwinkel wrote: > Hi Laurent, > > > On Wed, 2024-09-25 at 19:36 +0300, Laurent Pinchart wrote: > > Hi Steffen, > > > > On Wed, Sep 25, 2024 at 09:54:18AM +0200, Steffen Dirkwinkel wrote: > > > On Tue, 2024-09-24 at 21:43 +0300, Laurent Pinchart wrote: > > > > On Mon, Sep 23, 2024 at 09:48:03AM +0200, li...@steffen.cc wrote: > > > > > From: Steffen Dirkwinkel > > > > > > > > > > With hpd going through the bridge as of commit eb2d64bfcc17 > > > > > ("drm: xlnx: zynqmp_dpsub: Report HPD through the bridge") > > > > > we don't get hotplug events in userspace on zynqmp hardware. > > > > > Also sending hotplug events with drm_helper_hpd_irq_event > > > > > works. > > > > > > > > Why does the driver need to call both drm_helper_hpd_irq_event() > > > > and > > > > drm_bridge_hpd_notify() ? The latter should end up calling > > > > drm_kms_helper_connector_hotplug_event(), which is the same > > > > function > > > > that drm_helper_hpd_irq_event() calls. > > > > > > I don't know why we need drm_helper_hpd_irq_event. > > > I'll try to trace what happens on hotplug. > > > > Thank you. Let's try to find the best solution based on your > > findings. > > There's just nothing registering for hpd with > "drm_bridge_connector_enable_hpd" or "drm_bridge_hpd_enable". I'm not > sure what the correct way to implement this is. In > "drivers/gpu/drm/bridge/ti-tfp410.c" the driver registers for the > callback and calls "drm_helper_hpd_irq_event" in the callback. I guess > we could also do that, but then we might as well call > drm_helper_hpd_irq_event directly? Some other drivers just call both > like I did here. (drivers/gpu/drm/mediatek/mtk_hdmi.c for example) > For "drivers/gpu/drm/msm/hdmi/hdmi_bridge.c" I also can't find the hpd > enable call and it just calls drm_bridge_hpd_notify. The drm_bridge_connector handles enabling it for you when the driver calls drm_kms_helper_poll_init() / drm_kms_helper_poll_enable(). It seems zynqmp_kms calls drm_kms_helper_poll_init() too early, before creating DP chain, so the HPD doesn't get enabled. > > > > > > > > Fixes: eb2d64bfcc17 ("drm: xlnx: zynqmp_dpsub: Report HPD > > > > > through > > > > > the bridge") > > > > > Signed-off-by: Steffen Dirkwinkel > > > > > --- > > > > > drivers/gpu/drm/xlnx/zynqmp_dp.c | 4 > > > > > 1 file changed, 4 insertions(+) > > > > > > > > > > diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c > > > > > b/drivers/gpu/drm/xlnx/zynqmp_dp.c > > > > > index 1846c4971fd8..cb823540a412 100644 > > > > > --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c > > > > > +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c > > > > > @@ -17,6 +17,7 @@ > > > > > #include > > > > > #include > > > > > #include > > > > > +#include > > > > > > > > > > #include > > > > > #include > > > > > @@ -1614,6 +1615,9 @@ static void > > > > > zynqmp_dp_hpd_work_func(struct > > > > > work_struct *work) > > > > > hpd_work.work); > > > > > enum drm_connector_status status; > > > > > > > > > > + if (dp->bridge.dev) > > > > > + drm_helper_hpd_irq_event(dp->bridge.dev); > > > > > + > > > > > status = zynqmp_dp_bridge_detect(&dp->bridge); > > > > > drm_bridge_hpd_notify(&dp->bridge, status); > > > > > } > > > -- With best wishes Dmitry
Re: [PATCH v4 0/5] Display enablement changes for Qualcomm SA8775P platform
I apologize for the inconvenience caused by uploading the incorrect patch (v4). Kindly disregard it. On 10/19/2024 8:46 PM, Mahadevan wrote: This series introduces support to enable the Mobile Display Subsystem (MDSS) and Display Processing Unit (DPU) for the Qualcomm SA8775P target. It includes the addition of the hardware catalog, compatible string, relevant device tree changes, and their YAML bindings. --- In this series - PATCH 1: "dt-bindings: display/msm: Document MDSS on SA8775P" depends on dp binding documetion in this change: https://lore.kernel.org/all/20240923113150.24711-5-quic_mukho...@quicinc.com/ - PATCH 5: "arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU" depends on the clock enablement change: https://lore.kernel.org/all/20240816-sa8775p-mm-v3-v1-0-77d53c3c0...@quicinc.com/ --- [v5] - Update clock-name of display-controller in MDSS documentation to align with qcom,sm8650-dpu.yaml. [Rob] - Update power-domains of display-controller in DT to do proper voting on MMCX rail. [Internal Review] [v4] - Removed new YAML added for sa8775p dpu dt-binding documention as it is similar to qcom,sm8650-dpu.yaml and added the compatible in same. [Krzysztof] [v3] -Edited copyright for catalog changes. [Dmitry] -Fix dt_binding_check tool errors(update reg address as address-cells and size-cells of root node one and maintain the same for child nodes of mdss, added additionalProperties in schema). [Rob, Bjorn, Krzysztof] -Add QCOM_ICC_TAG_ACTIVE_ONLY interconnect path tag to mdp0-mem and mdp1-mem path in devicetree. [Dmitry] -Update commit subject and message for DT change. [Dmitry] -Remove interconnect path tags from dt bindings. (ref sm8450-mdss yaml) [v2] - Updated cover letter subject and message. [Dmitry] - Use fake DISPCC nodes to avoid clock dependencies in dt-bindings. [Dmitry] - Update bindings by fixing dt_binding_check tool errors (update includes in example), adding proper spacing and indentation in the binding example, droping unused labels, droping status disable, adding reset node. [Dmitry, Rob, Krzysztof] - Reorder compatible string of MDSS and DPU based on alphabetical order.[Dmitry] - add reg_bus_bw in msm_mdss_data. [Dmitry] - Fix indentation in the devicetree. [Dmitry] -- 2.34.1 --- Mahadevan (5): dt-bindings: display/msm: Document MDSS on SA8775P dt-bindings: display/msm: Document the DPU for SA8775P drm/msm: mdss: Add SA8775P support drm/msm/dpu: Add SA8775P support arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 ++ .../bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + drivers/gpu/drm/msm/msm_mdss.c | 11 + 8 files changed, 830 insertions(+) --- base-commit: e390603cfa79c860ed35e073f5fe77805b067a8e change-id: 20240930-patchv3_1-600cbc1549e8 Best regards,
Re: [PATCH v4 0/5] Display enablement changes for Qualcomm SA8775P platform
On Sat, Oct 19, 2024 at 09:13:23PM +0530, Mahadevan P wrote: > I apologize for the inconvenience caused by uploading the incorrect patch > (v4). Kindly disregard it. One thing makes me wonder. You are using b4 tool. It should handle versioning, changelogs, etc for you. However despite all of that you somehow have sent a duplicate version of the patchset. And the changelog also doesn't follow B4 style (which is useful BTW). Could you (and possibly some of your colleagues) please stop doing whatever strange things you are doing and just use the tool properly? This way, each time you send a series you'll get an automatic version rollup _and_ a properly formatted changelog with all the links to the previous iterations, etc. Please stop making your life harder than it is and just use the tool in a way it should be used. At the same time it will make our (maintainers / reviewers) life much easier. Thank you. > > On 10/19/2024 8:46 PM, Mahadevan wrote: > > This series introduces support to enable the Mobile Display Subsystem (MDSS) > > and Display Processing Unit (DPU) for the Qualcomm SA8775P target. It > > includes the addition of the hardware catalog, compatible string, > > relevant device tree changes, and their YAML bindings. > > > > --- > > In this series > > - PATCH 1: "dt-bindings: display/msm: Document MDSS on SA8775P" depends on > > dp > >binding documetion in this change: > > > > https://lore.kernel.org/all/20240923113150.24711-5-quic_mukho...@quicinc.com/ > > - PATCH 5: "arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and > > DPU" > >depends on the clock enablement change: > > > > https://lore.kernel.org/all/20240816-sa8775p-mm-v3-v1-0-77d53c3c0...@quicinc.com/ > > > > --- > > [v5] > > - Update clock-name of display-controller in MDSS documentation to align > > with > >qcom,sm8650-dpu.yaml. [Rob] > > - Update power-domains of display-controller in DT to do proper voting on > > MMCX > >rail. [Internal Review] > > > > [v4] > > - Removed new YAML added for sa8775p dpu dt-binding documention as it is > > similar > >to qcom,sm8650-dpu.yaml and added the compatible in same. [Krzysztof] > > > > [v3] > > -Edited copyright for catalog changes. [Dmitry] > > -Fix dt_binding_check tool errors(update reg address as address-cells and > > size-cells of root node one and maintain the same for child nodes of mdss, > > added additionalProperties in schema). > > [Rob, Bjorn, Krzysztof] > > -Add QCOM_ICC_TAG_ACTIVE_ONLY interconnect path tag to mdp0-mem and mdp1-mem > > path in devicetree. [Dmitry] > > -Update commit subject and message for DT change. [Dmitry] > > -Remove interconnect path tags from dt bindings. (ref sm8450-mdss yaml) > > > > [v2] > > - Updated cover letter subject and message. [Dmitry] > > - Use fake DISPCC nodes to avoid clock dependencies in dt-bindings. [Dmitry] > > - Update bindings by fixing dt_binding_check tool errors (update includes > > in example), > >adding proper spacing and indentation in the binding example, droping > > unused labels, > >droping status disable, adding reset node. [Dmitry, Rob, Krzysztof] > > - Reorder compatible string of MDSS and DPU based on alphabetical > > order.[Dmitry] > > - add reg_bus_bw in msm_mdss_data. [Dmitry] > > - Fix indentation in the devicetree. [Dmitry] > > > > -- > > 2.34.1 > > > > --- > > Mahadevan (5): > >dt-bindings: display/msm: Document MDSS on SA8775P > >dt-bindings: display/msm: Document the DPU for SA8775P > >drm/msm: mdss: Add SA8775P support > >drm/msm/dpu: Add SA8775P support > >arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU > > > > .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 ++ > > .../bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + > > arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 > > .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 > > + > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + > > drivers/gpu/drm/msm/msm_mdss.c | 11 + > > 8 files changed, 830 insertions(+) > > --- > > base-commit: e390603cfa79c860ed35e073f5fe77805b067a8e > > change-id: 20240930-patchv3_1-600cbc1549e8 > > > > Best regards, -- With best wishes Dmitry
[PATCH v4 2/5] dt-bindings: display/msm: Document the DPU for SA8775P
Document the DPU for Qualcomm SA8775P platform. Signed-off-by: Mahadevan --- Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml index c4087cc5abbdd44885a6755e1facda767a16f35d..01cf79bd754b491349c52c5aef49ba06e835d0bf 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml @@ -14,6 +14,7 @@ $ref: /schemas/display/msm/dpu-common.yaml# properties: compatible: enum: + - qcom,sa8775p-dpu - qcom,sm8650-dpu - qcom,x1e80100-dpu -- 2.34.1
Re: [PATCH v17 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
On Mon, Sep 30, 2024 at 10:18:06AM +0200, Maxime Ripard wrote: > On Sun, Sep 29, 2024 at 02:34:36AM GMT, Sandor Yu wrote: > > > > +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp) > > > > +{ > > > > + struct drm_display_info *display = > > > > &mhdp->curr_conn->display_info; > > > > + struct drm_connector_state *conn_state = mhdp->curr_conn->state; > > > > > > That looks a bit hackish to me. We should probably provide a helper to > > > get the > > > connector state the bridge is attached to. > > > > How about code change to followed, is it more clear? > > 370 struct drm_connector *connector = mhdp->curr_conn; > > 371 struct drm_connector_state *conn_state = connector->state; > > 372 struct drm_display_info *display = &connector->display_info; > > 373 struct drm_scdc *scdc = &display->hdmi.scdc; > > What I meant was that I wish bridges had a way to get their connector > pointer. It doesn't look like it's possible with drm_bridge_connector, > and we don't have access to drm_display_info anymore. > > I don't really see a good way to do this yet, so maybe that kind of > workaround is ok. Eventually, I guess we'll have the scrambler setup in > the HDMI connector helpers anyway. > > Dmitry, any idea? Unfortunately nothing significant, I didn't have time to look at the scrambler yet. The platforms that I'm working with either do not support HDMI 2.0 or require no additional setup there. Regarding the drm_connector_state, I had to go via the bridge->encoder, then drm_atomic_get_new_connector_for_encoder() and finally drm_atomic_get_new_connector_state(). I don't like the idea of storing the connector in drm_bridge driver data, it seems like a bad idea to me. > > > > > +static enum drm_mode_status > > > > +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, > > > > + const struct drm_display_mode *mode, > > > > + unsigned long long tmds_rate) { > > > > + struct cdns_mhdp8501_device *mhdp = bridge->driver_private; > > > > + union phy_configure_opts phy_cfg; > > > > + int ret; > > > > + > > > > + phy_cfg.hdmi.tmds_char_rate = tmds_rate; > > > > + > > > > + ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg); > > > > + if (ret < 0) > > > > + return MODE_CLOCK_RANGE; > > > > + > > > > + return MODE_OK; > > > > +} > > > > + > > > > +static enum drm_mode_status > > > > +cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge, > > > > + const struct drm_display_info *info, > > > > + const struct drm_display_mode *mode) { > > > > + unsigned long long tmds_rate; > > > > + > > > > + /* We don't support double-clocked and Interlaced modes */ > > > > + if (mode->flags & DRM_MODE_FLAG_DBLCLK || > > > > + mode->flags & DRM_MODE_FLAG_INTERLACE) > > > > + return MODE_BAD; > > > > + > > > > + if (mode->hdisplay > 3840) > > > > + return MODE_BAD_HVALUE; > > > > + > > > > + if (mode->vdisplay > 2160) > > > > + return MODE_BAD_VVALUE; > > > > + > > > > + tmds_rate = mode->clock * 1000ULL; > > > > + return cdns_hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate); > > > > } > > > > > > Didn't we agree on creating a mode_valid helper? > > > > In fact, now I'm no idea where should add the mode_valid helper function. > > > > In struct drm_bridge_funcs, it had mode_valid() and > > hdmi_tmds_char_rate_valid(). > > > > If create a new mode_valid helper function in struct > > drm_connector_hdmi_funcs, > > Is it appropriate to call another API function(tmds_char_rate_valid) > > at the same level within this API function? > > I'm not quite sure what you mean, but a reasonable approach to me would > be to turn drm_hdmi_state_helper.c hdmi_clock_valid into a public > function, and then call it from drm_bridge_connector mode_valid hook. > > It's a similar discussion to the previous one really: in order to > implement it properly, we need access to drm_display_info. I've sent a proposal, [1]. I don't think we should be using hdmi_clock_valid() directly (at least not before sorting out the EDID / hotplug handling in the HDMI Connector code) exactly because of the info->max_tmds_clock. If it gets stale, we might filter modes incorrectly. Also, I'm not sure if it should be left at 0 by default (or in drm_parse_hdmi_forum_scds()). [1] https://lore.kernel.org/dri-devel/20241018-hdmi-mode-valid-v1-0-6e49ae480...@linaro.org/ -- With best wishes Dmitry
Re: [PATCH v2 1/2] dt-bindings: display: panel-simple: Document support for Microchip AC69T88A
On Thu, 19 Sep 2024 14:45:47 +0530, Manikandan Muralidharan wrote: > Add Microchip AC69T88A 5" LVDS interface (800x480) TFT LCD panel > compatible string > > Applied to drm-misc-next, thanks! [1/2] dt-bindings: display: panel-simple: Document support for Microchip AC69T88A commit: c3f0b90f6ffc178bf158aeccae268276363d6945 [2/2] drm/panel: simple: Add Microchip AC69T88A LVDS Display panel commit: 40da1463cd6879f542238b36c1148f517927c595 Best regards, -- With best wishes Dmitry
Re: [PATCH 0/6] drm/display: hdmi: add drm_hdmi_connector_mode_valid()
On Sat, Oct 19, 2024 at 4:34 AM Dmitry Baryshkov wrote: > > Several HDMI drivers have common code pice in the .mode_valid function > that validates RGB / 8bpc rate using the TMDS char rate callbacks. > > Move this code piece to the common helper and remove the need to perform > this check manually. In case of DRM_BRIDGE_OP_HDMI bridges the check can > be dropped in favour of performing it in drm_bridge_connector. > > Signed-off-by: Dmitry Baryshkov Makes sense, code looks like a correct substitution, and AFAICT covers all current in tree drivers. Whole series is Reviewed-by: Chen-Yu Tsai > --- > Dmitry Baryshkov (6): > drm/display: hdmi: add generic mode_valid helper > drm/sun4i: use drm_hdmi_connector_mode_valid() > drm/vc4: use drm_hdmi_connector_mode_valid() > drm/display: bridge_connector: use drm_bridge_connector_mode_valid() > drm/bridge: lontium-lt9611: drop TMDS char rate check in mode_valid > drm/bridge: dw-hdmi-qp: replace mode_valid with tmds_char_rate > > drivers/gpu/drm/bridge/lontium-lt9611.c| 4 +--- > drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 12 +--- > drivers/gpu/drm/display/drm_bridge_connector.c | 16 +++- > drivers/gpu/drm/display/drm_hdmi_helper.c | 25 + > drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 12 +--- > drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +--- > include/drm/display/drm_hdmi_helper.h | 4 > 7 files changed, 52 insertions(+), 25 deletions(-) > --- > base-commit: af44b5b5776cc6ac1891393a37b1424509f07b35 > change-id: 20241018-hdmi-mode-valid-aaec4428501c > > Best regards, > -- > Dmitry Baryshkov >
Re: [PATCH 0/6] drm: Series with core improvements/refactorings
On Sun, Sep 08, 2024 at 02:04:45PM +0200, Heiner Kallweit wrote: > Series with DRM core improvements/refactorings. > > Heiner Kallweit (6): > drm/sysfs: Remove version attribute > drm/sysfs: Drop unused drm_class_device_(un)register > drm: Refactor drm_core_init error path > drm: Change drm_class from pointer to const struct class > drm: Add __init annotations > drm/sysfs: Remove device type drm_minor > > drivers/accel/drm_accel.c| 2 +- > drivers/gpu/drm/drm_cache.c | 2 +- > drivers/gpu/drm/drm_connector.c | 2 +- > drivers/gpu/drm/drm_drv.c| 18 +++-- > drivers/gpu/drm/drm_internal.h | 2 +- > drivers/gpu/drm/drm_panic.c | 4 +- > drivers/gpu/drm/drm_privacy_screen.c | 2 +- > drivers/gpu/drm/drm_privacy_screen_x86.c | 2 +- > drivers/gpu/drm/drm_sysfs.c | 89 +--- > include/drm/drm_sysfs.h | 3 - > 10 files changed, 39 insertions(+), 87 deletions(-) Heiner, any chance of a respin? I think most of the cleanups were good, needing just minor polishing. -- With best wishes Dmitry
[PATCH v4 0/5] Display enablement changes for Qualcomm SA8775P platform
This series introduces support to enable the Mobile Display Subsystem (MDSS) and Display Processing Unit (DPU) for the Qualcomm SA8775P target. It includes the addition of the hardware catalog, compatible string, relevant device tree changes, and their YAML bindings. --- In this series - PATCH 1: "dt-bindings: display/msm: Document MDSS on SA8775P" depends on dp binding documetion in this change: https://lore.kernel.org/all/20240923113150.24711-5-quic_mukho...@quicinc.com/ - PATCH 5: "arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU" depends on the clock enablement change: https://lore.kernel.org/all/20240816-sa8775p-mm-v3-v1-0-77d53c3c0...@quicinc.com/ --- [v5] - Update clock-name of display-controller in MDSS documentation to align with qcom,sm8650-dpu.yaml. [Rob] - Update power-domains of display-controller in DT to do proper voting on MMCX rail. [Internal Review] [v4] - Removed new YAML added for sa8775p dpu dt-binding documention as it is similar to qcom,sm8650-dpu.yaml and added the compatible in same. [Krzysztof] [v3] -Edited copyright for catalog changes. [Dmitry] -Fix dt_binding_check tool errors(update reg address as address-cells and size-cells of root node one and maintain the same for child nodes of mdss, added additionalProperties in schema). [Rob, Bjorn, Krzysztof] -Add QCOM_ICC_TAG_ACTIVE_ONLY interconnect path tag to mdp0-mem and mdp1-mem path in devicetree. [Dmitry] -Update commit subject and message for DT change. [Dmitry] -Remove interconnect path tags from dt bindings. (ref sm8450-mdss yaml) [v2] - Updated cover letter subject and message. [Dmitry] - Use fake DISPCC nodes to avoid clock dependencies in dt-bindings. [Dmitry] - Update bindings by fixing dt_binding_check tool errors (update includes in example), adding proper spacing and indentation in the binding example, droping unused labels, droping status disable, adding reset node. [Dmitry, Rob, Krzysztof] - Reorder compatible string of MDSS and DPU based on alphabetical order.[Dmitry] - add reg_bus_bw in msm_mdss_data. [Dmitry] - Fix indentation in the devicetree. [Dmitry] -- 2.34.1 --- Mahadevan (5): dt-bindings: display/msm: Document MDSS on SA8775P dt-bindings: display/msm: Document the DPU for SA8775P drm/msm: mdss: Add SA8775P support drm/msm/dpu: Add SA8775P support arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 ++ .../bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + drivers/gpu/drm/msm/msm_mdss.c | 11 + 8 files changed, 830 insertions(+) --- base-commit: e390603cfa79c860ed35e073f5fe77805b067a8e change-id: 20240930-patchv3_1-600cbc1549e8 Best regards, -- Mahadevan
[PATCH v4 4/5] drm/msm/dpu: Add SA8775P support
Add definitions for the display hardware used on the Qualcomm SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + 4 files changed, 488 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h new file mode 100644 index ..907b4d7ceb470b0391d2bbbab3ce520efa2b3263 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -0,0 +1,485 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DPU_8_4_SA8775P_H +#define _DPU_8_4_SA8775P_H + +static const struct dpu_caps sa8775p_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_mdp_cfg sa8775p_mdp = { + .name = "top_0", + .base = 0x0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ +static const struct dpu_ctl_cfg sa8775p_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sa8775p_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_1", .id = SSPP_VIG1, + .base = 0x6000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 4, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG1, + }, { + .name = "sspp_2", .id = SSPP_VIG2, + .base = 0x8000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 8, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG2, + }, { + .name = "sspp_3", .id = SSPP_VIG3, + .base = 0xa000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_
[PATCH v4 5/5] arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU
Add devicetree changes to enable MDSS0 display-subsystem its display-controller(DPU) for Qualcomm SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 +++ 1 file changed, 89 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi index 8fd68a8aa916e6595134b470f87b18b509178a51..5f6b7b59ec707490b162649d0fd97f85b1489e45 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -2937,6 +2938,94 @@ camcc: clock-controller@ade { #power-domain-cells = <1>; }; + mdss0: display-subsystem@ae0 { + compatible = "qcom,sa8775p-mdss"; + reg = <0x0 0x0ae0 0x0 0x1000>; + reg-names = "mdss"; + + /* same path used twice */ + interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY +&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_MDP1 QCOM_ICC_TAG_ACTIVE_ONLY +&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY +&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", +"mdp1-mem", +"cpu-cfg"; + + resets = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_BCR>; + + power-domains = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_GDSC>; + + clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, +<&gcc GCC_DISP_HF_AXI_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x1000 0x402>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss0_mdp: display-controller@ae01000 { + compatible = "qcom,sa8775p-dpu"; + reg = <0x0 0x0ae01000 0x0 0x8f000>, + <0x0 0x0aeb 0x0 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <1920>; + + operating-points-v2 = <&mdss0_mdp_opp_table>; + power-domains = <&rpmhpd SA8775P_MMCX>; + + interrupt-parent = <&mdss0>; + interrupts = <0>; + + mdss0_mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500 { + opp-hz = /bits/ 64 <37500>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-5 { + opp-hz = /bits/ 64 <5>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-57500 { + opp-hz = /bits/ 64 <57500>; + required-opps = <&rpmhpd_opp_turbo>; + }; + + opp-65000 { + opp-hz = /bits/ 64 <65000>;
[PATCH v5 0/5] Display enablement changes for Qualcomm SA8775P platform
This series introduces support to enable the Mobile Display Subsystem (MDSS) and Display Processing Unit (DPU) for the Qualcomm SA8775P target. It includes the addition of the hardware catalog, compatible string, relevant device tree changes, and their YAML bindings. --- In this series - PATCH 1: "dt-bindings: display/msm: Document MDSS on SA8775P" depends on dp binding documetion in this change: https://lore.kernel.org/all/20240923113150.24711-5-quic_mukho...@quicinc.com/ - PATCH 5: "arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU" depends on the clock enablement change: https://lore.kernel.org/all/20240816-sa8775p-mm-v3-v1-0-77d53c3c0...@quicinc.com/ --- [v5] - Update clock-name of display-controller in MDSS documentation to align with qcom,sm8650-dpu.yaml. [Rob] - Update power-domains of display-controller in DT to do proper voting on MMCX rail. [Internal Review] [v4] - Removed new YAML added for sa8775p dpu dt-binding documention as it is similar to qcom,sm8650-dpu.yaml and added the compatible in same. [Krzysztof] [v3] -Edited copyright for catalog changes. [Dmitry] -Fix dt_binding_check tool errors(update reg address as address-cells and size-cells of root node one and maintain the same for child nodes of mdss, added additionalProperties in schema). [Rob, Bjorn, Krzysztof] -Add QCOM_ICC_TAG_ACTIVE_ONLY interconnect path tag to mdp0-mem and mdp1-mem path in devicetree. [Dmitry] -Update commit subject and message for DT change. [Dmitry] -Remove interconnect path tags from dt bindings. (ref sm8450-mdss yaml) [v2] - Updated cover letter subject and message. [Dmitry] - Use fake DISPCC nodes to avoid clock dependencies in dt-bindings. [Dmitry] - Update bindings by fixing dt_binding_check tool errors (update includes in example), adding proper spacing and indentation in the binding example, droping unused labels, droping status disable, adding reset node. [Dmitry, Rob, Krzysztof] - Reorder compatible string of MDSS and DPU based on alphabetical order.[Dmitry] - add reg_bus_bw in msm_mdss_data. [Dmitry] - Fix indentation in the devicetree. [Dmitry] -- 2.34.1 --- --- Mahadevan (5): dt-bindings: display/msm: Document MDSS on SA8775P dt-bindings: display/msm: Document the DPU for SA8775P drm/msm: mdss: Add SA8775P support drm/msm/dpu: Add SA8775P support arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU .../bindings/display/msm/qcom,sa8775p-mdss.yaml| 241 ++ .../bindings/display/msm/qcom,sm8650-dpu.yaml | 1 + arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 .../drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h| 485 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + drivers/gpu/drm/msm/msm_mdss.c | 11 + 8 files changed, 830 insertions(+) --- base-commit: e390603cfa79c860ed35e073f5fe77805b067a8e change-id: 20240930-patchv3_1-600cbc1549e8 Best regards, -- Mahadevan
[PATCH v5 5/5] arm64: dts: qcom: sa8775p: add display dt nodes for MDSS0 and DPU
Add devicetree changes to enable MDSS0 display-subsystem its display-controller(DPU) for Qualcomm SA8775P platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Mahadevan --- arch/arm64/boot/dts/qcom/sa8775p.dtsi | 89 +++ 1 file changed, 89 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi index 8fd68a8aa916e6595134b470f87b18b509178a51..5f6b7b59ec707490b162649d0fd97f85b1489e45 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -2937,6 +2938,94 @@ camcc: clock-controller@ade { #power-domain-cells = <1>; }; + mdss0: display-subsystem@ae0 { + compatible = "qcom,sa8775p-mdss"; + reg = <0x0 0x0ae0 0x0 0x1000>; + reg-names = "mdss"; + + /* same path used twice */ + interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY +&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_MDP1 QCOM_ICC_TAG_ACTIVE_ONLY +&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY +&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", +"mdp1-mem", +"cpu-cfg"; + + resets = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_BCR>; + + power-domains = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_GDSC>; + + clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, +<&gcc GCC_DISP_HF_AXI_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x1000 0x402>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss0_mdp: display-controller@ae01000 { + compatible = "qcom,sa8775p-dpu"; + reg = <0x0 0x0ae01000 0x0 0x8f000>, + <0x0 0x0aeb 0x0 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>, +<&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <1920>; + + operating-points-v2 = <&mdss0_mdp_opp_table>; + power-domains = <&rpmhpd SA8775P_MMCX>; + + interrupt-parent = <&mdss0>; + interrupts = <0>; + + mdss0_mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-37500 { + opp-hz = /bits/ 64 <37500>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-5 { + opp-hz = /bits/ 64 <5>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-57500 { + opp-hz = /bits/ 64 <57500>; + required-opps = <&rpmhpd_opp_turbo>; + }; + + opp-65000 { + opp-hz = /bits/ 64 <65000>;
Re: fw_devlinks preventing a panel driver from probing
On Fri, Oct 04, 2024 at 02:52:24PM +0300, Tomi Valkeinen wrote: > Hi Dmitry, > > On 27/09/2024 11:35, Dmitry Baryshkov wrote: > > On Fri, 27 Sept 2024 at 08:41, Tomi Valkeinen > > wrote: > > > > > > On 27/09/2024 02:26, Dmitry Baryshkov wrote: > > > > On Thu, Sep 26, 2024 at 02:52:35PM GMT, Tomi Valkeinen wrote: > > > > > Hi, > > > > > > > > > > On 21/09/2024 23:15, Dmitry Baryshkov wrote: > > > > > > On Mon, Sep 16, 2024 at 02:51:57PM GMT, Tomi Valkeinen wrote: > > > > > > > Hi, > > > > > > > > > > > > > > We have an issue where two devices have dependencies to each > > > > > > > other, > > > > > > > according to drivers/base/core.c's fw_devlinks, and this prevents > > > > > > > them from > > > > > > > probing. I've been adding debugging to the core.c, but so far I > > > > > > > don't quite > > > > > > > grasp the issue, so I thought to ask. Maybe someone can instantly > > > > > > > say that > > > > > > > this just won't work... > > > > > > > > > > > > Well, just 2c from my side. I consider that fw_devlink adds > > > > > > devlinks for > > > > > > of-graph nodes to be a bug. It doesn't know about the actual > > > > > > direction > > > > > > of dependencies between corresponding devices or about the actual > > > > > > relationship between drivers. It results in a loop which is then > > > > > > broken > > > > > > in some way. Sometimes this works. Sometimes it doesn't. Sometimes > > > > > > this > > > > > > hides actual dependencies between devices. I tried reverting > > > > > > offending > > > > > > parts of devlink, but this attempt failed. > > > > > > > > > > I was also wondering about this. The of-graphs are always two-way > > > > > links, so > > > > > the system must always mark them as a cycle. But perhaps there are > > > > > other > > > > > benefits in the devlinks than dependency handling? > > > > > > > > > > > > If I understand the fw_devlink code correctly, in a normal case > > > > > > > the links > > > > > > > formed with media graphs are marked as a cycle > > > > > > > (FWLINK_FLAG_CYCLE), and then > > > > > > > ignored as far as probing goes. > > > > > > > > > > > > > > What we see here is that when using a single-link OLDI panel, the > > > > > > > panel > > > > > > > driver's probe never gets called, as it depends on the OLDI, and > > > > > > > the link > > > > > > > between the panel and the OLDI is not a cycle. > > > > > > > > > > > > I think in your case you should be able to fix the issue by using > > > > > > the > > > > > > FWNODE_FLAG_NOT_DEVICE, which is intented to be used in such cases. > > > > > > You > > > > > > > > > > How would I go using FWNODE_FLAG_NOT_DEVICE? Won't this only make a > > > > > difference if the flag is there at early stage when the linux devices > > > > > are > > > > > being created? I think it's too late if I set the flag when the dss > > > > > driver > > > > > is being probed. > > > > > > > > I think you have the NOT_DEVICE case as the DSS device corresponds to > > > > the parent of your OLDI nodes. There is no device which corresponds to > > > > the oldi@0 / oldi@1 device nodes (which contain corresponding port > > > > nodes). > > > > > > Do you mean that I should already see FWNODE_FLAG_NOT_DEVICE set in the > > > fwnode? > > > > No, I think you should set it for you DSS links. If I understand > > correctly, this should prevent fwdevlink from waiting on the OLDI to > > materialize as a device. > > Note: my understanding is based on a quick roaming through the code > > some time ago. > > Ok. Well, I did experiment with that, but I didn't figure out how to use it. > Afaics, even if I set FWNODE_FLAG_NOT_DEVICE to the oldi nodes (just as an > experiment I also set it to all the nodes from dss to oldi) in the DSS > driver's probe, it doesn't help: the panel driver still doesn't probe. > > I also wonder whether it would work reliably even if it did work. First the > panel driver is prevented from probing as the oldi dependency is not > present. Then the DSS driver probes, sets the above flag, but then it fails > to probe as the panel is missing. At this point something should trigger the > probing of the panel driver again, and I wonder if there's anything to > trigger it. My thought was that the flag should be set before panel / DSS drivers being probed. -- With best wishes Dmitry
[PATCH v5 01/13] drm/bridge: cdns-dsi: Fix connecting to next bridge
From: Aradhya Bhatia Fix the OF node pointer passed to the of_drm_find_bridge() call to find the next bridge in the display chain. The code to find the next panel (and create its panel-bridge) works fine, but to find the next (non-panel) bridge does not. To find the next bridge in the pipeline, we need to pass "np" - the OF node pointer of the next entity in the devicetree chain. Passing "of_node" to of_drm_find_bridge (which is what the code does currently) will fetch the bridge for the cdns-dsi which is not what's required. Fix that. Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Reviewed-by: Dmitry Baryshkov Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 7457d38622b0..b016f2ba06bb 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -952,7 +952,7 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, bridge = drm_panel_bridge_add_typed(panel, DRM_MODE_CONNECTOR_DSI); } else { - bridge = of_drm_find_bridge(dev->dev.of_node); + bridge = of_drm_find_bridge(np); if (!bridge) bridge = ERR_PTR(-EINVAL); } -- 2.34.1
[PATCH v5 10/13] drm/bridge: cdns-dsi: Move DSI mode check to _atomic_check()
From: Aradhya Bhatia At present, the DSI mode configuration check happens during the _atomic_enable() phase, which is not really the best place for this. Moreover, if the mode is not valid, the driver gives a warning and continues the hardware configuration. Move the DSI mode configuration check to _atomic_check() instead, which can properly report back any invalid mode, before the _enable phase even begins. Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 18 +++--- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 7341e609dc8b..79d8c2264c14 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -769,7 +769,7 @@ static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_display_mode *mode; struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long tx_byte_period; - struct cdns_dsi_cfg dsi_cfg; + struct cdns_dsi_cfg dsi_cfg = dsi->dsi_cfg; u32 tmp, reg_wakeup, div, status; int nlanes; @@ -782,8 +782,6 @@ static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge, mode = &bridge->encoder->crtc->state->adjusted_mode; nlanes = output->dev->lanes; - WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false)); - cdns_dsi_init_link(dsi); cdns_dsi_hs_init(dsi); @@ -954,6 +952,19 @@ static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, return input_fmts; } +static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); + struct cdns_dsi *dsi = input_to_dsi(input); + struct drm_display_mode *mode = &crtc_state->mode; + struct cdns_dsi_cfg *dsi_cfg = &dsi->dsi_cfg; + + return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); +} + static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = { .attach = cdns_dsi_bridge_attach, .mode_valid = cdns_dsi_bridge_mode_valid, @@ -961,6 +972,7 @@ static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = { .atomic_pre_enable = cdns_dsi_bridge_atomic_pre_enable, .atomic_enable = cdns_dsi_bridge_atomic_enable, .atomic_post_disable = cdns_dsi_bridge_atomic_post_disable, + .atomic_check = cdns_dsi_bridge_atomic_check, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h index 5db5dbbbcaad..b785df45bc59 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h @@ -77,6 +77,7 @@ struct cdns_dsi { bool link_initialized; bool phy_initialized; struct phy *dphy; + struct cdns_dsi_cfg dsi_cfg; }; #endif /* !__CDNS_DSI_H__ */ -- 2.34.1
[PATCH v5 02/13] drm/bridge: cdns-dsi: Move to devm_drm_of_get_bridge()
From: Aradhya Bhatia Instead of manually finding the next bridge/panel, and maintaining the panel-bridge (in-case the next entity is a panel), switch to using the automatically managing devm_drm_of_get_bridge() API. Drop the drm_panel support completely from the driver while at it. Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- .../gpu/drm/bridge/cadence/cdns-dsi-core.c| 28 ++- .../gpu/drm/bridge/cadence/cdns-dsi-core.h| 2 -- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index b016f2ba06bb..5159c3f0853e 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -920,8 +920,6 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, struct cdns_dsi_output *output = &dsi->output; struct cdns_dsi_input *input = &dsi->input; struct drm_bridge *bridge; - struct drm_panel *panel; - struct device_node *np; int ret; /* @@ -939,26 +937,10 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, /* * The host <-> device link might be described using an OF-graph * representation, in this case we extract the device of_node from -* this representation, otherwise we use dsidev->dev.of_node which -* should have been filled by the core. +* this representation. */ - np = of_graph_get_remote_node(dsi->base.dev->of_node, DSI_OUTPUT_PORT, - dev->channel); - if (!np) - np = of_node_get(dev->dev.of_node); - - panel = of_drm_find_panel(np); - if (!IS_ERR(panel)) { - bridge = drm_panel_bridge_add_typed(panel, - DRM_MODE_CONNECTOR_DSI); - } else { - bridge = of_drm_find_bridge(np); - if (!bridge) - bridge = ERR_PTR(-EINVAL); - } - - of_node_put(np); - + bridge = devm_drm_of_get_bridge(dsi->base.dev, dsi->base.dev->of_node, + DSI_OUTPUT_PORT, dev->channel); if (IS_ERR(bridge)) { ret = PTR_ERR(bridge); dev_err(host->dev, "failed to add DSI device %s (err = %d)", @@ -968,7 +950,6 @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, output->dev = dev; output->bridge = bridge; - output->panel = panel; /* * The DSI output has been properly configured, we can now safely @@ -984,12 +965,9 @@ static int cdns_dsi_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *dev) { struct cdns_dsi *dsi = to_cdns_dsi(host); - struct cdns_dsi_output *output = &dsi->output; struct cdns_dsi_input *input = &dsi->input; drm_bridge_remove(&input->bridge); - if (output->panel) - drm_panel_bridge_remove(output->bridge); return 0; } diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h index ca7ea2da635c..5db5dbbbcaad 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -21,7 +20,6 @@ struct reset_control; struct cdns_dsi_output { struct mipi_dsi_device *dev; - struct drm_panel *panel; struct drm_bridge *bridge; union phy_configure_opts phy_opts; }; -- 2.34.1
Re: [PATCH v6 03/10] drm/bridge: it6505: add AUX operation for HDCP KSV list read
Hi Hermes, kernel test robot noticed the following build errors: [auto build test ERROR on b8128f7815ff135f0333c1b46dcdf1543c41b860] url: https://github.com/intel-lab-lkp/linux/commits/Hermes-Wu-via-B4-Relay/drm-bridge-it6505-Change-definition-of-AUX_FIFO_MAX_SIZE/20241016-155607 base: b8128f7815ff135f0333c1b46dcdf1543c41b860 patch link: https://lore.kernel.org/r/20241016-upstream-v6-v6-3-4d93a0c46de1%40ite.com.tw patch subject: [PATCH v6 03/10] drm/bridge: it6505: add AUX operation for HDCP KSV list read config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20241020/202410200624.sr8sf1ya-...@intel.com/config) compiler: m68k-linux-gcc (GCC) 14.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241020/202410200624.sr8sf1ya-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202410200624.sr8sf1ya-...@intel.com/ All errors (new ones prefixed by >>): drivers/gpu/drm/bridge/ite-it6505.c: In function 'it6505_aux_operation': >> drivers/gpu/drm/bridge/ite-it6505.c:1004:47: error: implicit declaration of >> function 'FIELD_GET' [-Wimplicit-function-declaration] 1004 | it6505_write(it6505, REG_AUX_CMD_REQ, FIELD_GET(M_AUX_REQ_CMD, cmd)); | ^ Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for GET_FREE_REGION Depends on [n]: SPARSEMEM [=n] Selected by [m]: - RESOURCE_KUNIT_TEST [=m] && RUNTIME_TESTING_MENU [=y] && KUNIT [=m] vim +/FIELD_GET +1004 drivers/gpu/drm/bridge/ite-it6505.c 956 957 static ssize_t it6505_aux_operation(struct it6505 *it6505, 958 enum aux_cmd_type cmd, 959 unsigned int address, u8 *buffer, 960 size_t size, enum aux_cmd_reply *reply) 961 { 962 int i, ret; 963 bool aux_write_check = false; 964 965 if (!it6505_get_sink_hpd_status(it6505)) 966 return -EIO; 967 968 /* set AUX user mode */ 969 it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, AUX_USER_MODE); 970 971 aux_op_start: 972 /* HW AUX FIFO supports only EDID and DCPD KSV FIFO area */ 973 if (cmd == CMD_AUX_I2C_EDID_READ || cmd == CMD_AUX_GET_KSV_LIST) { 974 /* AUX EDID FIFO has max length of AUX_FIFO_MAX_SIZE bytes. */ 975 size = min_t(size_t, size, AUX_FIFO_MAX_SIZE); 976 /* Enable AUX FIFO read back and clear FIFO */ 977 it6505_set_bits(it6505, REG_AUX_CTRL, 978 AUX_EN_FIFO_READ | CLR_EDID_FIFO, 979 AUX_EN_FIFO_READ | CLR_EDID_FIFO); 980 981 it6505_set_bits(it6505, REG_AUX_CTRL, 982 AUX_EN_FIFO_READ | CLR_EDID_FIFO, 983 AUX_EN_FIFO_READ); 984 } else { 985 /* The DP AUX transmit buffer has 4 bytes. */ 986 size = min_t(size_t, size, 4); 987 it6505_set_bits(it6505, REG_AUX_CTRL, AUX_NO_SEGMENT_WR, 988 AUX_NO_SEGMENT_WR); 989 } 990 991 /* Start Address[7:0] */ 992 it6505_write(it6505, REG_AUX_ADR_0_7, (address >> 0) & 0xFF); 993 /* Start Address[15:8] */ 994 it6505_write(it6505, REG_AUX_ADR_8_15, (address >> 8) & 0xFF); 995 /* WriteNum[3:0]+StartAdr[19:16] */ 996 it6505_write(it6505, REG_AUX_ADR_16_19, 997 ((address >> 16) & 0x0F) | ((size - 1) << 4)); 998 999 if (cmd == CMD_AUX_NATIVE_WRITE) 1000 regmap_bulk_write(it6505->regmap, REG_AUX_OUT_DATA0, buffer, 1001size); 1002 1003 /* Aux Fire */ > 1004 it6505_write(it6505, REG_AUX_CMD_REQ, FIELD_GET(M_AUX_REQ_CMD, > cmd)); 1005 1006 ret = it6505_aux_wait(it6505); 1007 if (ret < 0) 1008 goto aux_op_err; 1009 1010 ret = it6505_read(it6505, REG_AUX_ERROR_STS); 1011 if (ret < 0) 1012 goto aux_op_err; 1013 1014 switch ((ret >> 6) & 0x3) { 1015 case 0: 1016 *reply = REPLY_ACK; 1017 break; 1018 case 1: 1019 *reply = REPLY_DEFER; 1020 ret = -EAGAIN; 1021 goto aux_op_err; 1022 case 2: 1023 *reply = REPLY_NACK; 1024 ret = -EIO; 1025 g
[PATCH v3 3/6] drm/xe: Update xe_ttm_access_memory to use GPU for non-visible access
Add migrate layer functions to access VRAM and update xe_ttm_access_memory to use for non-visible access. Signed-off-by: Matthew Brost --- drivers/gpu/drm/xe/xe_bo.c | 18 ++- drivers/gpu/drm/xe/xe_migrate.c | 267 drivers/gpu/drm/xe/xe_migrate.h | 4 + 3 files changed, 285 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 99557af16120..0a7b91df69c2 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -1133,13 +1133,22 @@ static int xe_ttm_access_memory(struct ttm_buffer_object *ttm_bo, if (!mem_type_is_vram(ttm_bo->resource->mem_type)) return -EIO; - /* FIXME: Use GPU for non-visible VRAM */ - if (!xe_ttm_resource_visible(ttm_bo->resource)) - return -EIO; - if (!xe_pm_runtime_get_if_in_use(xe)) return -EIO; + if (!xe_ttm_resource_visible(ttm_bo->resource) || len >= SZ_16K) { + struct xe_migrate *migrate = + mem_type_to_migrate(xe, ttm_bo->resource->mem_type); + int err; + + err = xe_migrate_access_memory(migrate, bo, offset, buf, len, + write); + if (err) + return err; + + goto out; + } + vram = res_to_mem_region(ttm_bo->resource); xe_res_first(ttm_bo->resource, offset & PAGE_MASK, bo->size, &cursor); @@ -1161,6 +1170,7 @@ static int xe_ttm_access_memory(struct ttm_buffer_object *ttm_bo, xe_res_next(&cursor, PAGE_SIZE); } while (bytes_left); +out: xe_pm_runtime_put(xe); return len; diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c index cfd31ae49cc1..ccdca1f79bb2 100644 --- a/drivers/gpu/drm/xe/xe_migrate.c +++ b/drivers/gpu/drm/xe/xe_migrate.c @@ -1542,6 +1542,273 @@ void xe_migrate_wait(struct xe_migrate *m) dma_fence_wait(m->fence, false); } +static u32 pte_update_cmd_size(u64 size) +{ + u32 dword; + u64 entries = DIV_ROUND_UP(size, XE_PAGE_SIZE); + + XE_WARN_ON(size > MAX_PREEMPTDISABLE_TRANSFER); + /* +* MI_STORE_DATA_IMM command is used to update page table. Each +* instruction can update maximumly 0x1ff pte entries. To update +* n (n <= 0x1ff) pte entries, we need: +* 1 dword for the MI_STORE_DATA_IMM command header (opcode etc) +* 2 dword for the page table's physical location +* 2*n dword for value of pte to fill (each pte entry is 2 dwords) +*/ + dword = (1 + 2) * DIV_ROUND_UP(entries, 0x1ff); + dword += entries * 2; + + return dword; +} + +static void build_pt_update_batch_sram(struct xe_migrate *m, + struct xe_bb *bb, u32 pt_offset, + dma_addr_t *sram_addr, u32 size) +{ + u16 pat_index = tile_to_xe(m->tile)->pat.idx[XE_CACHE_WB]; + u32 ptes; + int i = 0; + + ptes = DIV_ROUND_UP(size, XE_PAGE_SIZE); + while (ptes) { + u32 chunk = min(0x1ffU, ptes); + + bb->cs[bb->len++] = MI_STORE_DATA_IMM | MI_SDI_NUM_QW(chunk); + bb->cs[bb->len++] = pt_offset; + bb->cs[bb->len++] = 0; + + pt_offset += chunk * 8; + ptes -= chunk; + + while (chunk--) { + u64 addr = sram_addr[i++] & PAGE_MASK; + + xe_tile_assert(m->tile, addr); + addr = m->q->vm->pt_ops->pte_encode_addr(m->tile->xe, +addr, pat_index, +0, false, 0); + bb->cs[bb->len++] = lower_32_bits(addr); + bb->cs[bb->len++] = upper_32_bits(addr); + } + } +} + +enum xe_migrate_copy_dir { + XE_MIGRATE_COPY_TO_VRAM, + XE_MIGRATE_COPY_TO_SRAM, +}; + +static struct dma_fence *xe_migrate_vram(struct xe_migrate *m, +unsigned long len, +unsigned long sram_offset, +dma_addr_t *sram_addr, u64 vram_addr, +const enum xe_migrate_copy_dir dir) +{ + struct xe_gt *gt = m->tile->primary_gt; + struct xe_device *xe = gt_to_xe(gt); + struct dma_fence *fence = NULL; + u32 batch_size = 2; + u64 src_L0_ofs, dst_L0_ofs; + struct xe_sched_job *job; + struct xe_bb *bb; + u32 update_idx, pt_slot = 0; + unsigned long npages = DIV_ROUND_UP(len + sram_offset, PAGE_SIZE); + int err; + + xe_assert(xe, npages * PAGE_SIZE <= MAX_PREEMPTDISABLE_TRANSFER); + + batch_size += pte_update_cmd_size(len); + batch_size += EMI
[PATCH v3 4/6] drm/xe: Use ttm_bo_access in xe_vm_snapshot_capture_delayed
Non-contiguous mapping of BO in VRAM doesn't work, use ttm_bo_access instead. v2: - Fix error handling Fixes: 0eb2a18a8fad ("drm/xe: Implement VM snapshot support for BO's and userptr") Suggested-by: Matthew Auld Signed-off-by: Matthew Brost --- drivers/gpu/drm/xe/xe_vm.c | 17 ++--- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index c99380271de6..c8782da3a5c3 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -3303,7 +3303,6 @@ void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap) for (int i = 0; i < snap->num_snaps; i++) { struct xe_bo *bo = snap->snap[i].bo; - struct iosys_map src; int err; if (IS_ERR(snap->snap[i].data)) @@ -3316,16 +3315,12 @@ void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap) } if (bo) { - xe_bo_lock(bo, false); - err = ttm_bo_vmap(&bo->ttm, &src); - if (!err) { - xe_map_memcpy_from(xe_bo_device(bo), - snap->snap[i].data, - &src, snap->snap[i].bo_ofs, - snap->snap[i].len); - ttm_bo_vunmap(&bo->ttm, &src); - } - xe_bo_unlock(bo); + err = ttm_bo_access(&bo->ttm, snap->snap[i].bo_ofs, + snap->snap[i].data, snap->snap[i].len, 0); + if (!(err < 0) && err != snap->snap[i].len) + err = -EIO; + else if (!(err < 0)) + err = 0; } else { void __user *userptr = (void __user *)(size_t)snap->snap[i].bo_ofs; -- 2.34.1
[PATCH v3 1/6] drm/ttm: Add ttm_bo_access
Non-contiguous VRAM cannot easily be mapped in TTM nor can non-visible VRAM easily be accessed. Add ttm_bo_access, which is similar to ttm_bo_vm_access, to access such memory. Reported-by: Christoph Manszewski Suggested-by: Thomas Hellström Signed-off-by: Matthew Brost --- drivers/gpu/drm/ttm/ttm_bo_util.c | 86 +++ drivers/gpu/drm/ttm/ttm_bo_vm.c | 65 +-- include/drm/ttm/ttm_bo.h | 2 + 3 files changed, 89 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index d939925efa81..084d2e9b9123 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -919,3 +919,89 @@ s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev, return progress; } + +static int ttm_bo_access_kmap(struct ttm_buffer_object *bo, + unsigned long offset, + uint8_t *buf, int len, int write) +{ + unsigned long page = offset >> PAGE_SHIFT; + unsigned long bytes_left = len; + int ret; + + /* Copy a page at a time, that way no extra virtual address +* mapping is needed +*/ + offset -= page << PAGE_SHIFT; + do { + unsigned long bytes = min(bytes_left, PAGE_SIZE - offset); + struct ttm_bo_kmap_obj map; + void *ptr; + bool is_iomem; + + ret = ttm_bo_kmap(bo, page, 1, &map); + if (ret) + return ret; + + ptr = (uint8_t *)ttm_kmap_obj_virtual(&map, &is_iomem) + offset; + WARN_ON_ONCE(is_iomem); + if (write) + memcpy(ptr, buf, bytes); + else + memcpy(buf, ptr, bytes); + ttm_bo_kunmap(&map); + + page++; + buf += bytes; + bytes_left -= bytes; + offset = 0; + } while (bytes_left); + + return len; +} + +/** + * ttm_bo_access - Helper to access a buffer object + * + * @bo: ttm buffer object + * @offset: access offset into buffer object + * @buf: pointer to caller memory to read into or write from + * @len: length of access + * @write: write access + * + * Utility function to access a buffer object. Useful when buffer object cannot + * be easily mapped (non-contiguous, non-visible, etc...). + * + * Returns: + * 0 if successful, negative error code on failure. + */ +int ttm_bo_access(struct ttm_buffer_object *bo, unsigned long offset, + void *buf, int len, int write) +{ + int ret; + + if (len < 1 || (offset + len) > bo->base.size) + return -EIO; + + ret = ttm_bo_reserve(bo, true, false, NULL); + if (ret) + return ret; + + switch (bo->resource->mem_type) { + case TTM_PL_SYSTEM: + fallthrough; + case TTM_PL_TT: + ret = ttm_bo_access_kmap(bo, offset, buf, len, write); + break; + default: + if (bo->bdev->funcs->access_memory) + ret = bo->bdev->funcs->access_memory( + bo, offset, buf, len, write); + else + ret = -EIO; + } + + ttm_bo_unreserve(bo); + + return ret; +} +EXPORT_SYMBOL(ttm_bo_access); diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 2c699ed1963a..20b1e5f78684 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -366,45 +366,6 @@ void ttm_bo_vm_close(struct vm_area_struct *vma) } EXPORT_SYMBOL(ttm_bo_vm_close); -static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo, -unsigned long offset, -uint8_t *buf, int len, int write) -{ - unsigned long page = offset >> PAGE_SHIFT; - unsigned long bytes_left = len; - int ret; - - /* Copy a page at a time, that way no extra virtual address -* mapping is needed -*/ - offset -= page << PAGE_SHIFT; - do { - unsigned long bytes = min(bytes_left, PAGE_SIZE - offset); - struct ttm_bo_kmap_obj map; - void *ptr; - bool is_iomem; - - ret = ttm_bo_kmap(bo, page, 1, &map); - if (ret) - return ret; - - ptr = (uint8_t *)ttm_kmap_obj_virtual(&map, &is_iomem) + offset; - WARN_ON_ONCE(is_iomem); - if (write) - memcpy(ptr, buf, bytes); - else - memcpy(buf, ptr, bytes); - ttm_bo_kunmap(&map); - - page++; - buf += bytes; - bytes_left -= bytes; - offset = 0; - } while (bytes_left); - - return len; -} - int ttm_bo_vm_access(s
[PATCH v3 6/6] drm/xe: Only allow contiguous BOs to use xe_bo_vmap
xe_bo_vmap only works on contiguous BOs, disallow xe_bo_vmap on BO unless we are certain the BO is contiguous. Signed-off-by: Matthew Brost --- drivers/gpu/drm/xe/xe_bo.c | 23 ++- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 0a7b91df69c2..46c640f8db9e 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -162,6 +162,15 @@ static void try_add_system(struct xe_device *xe, struct xe_bo *bo, } } +static bool force_contiguous(u32 bo_flags) +{ + /* +* For eviction / restore on suspend / resume objects pinned in VRAM +* must be contiguous, also only contiguous BOs support xe_bo_vmap. +*/ + return bo_flags & (XE_BO_FLAG_PINNED | XE_BO_FLAG_GGTT); +} + static void add_vram(struct xe_device *xe, struct xe_bo *bo, struct ttm_place *places, u32 bo_flags, u32 mem_type, u32 *c) { @@ -175,12 +184,7 @@ static void add_vram(struct xe_device *xe, struct xe_bo *bo, xe_assert(xe, vram && vram->usable_size); io_size = vram->io_size; - /* -* For eviction / restore on suspend / resume objects -* pinned in VRAM must be contiguous -*/ - if (bo_flags & (XE_BO_FLAG_PINNED | - XE_BO_FLAG_GGTT)) + if (force_contiguous(bo_flags)) place.flags |= TTM_PL_FLAG_CONTIGUOUS; if (io_size < vram->usable_size) { @@ -212,8 +216,7 @@ static void try_add_stolen(struct xe_device *xe, struct xe_bo *bo, bo->placements[*c] = (struct ttm_place) { .mem_type = XE_PL_STOLEN, - .flags = bo_flags & (XE_BO_FLAG_PINNED | -XE_BO_FLAG_GGTT) ? + .flags = force_contiguous(bo_flags) ? TTM_PL_FLAG_CONTIGUOUS : 0, }; *c += 1; @@ -2024,13 +2027,15 @@ dma_addr_t xe_bo_addr(struct xe_bo *bo, u64 offset, size_t page_size) int xe_bo_vmap(struct xe_bo *bo) { + struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev); void *virtual; bool is_iomem; int ret; xe_bo_assert_held(bo); - if (!(bo->flags & XE_BO_FLAG_NEEDS_CPU_ACCESS)) + if (drm_WARN_ON(&xe->drm, !(bo->flags & XE_BO_FLAG_NEEDS_CPU_ACCESS) || + !force_contiguous(bo->flags))) return -EINVAL; if (!iosys_map_is_null(&bo->vmap)) -- 2.34.1
[PATCH v3 0/6] Fix non-contiguous VRAM BO access in Xe
Mapping a non-contiguous VRAM BO doesn't work, start to fix this. v2: - Include missing local change v3: - Use GPU for non-visible access - Take PM ref in xe_ttm_access_memory - Disable VMAP for non-contiguous BOs Matthew Brost (6): drm/ttm: Add ttm_bo_access drm/xe: Add xe_ttm_access_memory drm/xe: Update xe_ttm_access_memory to use GPU for non-visible access drm/xe: Use ttm_bo_access in xe_vm_snapshot_capture_delayed drm/xe: Set XE_BO_FLAG_PINNED in migrate selftest BOs drm/xe: Only allow contiguous BOs to use xe_bo_vmap drivers/gpu/drm/ttm/ttm_bo_util.c | 86 + drivers/gpu/drm/ttm/ttm_bo_vm.c | 65 +-- drivers/gpu/drm/xe/tests/xe_migrate.c | 13 +- drivers/gpu/drm/xe/xe_bo.c| 95 +++-- drivers/gpu/drm/xe/xe_migrate.c | 267 ++ drivers/gpu/drm/xe/xe_migrate.h | 4 + drivers/gpu/drm/xe/xe_vm.c| 17 +- include/drm/ttm/ttm_bo.h | 2 + 8 files changed, 458 insertions(+), 91 deletions(-) -- 2.34.1
[PATCH v5 13/13] drm/bridge: cdns-dsi: Use pre_enable/post_disable to enable/disable
From: Aradhya Bhatia The cdns-dsi controller requires that it be turned on completely before the input DPI's source has begun streaming[0]. Not having that, allows for a small window before cdns-dsi enable and after cdns-dsi disable where the previous entity (in this case tidss's videoport) to continue streaming DPI video signals. This small window where cdns-dsi is disabled but is still receiving signals causes the input FIFO of cdns-dsi to get corrupted. This causes the colors to shift on the output display. The colors can either shift by one color component (R->G, G->B, B->R), or by two color components (R->B, G->R, B->G). Since tidss's videoport starts streaming via crtc enable hooks, we need cdns-dsi to be up and running before that. Now that the bridges are pre_enabled before crtc is enabled, and post_disabled after crtc is disabled, use the pre_enable and post_disable hooks to get cdns-dsi ready and running before the tidss videoport to get pass the color shift issues. [0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM TRM Link: http://www.ti.com/lit/pdf/spruil1 Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- .../gpu/drm/bridge/cadence/cdns-dsi-core.c| 62 ++- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 79d8c2264c14..dfeb53841ebc 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -658,13 +658,28 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void cdns_dsi_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void cdns_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); u32 val; + /* +* The cdns-dsi controller needs to be disabled after it's DPI source +* has stopped streaming. If this is not followed, there is a brief +* window before DPI source is disabled and after cdns-dsi controller +* has been disabled where the DPI stream is still on, but the cdns-dsi +* controller is not ready anymore to accept the incoming signals. This +* is one of the reasons why a shift in pixel colors is observed on +* displays that have cdns-dsi as one of the bridges. +* +* To mitigate this, disable this bridge from the bridge post_disable() +* hook, instead of the bridge _disable() hook. The bridge post_disable() +* hook gets called after the CRTC disable, where often many DPI sources +* disable their streams. +*/ + val = readl(dsi->regs + MCTL_MAIN_DATA_CTL); val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN | DISP_EOT_GEN); @@ -683,15 +698,6 @@ static void cdns_dsi_bridge_atomic_disable(struct drm_bridge *bridge, pm_runtime_put(dsi->base.dev); } -static void cdns_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) -{ - struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); - struct cdns_dsi *dsi = input_to_dsi(input); - - pm_runtime_put(dsi->base.dev); -} - static void cdns_dsi_hs_init(struct cdns_dsi *dsi) { struct cdns_dsi_output *output = &dsi->output; @@ -760,8 +766,8 @@ static void cdns_dsi_init_link(struct cdns_dsi *dsi) dsi->link_initialized = true; } -static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); @@ -776,6 +782,21 @@ static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge, if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) return; + /* +* The cdns-dsi controller needs to be enabled before it's DPI source +* has begun streaming. If this is not followed, there is a brief window +* after DPI source enable and before cdns-dsi controller enable where +* the DPI stream is on, but the cdns-dsi controller is not ready to +* accept the incoming signals. This is one of the reasons why a shift +* in pixel colors is observed on displays that have cdns-dsi as one of +* the
[PATCH v5 09/13] drm/bridge: cdns-dsi: Support atomic bridge APIs
From: Aradhya Bhatia Change the existing (and deprecated) bridge hooks, to the bridge atomic APIs. Add drm helpers for duplicate_state, destroy_state, and bridge_reset bridge hooks. Further add support for the input format negotiation hook. Reviewed-by: Dmitry Baryshkov Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- .../gpu/drm/bridge/cadence/cdns-dsi-core.c| 51 --- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 284c468db6c3..7341e609dc8b 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -658,7 +658,8 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) +static void cdns_dsi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); @@ -682,7 +683,8 @@ static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) pm_runtime_put(dsi->base.dev); } -static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge) +static void cdns_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); @@ -758,7 +760,8 @@ static void cdns_dsi_init_link(struct cdns_dsi *dsi) dsi->link_initialized = true; } -static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) +static void cdns_dsi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); @@ -911,7 +914,8 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) writel(tmp, dsi->regs + MCTL_MAIN_EN); } -static void cdns_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); @@ -923,13 +927,44 @@ static void cdns_dsi_bridge_pre_enable(struct drm_bridge *bridge) cdns_dsi_hs_init(dsi); } +static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); + struct cdns_dsi *dsi = input_to_dsi(input); + struct cdns_dsi_output *output = &dsi->output; + u32 *input_fmts; + + *num_input_fmts = 0; + + input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + + input_fmts[0] = drm_mipi_dsi_get_input_bus_fmt(output->dev->format); + if (!input_fmts[0]) + return NULL; + + *num_input_fmts = 1; + + return input_fmts; +} + static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = { .attach = cdns_dsi_bridge_attach, .mode_valid = cdns_dsi_bridge_mode_valid, - .disable = cdns_dsi_bridge_disable, - .pre_enable = cdns_dsi_bridge_pre_enable, - .enable = cdns_dsi_bridge_enable, - .post_disable = cdns_dsi_bridge_post_disable, + .atomic_disable = cdns_dsi_bridge_atomic_disable, + .atomic_pre_enable = cdns_dsi_bridge_atomic_pre_enable, + .atomic_enable = cdns_dsi_bridge_atomic_enable, + .atomic_post_disable = cdns_dsi_bridge_atomic_post_disable, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_get_input_bus_fmts = cdns_dsi_bridge_get_input_bus_fmts, }; static int cdns_dsi_attach(struct mipi_dsi_host *host, -- 2.34.1
Re: [PATCH] drm: lcdif: Use adjusted_mode .clock instead of .crtc_clock
Quoting Marek Vasut (2024-10-12 21:37:59) > On 10/11/24 5:10 AM, Liu Ying wrote: > > Hi, > > This Video PLL1 configuration since moved to &media_blk_ctrl {} , but it > is still in the imx8mp.dtsi . Therefore, to make your panel work at the > correct desired pixel clock frequency instead of some random one > inherited from imx8mp.dtsi, add the following to the pollux DT, I > believe that will fix the problem and is the correct fix: > > &media_blk_ctrl { > // 50680 = 7240 * 7 (for single-link LVDS, this is enough) > // there is no need to multiply the clock by * 2 > assigned-clock-rates = <5>, <2>, <0>, <0>, > <5>, <50680>; > >>> > >>> This assigns "video_pll1" clock rate to 506.8MHz which is currently not > >>> listed in imx_pll1443x_tbl[]. > >> > >> Since commit b09c68dc57c9 ("clk: imx: pll14xx: Support dynamic rates") the > >> 1443x PLLs can be configured to arbitrary rates which for video PLL is > >> desirable as those should produce accurate clock. > > > > Ack. > > > >> > >>> Does the below patch[1] fix the regression issue? It explicitly sets > >>> the clock frequency of the panel timing to 74.25MHz. > >>> > >>> [1] https://patchwork.freedesktop.org/patch/616905/?series=139266&rev=1 > >> That patch is wrong, there is an existing entry for this panel in > >> panel-simple.c which is correct and precise, please do not add that kind > >> of imprecise duplicate timings into DT. > > > > At least the patch[1] is legitimate now to override the display > > timing of the panel because the override mode is something > > panel-simple.c supports. > > It may be possible to override the mode, but why would this be the > desired if the panel-simple.c already contains valid accurate timings > for this particular panel ? I'm confused a little here. Why is it that setting the panel timings in the DT as per [1] make the display work, while the panel timeings in panel-simple alone are not enough? Is there some difference in code path for 'how' the panel timings are set as to whether they will apply fully or not ? -- Kieran > > > And, pixel clock @74.25MHz is not out > > of the panel specification since edt_etml1010g3dra_timing > > indicates the minimum as 66.3MHz and the maximum as 78.9MHz. > > The panel-simple.c already contains timings for this panel, which are > accurate and follow the panel datasheet. If the goal here is to support > approximate panel timings between the currently available three options > (min/typ/max) listed in panel-simple, then that is another discussion > for another patch. > > > Furthermore, if "PHYTEC phyBOARD-Pollux i.MX8MP" also supports > > something like MIPI DSI to HDMI, then 74.25MHz panel pixel clock > > rate is more desirable because the LVDS display and the MIPI DSI > > display pipeline with typical 148.5MHz/74.25MHz pixel clock rates > > may use one single "video_pll1" clock. > > I actually do have exactly this use case on one system -- one LVDS panel > and one MIPI DSI panel -- the solution is really easy, source the LVDS > pixel clock from Video PLL and the DSI clock from e.g. PLL3 . > > > Anyway, I think it is ok to use the patch[1] or assigning > > "video_pll1" clock rate to 506.8MHz in DT(no things like MIPI > > DSI to HDMI in existing DT). > I believe for the current release, it is better to update the Video PLL > clock in this one board DT, because that is minimum impact change > isolated to this board and fixes a real issue where the LVDS panel > worked within specification only by sheer chance.
[PATCH v5 11/13] drm/atomic-helper: Separate out Encoder-Bridge enable and disable
From: Aradhya Bhatia The way any singular display pipeline, in need of a modeset, gets enabled is as follows - CRTC Enable All Bridge Pre-Enable Encoder Enable All Bridge Enable - and the disable path is exactly the reverse of this. The CRTC enable/disable occurs by looping over the old and new CRTC states, while the bridge pre-enable, encoder enable, and bridge enable occur by looping through the new connector states of the display pipelines. At the moment, the encoder and bridge operations are grouped together and occur under the same loops. Separate out the enable/disable loops of the encoder and bridge operations into a different function, to make way for the re-ordering of the enable and disable sequence of all these display elements. This patch doesn't alter in any way the ordering of CRTC/encoder/bridge enable and disable, but merely helps to cleanly set up for the next patch and to make sure that the bisectibility remains intact. Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/drm_atomic_helper.c | 97 + 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 5186d2114a50..7741fbcc8fc7 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1122,11 +1122,10 @@ crtc_needs_disable(struct drm_crtc_state *old_state, } static void -disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) +encoder_bridge_chain_disable(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_connector *connector; struct drm_connector_state *old_conn_state, *new_conn_state; - struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state, *new_crtc_state; int i; @@ -1189,6 +1188,16 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) drm_atomic_bridge_chain_post_disable(bridge, old_state); } +} + +static void +disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + int i; + + encoder_bridge_chain_disable(dev, old_state); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { const struct drm_crtc_helper_funcs *funcs; @@ -1445,6 +1454,51 @@ static void drm_atomic_helper_commit_writebacks(struct drm_device *dev, } } +static void +encoder_bridge_chain_enable(struct drm_device *dev, struct drm_atomic_state *old_state) +{ + struct drm_connector *connector; + struct drm_connector_state *new_conn_state; + int i; + + for_each_new_connector_in_state(old_state, connector, new_conn_state, i) { + const struct drm_encoder_helper_funcs *funcs; + struct drm_encoder *encoder; + struct drm_bridge *bridge; + + if (!new_conn_state->best_encoder) + continue; + + if (!new_conn_state->crtc->state->active || + !drm_atomic_crtc_needs_modeset(new_conn_state->crtc->state)) + continue; + + encoder = new_conn_state->best_encoder; + funcs = encoder->helper_private; + + drm_dbg_atomic(dev, "enabling [ENCODER:%d:%s]\n", + encoder->base.id, encoder->name); + + /* +* Each encoder has at most one connector (since we always steal +* it away), so we won't call enable hooks twice. +*/ + bridge = drm_bridge_chain_get_first_bridge(encoder); + drm_atomic_bridge_chain_pre_enable(bridge, old_state); + + if (funcs) { + if (funcs->atomic_enable) + funcs->atomic_enable(encoder, old_state); + else if (funcs->enable) + funcs->enable(encoder); + else if (funcs->commit) + funcs->commit(encoder); + } + + drm_atomic_bridge_chain_enable(bridge, old_state); + } +} + /** * drm_atomic_helper_commit_modeset_enables - modeset commit to enable outputs * @dev: DRM device @@ -1465,8 +1519,6 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state; - struct drm_connector *connector; - struct drm_connector_state *new_conn_state; int i; for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { @@ -1491,42 +1543,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, } } -
Re: [PATCH 1/7] drm/panic: avoid reimplementing Iterator::find
On Sat Oct 12, 2024 at 1:04 PM CEST, Miguel Ojeda wrote: > Hi Thomas, Hi Miguel, > > On Sat, Oct 12, 2024 at 9:53 AM Thomas Böhler wrote: > > > > implementing the same logic itself. > > Clippy complains about this in the `manual_find` lint: > > Typically commit messages use newlines between paragraphs. I wanted to logically group these sentences together, but can also use paragraphs of course. > > Reported-by: Miguel Ojeda > > Closes: https://github.com/Rust-for-Linux/linux/issues/1123 > > Since each of these commits fixes part of the issue, I think these are > meant to be `Link:`s instead of `Closes:`s according to the docs: > > > https://docs.kernel.org/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes > > In addition, these should probably have a `Fixes:` tag too -- I should > have mentioned that in the issue, sorry. Good point, I didn't realise this when I read the documentation. I'll change/add the trailer as suggested. > Finally, as a suggestion for the future: for a series like this, it > may make sense to have a small/quick cover letter saying something as > simple as: "Clippy reports some issues in ... -- this series cleans > them up.". Having a cover letter also allows you to give a title to > the series. Makes sense, v2 will have a cover letter :) > Thanks again! Thank you for the nits, they're exactly what I've been looking forward to! I'll prepare a v2 within the coming days as I'm currently limited on free time, so thank you in advance for the patience. > Cheers, > Miguel Kind regards, -- Thomas Böhler https://wiredspace.de
[PATCH v2 4/7] drm/panic: remove redundant field when assigning value
Rust allows initializing fields of a struct without specifying the attribute that is assigned if the variable has the same name. In this instance this is done for all other attributes of the struct except for `data`. Remove the redundant `data` in the assignment to be consistent. Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") Reported-by: Miguel Ojeda Link: https://github.com/Rust-for-Linux/linux/issues/1123 Signed-off-by: Thomas Böhler Reviewed-by: Jocelyn Falempe --- drivers/gpu/drm/drm_panic_qr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs index 767a8eb0acec..5b2386a515fa 100644 --- a/drivers/gpu/drm/drm_panic_qr.rs +++ b/drivers/gpu/drm/drm_panic_qr.rs @@ -489,7 +489,7 @@ fn new<'a>(segments: &[&Segment<'_>], data: &'a mut [u8]) -> Option
[PATCH v2 0/7] Cleanup Clippy issues in drm_panic_qr.rs
The file drivers/gpu/drm/drm_panic_qr.rs has some lints that Clippy complains about. This series cleans them up by either allowing what is written or conforming to what Clippy expects where it makes sense. All explicitly allowed lints are marked with `#[expect(...)]`. v1 -> v2: - Add "Fixes" trailers and rename "Closes" to "Link" trailers as the patches all fix part of the issue. - Replace `#[allow(...)]` with `#[expect(...)]`. Support for `expect` is already in rust-next, which is where this series will be merged into. Thomas Böhler (7): drm/panic: avoid reimplementing Iterator::find drm/panic: remove unnecessary borrow in alignment_pattern drm/panic: prefer eliding lifetimes drm/panic: remove redundant field when assigning value drm/panic: correctly indent continuation of line in list item drm/panic: allow verbose boolean for clarity drm/panic: allow verbose version check drivers/gpu/drm/drm_panic_qr.rs | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) -- 2.46.2
Re: [PATCH 1/7] drm/panic: avoid reimplementing Iterator::find
On Mon Oct 14, 2024 at 11:06 AM CEST, Jocelyn Falempe wrote: > Hi Thomas, Hi Jocelyn, > If you want to send a v2, the easiest way is to download the mbox series > from https://patchwork.freedesktop.org/series/139924/ > and apply it with git am. > > That way you will have my reviewed-by automatically added. That's neat to know, thank you! That makes the use-case of patchwork a bit clearer for me. > Best regards, > > -- > > Jocelyn Kind regards, -- Thomas Böhler https://wiredspace.de
Re: [PATCH] drm: a6xx: avoid excessive stack usage
On Sat, Oct 19, 2024 at 03:01:46PM +0530, Akhil P Oommen wrote: > On Fri, Oct 18, 2024 at 03:11:38PM +, Arnd Bergmann wrote: > > From: Arnd Bergmann > > > > Clang-19 and above sometimes end up with multiple copies of the large > > a6xx_hfi_msg_bw_table structure on the stack. The problem is that > > a6xx_hfi_send_bw_table() calls a number of device specific functions to > > fill the structure, but these create another copy of the structure on > > the stack which gets copied to the first. > > > > If the functions get inlined, that busts the warning limit: > > > > drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size > > (1032) exceeds limit (1024) in 'a6xx_hfi_send_bw_table' > > [-Werror,-Wframe-larger-than] > > Why does this warning says that the limit is 1024? 1024 bytes is too small, > isn't it? Kernel stacks are expected to be space limited, so 1024 is a logical limit for a single function. -- With best wishes Dmitry
Re: [PATCH 11/28] drm/msm: Use video aperture helpers
On Mon, Sep 30, 2024 at 03:03:09PM +0200, Thomas Zimmermann wrote: > DRM's aperture functions have long been implemented as helpers > under drivers/video/ for use with fbdev. Avoid the DRM wrappers by > calling the video functions directly. > > Signed-off-by: Thomas Zimmermann > Cc: Rob Clark > Cc: Abhinav Kumar > Cc: Dmitry Baryshkov > Cc: Sean Paul > Cc: Marijn Suijten > --- > drivers/gpu/drm/msm/msm_kms.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH drm-dp 3/4] drm/hisilicon/hibmc: add dp kapi moduel in hibmc drivers
On Mon, Sep 30, 2024 at 06:06:09PM +0800, shiyongbang wrote: > From: baihan li > > Build a kapi level that hibmc driver can enable dp by > calling these kapi functions. > > Signed-off-by: baihan li > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > .../gpu/drm/hisilicon/hibmc/dp/dp_config.h| 20 > drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.c | 12 ++--- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.h | 48 +++ > 4 files changed, 75 insertions(+), 7 deletions(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 94d77da88bbf..693036dfab52 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o dp/dp_link.o > +dp/dp_aux.o dp/dp_link.o dp/dp_kapi.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h > new file mode 100644 > index ..a6353a808cc4 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h > @@ -0,0 +1,20 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* Copyright (c) 2024 Hisilicon Limited. */ > + > +#ifndef DP_CONFIG_H > +#define DP_CONFIG_H > + > +#define DP_BPP 24 > +#define DP_SYMBOL_PER_FCLK 4 > +#define DP_MIN_PULSE_NUM 0x9 > +#define DP_MSA1 0x20 > +#define DP_MSA2 0x845c00 > +#define DP_OFFSET 0x1e > +#define DP_HDCP 0x2 > +#define DP_INT_RST 0x > +#define DP_DPTX_RST 0x3ff > +#define DP_CLK_EN 0x7 > +#define DP_SYNC_EN_MASK 0x3 > +#define DP_LINK_RATE_CAL 27 I think some of these defines were used in previous patches. Please make sure that at each step the code builds without errors. > + > +#endif > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.c > index 4091723473ad..ca7edc69427c 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.c > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.c > @@ -64,12 +64,12 @@ static void hibmc_dp_set_tu(struct hibmc_dp_dev *dp, > struct dp_mode *mode) > rate_ks = dp->link.cap.link_rate * DP_LINK_RATE_CAL; > value = (pixel_clock * bpp * 5000) / (61 * lane_num * rate_ks); > > - if (value % 10 == 9) { /* 10: div, 9: carry */ > - tu_symbol_size = value / 10 + 1; /* 10: div */ > + if (value % 10 == 9) { /* 9 carry */ > + tu_symbol_size = value / 10 + 1; > tu_symbol_frac_size = 0; > } else { > - tu_symbol_size = value / 10; /* 10: div */ > - tu_symbol_frac_size = value % 10 + 1; /* 10: div */ > + tu_symbol_size = value / 10; > + tu_symbol_frac_size = value % 10 + 1; > } > > drm_info(dp->dev, "tu value: %u.%u value: %u\n", > @@ -158,7 +158,7 @@ static void hibmc_dp_link_cfg(struct hibmc_dp_dev *dp, > struct dp_mode *mode) > dp_write_bits(dp->base + DP_VIDEO_CTRL, > DP_CFG_STREAM_HSYNC_POLARITY, mode->h_pol); > > - /* MSA mic 0 and 1*/ > + /* MSA mic 0 and 1 */ > writel(DP_MSA1, dp->base + DP_VIDEO_MSA1); > writel(DP_MSA2, dp->base + DP_VIDEO_MSA2); > > @@ -167,7 +167,7 @@ static void hibmc_dp_link_cfg(struct hibmc_dp_dev *dp, > struct dp_mode *mode) > dp_write_bits(dp->base + DP_VIDEO_CTRL, DP_CFG_STREAM_RGB_ENABLE, 0x1); > dp_write_bits(dp->base + DP_VIDEO_CTRL, DP_CFG_STREAM_VIDEO_MAPPING, 0); > > - /*divide 2: up even */ > + /* divide 2: up even */ > if (timing_delay % 2) > timing_delay++; > This should be squashed into the previous commits. > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.h > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.h > new file mode 100644 > index ..6b07642d55b8 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_kapi.h > @@ -0,0 +1,48 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* Copyright (c) 2024 Hisilicon Limited. */ > + > +#ifndef DP_KAPI_H > +#define DP_KAPI_H > + > +#include > +#include > +#include > +#include > +#include > +#include Sort the headers, please. > + > +struct hibmc_dp_dev; > + > +struct dp_mode { > + u32 h_total; > + u32 h_active; > + u32 h_blank; > + u32 h_front; > + u32 h_sync; > + u32 h_back; > + bool h_pol; > + u32 v_total; > + u32 v_active; > + u32 v_blank; > + u32 v_front; > + u32 v_sync; > + u32 v_back; > + bool v_pol; > + u32 field_rate; > + u32 pixel_clock; // khz Why do you need a separate struct for this? > +}; > + > +struct hibmc_dp { > + struct hibmc_dp_dev *dp_dev;
Re: [PATCH drm-dp 4/4] drm/hisilicon/hibmc: add dp module in hibmc
On Mon, Sep 30, 2024 at 06:06:10PM +0800, shiyongbang wrote: > From: baihan li > > To support DP interface displaying in hibmc driver. Add > a encoder and connector for DP modual. > > Signed-off-by: baihan li > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c| 195 ++ > .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 17 +- > .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 5 + > 4 files changed, 217 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 693036dfab52..8cf74e0d4785 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o dp/dp_link.o dp/dp_kapi.o > +dp/dp_aux.o dp/dp_link.o dp/dp_kapi.o hibmc_drm_dp.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > new file mode 100644 > index ..7a50f1d81aac > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > @@ -0,0 +1,195 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > + > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#include "hibmc_drm_drv.h" > +#include "dp/dp_kapi.h" > + > +static int hibmc_dp_connector_get_modes(struct drm_connector *connector) > +{ > + int count; > + > + count = drm_add_modes_noedid(connector, > connector->dev->mode_config.max_width, > + connector->dev->mode_config.max_height); > + drm_set_preferred_mode(connector, 800, 600); /* default 800x600 */ What? Please parse EDID instead. > + > + return count; > +} > + > +static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = { > + .get_modes = hibmc_dp_connector_get_modes, > +}; > + > +static const struct drm_connector_funcs hibmc_dp_conn_funcs = { > + .reset = drm_atomic_helper_connector_reset, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .destroy = drm_connector_cleanup, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > +}; > + > +static void dp_mode_cfg(struct drm_device *dev, struct dp_mode *dp_mode, > + struct drm_display_mode *mode) > +{ > + dp_mode->field_rate = drm_mode_vrefresh(mode); > + dp_mode->pixel_clock = mode->clock / 1000; /* 1000: khz to hz */ > + > + dp_mode->h_total = mode->htotal; > + dp_mode->h_active = mode->hdisplay; > + dp_mode->h_blank = mode->htotal - mode->hdisplay; > + dp_mode->h_front = mode->hsync_start - mode->hdisplay; > + dp_mode->h_sync = mode->hsync_end - mode->hsync_start; > + dp_mode->h_back = mode->htotal - mode->hsync_end; > + > + dp_mode->v_total = mode->vtotal; > + dp_mode->v_active = mode->vdisplay; > + dp_mode->v_blank = mode->vtotal - mode->vdisplay; > + dp_mode->v_front = mode->vsync_start - mode->vdisplay; > + dp_mode->v_sync = mode->vsync_end - mode->vsync_start; > + dp_mode->v_back = mode->vtotal - mode->vsync_end; No need to copy the bits around. Please use drm_display_mode directly. > + > + if (mode->flags & DRM_MODE_FLAG_PHSYNC) { > + drm_info(dev, "horizontal sync polarity: positive\n"); > + dp_mode->h_pol = 1; > + } else if (mode->flags & DRM_MODE_FLAG_NHSYNC) { > + drm_info(dev, "horizontal sync polarity: negative\n"); > + dp_mode->h_pol = 0; > + } else { > + drm_err(dev, "horizontal sync polarity: unknown or not set\n"); > + } > + > + if (mode->flags & DRM_MODE_FLAG_PVSYNC) { > + drm_info(dev, "vertical sync polarity: positive\n"); > + dp_mode->v_pol = 1; > + } else if (mode->flags & DRM_MODE_FLAG_NVSYNC) { > + drm_info(dev, "vertical sync polarity: negative\n"); No spamming, use DRM debugging macros. > + dp_mode->v_pol = 0; > + } else { > + drm_err(dev, "vertical sync polarity: unknown or not set\n"); > + } > +} > + > +static int dp_prepare(struct hibmc_dp *dp, struct drm_display_mode *mode) > +{ > + struct dp_mode dp_mode = {0}; > + int ret; > + > + hibmc_dp_display_en(dp, false); > + > + dp_mode_cfg(dp->drm_dev, &dp_mode, mode); > + ret = hibmc_dp_mode_set(dp, &dp_mode); > + if (ret) > + drm_err(dp->drm_dev, "hibmc dp mode set failed: %d\n", ret); > + > + return ret; > +} > + > +static void dp_enable(struct hibmc_dp *dp) > +{ > + hibmc_dp_display_en(dp, true); > +} > + > +static void dp_dis
Re: [PATCH v5 01/26] drm: sun4i: de2/de3: Change CSC argument
On Sun, Sep 29, 2024 at 10:04:33PM +1300, Ryan Walklin wrote: > From: Jernej Skrabec > > Currently, CSC module takes care only for converting YUV to RGB. > However, DE3 is more suited to work in YUV color space. Change CSC mode > argument to format type to be more neutral. New argument only tells > layer format type and doesn't imply output type. > > This commit doesn't make any functional change. > > Signed-off-by: Jernej Skrabec > Signed-off-by: Ryan Walklin > Reviewed-by: Andre Przywara > --- > drivers/gpu/drm/sun4i/sun8i_csc.c | 22 +++--- > drivers/gpu/drm/sun4i/sun8i_csc.h | 10 +- > drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 16 > 3 files changed, 24 insertions(+), 24 deletions(-) > > void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h > b/drivers/gpu/drm/sun4i/sun8i_csc.h > index 828b86fd0cabb..7322770f39f03 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_csc.h > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.h > @@ -22,14 +22,14 @@ struct sun8i_mixer; > > #define SUN8I_CSC_CTRL_ENBIT(0) > > -enum sun8i_csc_mode { > - SUN8I_CSC_MODE_OFF, > - SUN8I_CSC_MODE_YUV2RGB, > - SUN8I_CSC_MODE_YVU2RGB, > +enum format_type { enum sun8i_format_type, unless there is a strong reason to name it otherwise. > + FORMAT_TYPE_RGB, > + FORMAT_TYPE_YUV, > + FORMAT_TYPE_YVU, > }; > > void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, > - enum sun8i_csc_mode mode, > + enum format_type fmt_type, >enum drm_color_encoding encoding, >enum drm_color_range range); > void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool > enable); > -- With best wishes Dmitry
Re: [PATCH v5 08/26] drm: sun4i: de3: add YUV support to the DE3 mixer
On Sun, Sep 29, 2024 at 10:04:40PM +1300, Ryan Walklin wrote: > From: Jernej Skrabec > > The mixer in the DE3 display engine supports YUV 8 and 10 bit > formats in addition to 8-bit RGB. Add the required register > configuration and format enumeration callback functions to the mixer, > and store the in-use output format (defaulting to RGB) and color > encoding in engine variables. > > Signed-off-by: Jernej Skrabec > Signed-off-by: Ryan Walklin > > --- > Changelog v4..v5: > - Remove trailing whitespace > --- > drivers/gpu/drm/sun4i/sun8i_mixer.c | 53 ++-- > drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++ > 2 files changed, 55 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c > b/drivers/gpu/drm/sun4i/sun8i_mixer.c > index 252827715de1d..a50c583852edf 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c > @@ -23,7 +23,10 @@ > #include > #include > > +#include > + > #include "sun4i_drv.h" > +#include "sun50i_fmt.h" > #include "sun8i_mixer.h" > #include "sun8i_ui_layer.h" > #include "sun8i_vi_layer.h" > @@ -390,12 +393,52 @@ static void sun8i_mixer_mode_set(struct sunxi_engine > *engine, > > DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", >interlaced ? "on" : "off"); > + > + if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) > + val = SUN8I_MIXER_BLEND_COLOR_BLACK; > + else > + val = 0xff108080; > + > + regmap_write(mixer->engine.regs, > + SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); > + regmap_write(mixer->engine.regs, > + SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); > + > + if (mixer->cfg->has_formatter) > + sun50i_fmt_setup(mixer, mode->hdisplay, > + mode->vdisplay, mixer->engine.format); > +} > + > +static u32 *sun8i_mixer_get_supported_fmts(struct sunxi_engine *engine, u32 > *num) > +{ > + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); > + u32 *formats, count; > + > + count = 0; > + > + formats = kcalloc(5, sizeof(*formats), GFP_KERNEL); > + if (!formats) > + return NULL; > + > + if (mixer->cfg->has_formatter) { > + formats[count++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; > + formats[count++] = MEDIA_BUS_FMT_YUV8_1X24; > + formats[count++] = MEDIA_BUS_FMT_UYVY8_1X16; > + formats[count++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; > + } > + > + formats[count++] = MEDIA_BUS_FMT_RGB888_1X24; > + > + *num = count; > + > + return formats; > } > > static const struct sunxi_engine_ops sun8i_engine_ops = { > - .commit = sun8i_mixer_commit, > - .layers_init= sun8i_layers_init, > - .mode_set = sun8i_mixer_mode_set, > + .commit = sun8i_mixer_commit, > + .layers_init= sun8i_layers_init, > + .mode_set = sun8i_mixer_mode_set, > + .get_supported_fmts = sun8i_mixer_get_supported_fmts, > }; > > static const struct regmap_config sun8i_mixer_regmap_config = { > @@ -456,6 +499,10 @@ static int sun8i_mixer_bind(struct device *dev, struct > device *master, > dev_set_drvdata(dev, mixer); > mixer->engine.ops = &sun8i_engine_ops; > mixer->engine.node = dev->of_node; > + /* default output format, supported by all mixers */ > + mixer->engine.format = MEDIA_BUS_FMT_RGB888_1X24; > + /* default color encoding, ignored with RGB I/O */ > + mixer->engine.encoding = DRM_COLOR_YCBCR_BT601; > > if (of_property_present(dev->of_node, "iommus")) { > /* > diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h > b/drivers/gpu/drm/sun4i/sunxi_engine.h > index c48cbc1aceb80..ffafc29b3a0c3 100644 > --- a/drivers/gpu/drm/sun4i/sunxi_engine.h > +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h > @@ -6,6 +6,8 @@ > #ifndef _SUNXI_ENGINE_H_ > #define _SUNXI_ENGINE_H_ > > +#include > + > struct drm_plane; > struct drm_crtc; > struct drm_device; > @@ -151,6 +153,9 @@ struct sunxi_engine { > > int id; > > + u32 format; > + enum drm_color_encoding encoding; Should these be a part of the state instead of being a part of the sunxi_engine? > + > /* Engine list management */ > struct list_headlist; > }; > -- > 2.46.1 > -- With best wishes Dmitry
Re: [PATCH v2 2/2] drm: fsl-dcu: enable PIXCLK on LS1021A
On Thu, Oct 17, 2024 at 08:50:43AM +0200, Alexander Stein wrote: > Hi everyone, > > Am Freitag, 27. September 2024, 01:13:57 CEST schrieb Dmitry Baryshkov: > > On Thu, Sep 26, 2024 at 04:09:03PM GMT, Alexander Stein wrote: > > > Hi Dmitry, > > > > > > Am Donnerstag, 26. September 2024, 08:05:56 CEST schrieb Dmitry Baryshkov: > > > > On Thu, Sep 26, 2024 at 07:55:51AM GMT, Alexander Stein wrote: > > > > > From: Matthias Schiffer > > > > > > > > > > The PIXCLK needs to be enabled in SCFG before accessing certain DCU > > > > > registers, or the access will hang. For simplicity, the PIXCLK is > > > > > enabled > > > > > unconditionally, resulting in increased power consumption. > > > > > > > > By this description it looks like a fix. What is the first broken > > > > commit? It needs to be mentioned in the Fixes: tag. Or is it hat > > > > existing devices have been enabling SCFG in some other way? > > > > > > We discussed this internally and it seems this never worked, unless PIXCLK > > > was already enabled in SCFG by a different way, e.g. firmware, etc. > > > > My bet was on the firmware, but I never touched Layerscape platforms. > > Anyway, > > > > Fixes: 109eee2f2a18 ("drm/layerscape: Add Freescale DCU DRM driver") > > Acked-by: Dmitry Baryshkov > > Any additional feedback? No response from Stefan and Alison for nearly a month... -- With best wishes Dmitry
Re: [PATCH] drm: lcdif: Use adjusted_mode .clock instead of .crtc_clock
On 10/19/24 11:49 PM, Kieran Bingham wrote: Quoting Marek Vasut (2024-10-12 21:37:59) On 10/11/24 5:10 AM, Liu Ying wrote: Hi, This Video PLL1 configuration since moved to &media_blk_ctrl {} , but it is still in the imx8mp.dtsi . Therefore, to make your panel work at the correct desired pixel clock frequency instead of some random one inherited from imx8mp.dtsi, add the following to the pollux DT, I believe that will fix the problem and is the correct fix: &media_blk_ctrl { // 50680 = 7240 * 7 (for single-link LVDS, this is enough) // there is no need to multiply the clock by * 2 assigned-clock-rates = <5>, <2>, <0>, <0>, <5>, <50680>; This assigns "video_pll1" clock rate to 506.8MHz which is currently not listed in imx_pll1443x_tbl[]. Since commit b09c68dc57c9 ("clk: imx: pll14xx: Support dynamic rates") the 1443x PLLs can be configured to arbitrary rates which for video PLL is desirable as those should produce accurate clock. Ack. Does the below patch[1] fix the regression issue? It explicitly sets the clock frequency of the panel timing to 74.25MHz. [1] https://patchwork.freedesktop.org/patch/616905/?series=139266&rev=1 That patch is wrong, there is an existing entry for this panel in panel-simple.c which is correct and precise, please do not add that kind of imprecise duplicate timings into DT. At least the patch[1] is legitimate now to override the display timing of the panel because the override mode is something panel-simple.c supports. It may be possible to override the mode, but why would this be the desired if the panel-simple.c already contains valid accurate timings for this particular panel ? I'm confused a little here. Why is it that setting the panel timings in the DT as per [1] make the display work, while the panel timeings in panel-simple alone are not enough? Is there some difference in code path for 'how' the panel timings are set as to whether they will apply fully or not ? Because [1] sets inaccurate pixel clock of 74.25 MHz, which can be divided down from random default Video PLL setting of 1039.5 MHz set in imx8mp.dtsi media_blk_ctrl , 1039.5 / 74.25 = 14 . The panel-simple pixel clock are 72.4 MHz, to achieve that accurately, it is necessary to reconfigure the Video PLL frequency to 506.8 MHz , which LCDIFv3 can do, but LDB can not, hence it has to be done in DT for now.
Re: [PATCH v6 03/10] drm/bridge: it6505: add AUX operation for HDCP KSV list read
Hi Hermes, kernel test robot noticed the following build errors: [auto build test ERROR on b8128f7815ff135f0333c1b46dcdf1543c41b860] url: https://github.com/intel-lab-lkp/linux/commits/Hermes-Wu-via-B4-Relay/drm-bridge-it6505-Change-definition-of-AUX_FIFO_MAX_SIZE/20241016-155607 base: b8128f7815ff135f0333c1b46dcdf1543c41b860 patch link: https://lore.kernel.org/r/20241016-upstream-v6-v6-3-4d93a0c46de1%40ite.com.tw patch subject: [PATCH v6 03/10] drm/bridge: it6505: add AUX operation for HDCP KSV list read config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20241020/202410200756.klsple8a-...@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project bfe84f7085d82d06d61c632a7bad1e692fd159e4) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241020/202410200756.klsple8a-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202410200756.klsple8a-...@intel.com/ All errors (new ones prefixed by >>): In file included from drivers/gpu/drm/bridge/ite-it6505.c:13: In file included from include/linux/i2c.h:19: In file included from include/linux/regulator/consumer.h:35: In file included from include/linux/suspend.h:5: In file included from include/linux/swap.h:9: In file included from include/linux/memcontrol.h:13: In file included from include/linux/cgroup.h:26: In file included from include/linux/kernel_stat.h:8: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:14: In file included from arch/hexagon/include/asm/io.h:328: include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 548 | val = __raw_readb(PCI_IOBASE + addr); | ~~ ^ include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 561 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); | ~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' 37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) | ^ In file included from drivers/gpu/drm/bridge/ite-it6505.c:13: In file included from include/linux/i2c.h:19: In file included from include/linux/regulator/consumer.h:35: In file included from include/linux/suspend.h:5: In file included from include/linux/swap.h:9: In file included from include/linux/memcontrol.h:13: In file included from include/linux/cgroup.h:26: In file included from include/linux/kernel_stat.h:8: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:14: In file included from arch/hexagon/include/asm/io.h:328: include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 574 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); | ~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' 35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) | ^ In file included from drivers/gpu/drm/bridge/ite-it6505.c:13: In file included from include/linux/i2c.h:19: In file included from include/linux/regulator/consumer.h:35: In file included from include/linux/suspend.h:5: In file included from include/linux/swap.h:9: In file included from include/linux/memcontrol.h:13: In file included from include/linux/cgroup.h:26: In file included from include/linux/kernel_stat.h:8: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:14: In file incl
[PATCH v3 2/6] drm/xe: Add xe_ttm_access_memory
Non-contiguous VRAM cannot easily be mapped in TTM nor can non-visible VRAM easily be accessed. Add xe_ttm_access_memory which hooks into ttm_bo_access to access such memory. Reported-by: Christoph Manszewski Suggested-by: Thomas Hellström Signed-off-by: Matthew Brost --- drivers/gpu/drm/xe/xe_bo.c | 62 -- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 5b232f2951b1..99557af16120 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -442,6 +442,14 @@ static void xe_ttm_tt_destroy(struct ttm_device *ttm_dev, struct ttm_tt *tt) kfree(tt); } +static bool xe_ttm_resource_visible(struct ttm_resource *mem) +{ + struct xe_ttm_vram_mgr_resource *vres = + to_xe_ttm_vram_mgr_resource(mem); + + return vres->used_visible_size == mem->size; +} + static int xe_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *mem) { @@ -453,11 +461,9 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev, return 0; case XE_PL_VRAM0: case XE_PL_VRAM1: { - struct xe_ttm_vram_mgr_resource *vres = - to_xe_ttm_vram_mgr_resource(mem); struct xe_mem_region *vram = res_to_mem_region(mem); - if (vres->used_visible_size < mem->size) + if (!xe_ttm_resource_visible(mem)) return -EINVAL; mem->bus.offset = mem->start << PAGE_SHIFT; @@ -,6 +1117,55 @@ static void xe_ttm_bo_swap_notify(struct ttm_buffer_object *ttm_bo) } } +static int xe_ttm_access_memory(struct ttm_buffer_object *ttm_bo, + unsigned long offset, void *buf, int len, + int write) +{ + struct xe_bo *bo = ttm_to_xe_bo(ttm_bo); + struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev); + struct iosys_map vmap; + struct xe_res_cursor cursor; + struct xe_mem_region *vram; + int bytes_left = len; + + xe_bo_assert_held(bo); + + if (!mem_type_is_vram(ttm_bo->resource->mem_type)) + return -EIO; + + /* FIXME: Use GPU for non-visible VRAM */ + if (!xe_ttm_resource_visible(ttm_bo->resource)) + return -EIO; + + if (!xe_pm_runtime_get_if_in_use(xe)) + return -EIO; + + vram = res_to_mem_region(ttm_bo->resource); + xe_res_first(ttm_bo->resource, offset & PAGE_MASK, bo->size, &cursor); + + do { + unsigned long page_offset = (offset & ~PAGE_MASK); + int byte_count = min((int)(PAGE_SIZE - page_offset), bytes_left); + + iosys_map_set_vaddr_iomem(&vmap, (u8 __iomem *)vram->mapping + + cursor.start); + if (write) + xe_map_memcpy_to(xe, &vmap, page_offset, buf, byte_count); + else + xe_map_memcpy_from(xe, buf, &vmap, page_offset, byte_count); + + offset += byte_count; + buf += byte_count; + bytes_left -= byte_count; + if (bytes_left) + xe_res_next(&cursor, PAGE_SIZE); + } while (bytes_left); + + xe_pm_runtime_put(xe); + + return len; +} + const struct ttm_device_funcs xe_ttm_funcs = { .ttm_tt_create = xe_ttm_tt_create, .ttm_tt_populate = xe_ttm_tt_populate, @@ -1120,6 +1175,7 @@ const struct ttm_device_funcs xe_ttm_funcs = { .move = xe_bo_move, .io_mem_reserve = xe_ttm_io_mem_reserve, .io_mem_pfn = xe_ttm_io_mem_pfn, + .access_memory = xe_ttm_access_memory, .release_notify = xe_ttm_bo_release_notify, .eviction_valuable = ttm_bo_eviction_valuable, .delete_mem_notify = xe_ttm_bo_delete_mem_notify, -- 2.34.1
[PATCH v5 06/13] drm/bridge: cdns-dsi: Check return value when getting default PHY config
From: Aradhya Bhatia Check for the return value of the phy_mipi_dphy_get_default_config() call, and incase of an error, return back the same. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 2fc24352d989..e4c0968313af 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -575,9 +575,11 @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, if (ret) return ret; - phy_mipi_dphy_get_default_config(mode_clock * 1000, - mipi_dsi_pixel_format_to_bpp(output->dev->format), -nlanes, phy_cfg); + ret = phy_mipi_dphy_get_default_config(mode_clock * 1000, + mipi_dsi_pixel_format_to_bpp(output->dev->format), + nlanes, phy_cfg); + if (ret) + return ret; ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); if (ret) -- 2.34.1
[PATCH v5 03/13] drm/bridge: cdns-dsi: Fix Phy _init() and _exit()
From: Aradhya Bhatia Initialize the Phy during the cdns-dsi _resume(), and de-initialize it during the _suspend(). Also power-off the Phy from bridge_disable. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 5159c3f0853e..d89c32bae2b9 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -672,6 +672,10 @@ static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) if (dsi->platform_ops && dsi->platform_ops->disable) dsi->platform_ops->disable(dsi); + phy_power_off(dsi->dphy); + dsi->link_initialized = false; + dsi->phy_initialized = false; + pm_runtime_put(dsi->base.dev); } @@ -698,7 +702,6 @@ static void cdns_dsi_hs_init(struct cdns_dsi *dsi) DPHY_CMN_PDN | DPHY_PLL_PDN, dsi->regs + MCTL_DPHY_CFG0); - phy_init(dsi->dphy); phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY); phy_configure(dsi->dphy, &output->phy_opts); phy_power_on(dsi->dphy); @@ -1120,6 +1123,8 @@ static int __maybe_unused cdns_dsi_resume(struct device *dev) clk_prepare_enable(dsi->dsi_p_clk); clk_prepare_enable(dsi->dsi_sys_clk); + phy_init(dsi->dphy); + return 0; } @@ -1127,10 +1132,11 @@ static int __maybe_unused cdns_dsi_suspend(struct device *dev) { struct cdns_dsi *dsi = dev_get_drvdata(dev); + phy_exit(dsi->dphy); + clk_disable_unprepare(dsi->dsi_sys_clk); clk_disable_unprepare(dsi->dsi_p_clk); reset_control_assert(dsi->dsi_p_rst); - dsi->link_initialized = false; return 0; } -- 2.34.1
[PATCH v5 12/13] drm/atomic-helper: Re-order bridge chain pre-enable and post-disable
From: Aradhya Bhatia Move the bridge pre_enable call before crtc enable, and the bridge post_disable call after the crtc disable. The sequence of enable after this patch will look like: bridge[n]_pre_enable ... bridge[1]_pre_enable crtc_enable encoder_enable bridge[1]_enable ... bridge[n]_enable and vice-versa for the bridge chain disable sequence. The definition of bridge pre_enable hook says that, "The display pipe (i.e. clocks and timing signals) feeding this bridge will not yet be running when this callback is called". Since CRTC is also a source feeding the bridge, it should not be enabled before the bridges in the pipeline are pre_enabled. Fix that by re-ordering the sequence of bridge pre_enable and bridge post_disable. Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/drm_atomic_helper.c | 102 ++-- include/drm/drm_atomic_helper.h | 5 ++ 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 7741fbcc8fc7..6ebd869df79b 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1122,7 +1122,8 @@ crtc_needs_disable(struct drm_crtc_state *old_state, } static void -encoder_bridge_chain_disable(struct drm_device *dev, struct drm_atomic_state *old_state) +encoder_bridge_chain_disable(struct drm_device *dev, struct drm_atomic_state *old_state, +enum bridge_chain_operation_type op_type) { struct drm_connector *connector; struct drm_connector_state *old_conn_state, *new_conn_state; @@ -1162,31 +1163,43 @@ encoder_bridge_chain_disable(struct drm_device *dev, struct drm_atomic_state *ol if (WARN_ON(!encoder)) continue; - funcs = encoder->helper_private; - - drm_dbg_atomic(dev, "disabling [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); - /* * Each encoder has at most one connector (since we always steal * it away), so we won't call disable hooks twice. */ bridge = drm_bridge_chain_get_first_bridge(encoder); - drm_atomic_bridge_chain_disable(bridge, old_state); - /* Right function depends upon target state. */ - if (funcs) { - if (funcs->atomic_disable) - funcs->atomic_disable(encoder, old_state); - else if (new_conn_state->crtc && funcs->prepare) - funcs->prepare(encoder); - else if (funcs->disable) - funcs->disable(encoder); - else if (funcs->dpms) - funcs->dpms(encoder, DRM_MODE_DPMS_OFF); - } + switch (op_type) { + case DRM_BRIDGE_ENABLE_DISABLE: + funcs = encoder->helper_private; + + drm_dbg_atomic(dev, "disabling [ENCODER:%d:%s]\n", + encoder->base.id, encoder->name); + + drm_atomic_bridge_chain_disable(bridge, old_state); + + /* Right function depends upon target state. */ + if (funcs) { + if (funcs->atomic_disable) + funcs->atomic_disable(encoder, old_state); + else if (new_conn_state->crtc && funcs->prepare) + funcs->prepare(encoder); + else if (funcs->disable) + funcs->disable(encoder); + else if (funcs->dpms) + funcs->dpms(encoder, DRM_MODE_DPMS_OFF); + } - drm_atomic_bridge_chain_post_disable(bridge, old_state); + break; + + case DRM_BRIDGE_PRE_ENABLE_POST_DISABLE: + drm_atomic_bridge_chain_post_disable(bridge, old_state); + break; + + default: + drm_err(dev, "Unrecognized Encoder/Bridge Operation (%d).\n", op_type); + break; + } } } @@ -1197,7 +1210,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) struct drm_crtc_state *old_crtc_state, *new_crtc_state; int i; - encoder_bridge_chain_disable(dev, old_state); + encoder_bridge_chain_disable(dev, old_state, DRM_BRIDGE_ENABLE_DISABLE); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { const struct drm_crtc_helper_funcs *funcs; @@ -1243,6
[PATCH v5 00/13] drm/bridge: cdns-dsi: Fix the color-shift issue
Hello all, This series provides some crucial fixes and improvements for the Cadence's DSI TX (cdns-dsi) controller found commonly in Texas Instruments' J7 family of SoCs as well as in AM62P. Along with that, this series aims to fix the color-shift issue that has been going on with the DSI controller. This controller requires to be enabled before the previous entity enables its stream[0]. It's a strict requirement which, if not followed, causes the colors to "shift" on the display. The fix happens in 2 steps. 1. The bridge pre_enable calls have been shifted before the crtc_enable and the bridge post_disable calls have been shifted after the crtc_disable. This has been done as per the definition of bridge pre_enable. "The display pipe (i.e. clocks and timing signals) feeding this bridge will not yet be running when this callback is called". Since CRTC is also a source feeding the bridge, it should not be enabled before the bridges in the pipeline are pre_enabled. The sequence of enable after this patch will look like: bridge[n]_pre_enable ... bridge[1]_pre_enable crtc_enable encoder_enable bridge[1]_enable ... bridge[n]_enable and vice-versa for the bridge chain disable sequence. 2. The cdns-dsi enable / disable sequences have now been moved to pre_enable and post_disable sequences. This is the only way to have cdns-dsi drivers be up and ready before the previous entity is enables its streaming. The DSI also spec requires the Clock and Data Lanes be ready before the DSI TX enables its stream[0]. A patch has been added to make the code wait for that to happen. Going ahead with further DSI (and DSS configuration), while the lanes are not ready, has been found to be another reason for shift in colors. These patches have been tested with J721E based BeagleboneAI64 along with a RaspberryPi 7" DSI panel. The extra patches can be found in the "next_dsi_test-v5" branch of my github fork[1] for anyone who would like to test them. * Important note about the authorship of patches * All the patches in the previous revisions of this series, as well as a majority of this revision too have been authored when I owned a "ti.com" based email id, i.e. . This email id is not in use anymore, and all the work done later has been part of my personal work. Since the original patches were authored using TI's email id, I have maintained the original authorships as they are, as well as their sign offs. I have further added another another sign off that uses my current (and personal) email id, the one that is being used to send this revision, i.e. . Thanks, Aradhya [0]: Section 12.6.5.7.3: "Start-up Procedure" [For DSI TX controller] in TDA4VM Technical Reference Manual https://www.ti.com/lit/zip/spruil1 [1]: https://github.com/aradhya07/linux-ab/tree/next_dsi_test-v5 Change Log: - Changes in v5: - Fix subject and description in patch 1/13. - Add patch to check the return value of phy_mipi_dphy_get_default_config() (patch: 6/13). - Change the Clk and Data Lane ready timeout from forever to 5s. - Print an error instead of calling WARN_ON_ONCE in patch 7/13. - Drop patch v4-07/11: "drm/bridge: cdns-dsi: Reset the DCS write FIFO". There has been some inconsistencies found with this patch upon further testing. This patch was being used to enable a DSI panel based on ILITEK ILI9881C bridge. This will be debugged separately. - Add patch to move the DSI mode check from _atomic_enable() to _atomic_check() (patch: 10/13). - Split patch v4-10/11 into 2 patches - 11/13 and 12/13. Patch 11/13 separates out the Encoder-Bridge operations into a helper function *without* changing the logic. Patch 12/13 then changes the order of the encoder-bridge operations as was intended in the original patch. - Add detailed comment for patch 13/13. - Add Tomi Valkeinen's R-b in patches 1, 2, 4, 5, 7, 8, 9, 13. - Changes in v4: - Add new patch, "drm/bridge: cdns-dsi: Move to devm_drm_of_get_bridge()", to update to an auto-managed way of finding next bridge in the chain. - Drop patch "drm/bridge: cdns-dsi: Fix the phy_initialized variable" and add "drm/bridge: cdns-dsi: Fix Phy _init() and _exit()" that properly de-initializes the Phy and maintains the initialization state. - Reword patch "drm/bridge: cdns-dsi: Reset the DCS write FIFO" to explain the HW concerns better. - Add R-b tag from Dmitry Baryshkov for patches 1/11 and 8/11. - Changes in v3: - Reword the commit message for patch "drm/bridge: cdns-dsi: Fix OF node pointer". - Add a new helper API to figure out DSI host input pixel format in patch "drm/mipi-dsi: Add helper to find input format". - Use a common function for bri
[PATCH v5 04/13] drm/bridge: cdns-dsi: Fix the link and phy init order
From: Aradhya Bhatia The order of init of DSI link and DSI phy is wrong. The DSI link needs to be configured before the DSI phy is getting configured. Otherwise, the D-Phy is unable to lock in on the incoming PLL Reference clock[0]. Fix the order of inits. [0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM TRM Link: http://www.ti.com/lit/pdf/spruil1 Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index d89c32bae2b9..03a5af52ec0b 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -778,8 +778,8 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false)); - cdns_dsi_hs_init(dsi); cdns_dsi_init_link(dsi); + cdns_dsi_hs_init(dsi); writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa), dsi->regs + VID_HSIZE1); -- 2.34.1
[PATCH v5 07/13] drm/bridge: cdns-dsi: Wait for Clk and Data Lanes to be ready
From: Aradhya Bhatia Once the DSI Link and DSI Phy are initialized, the code needs to wait for Clk and Data Lanes to be ready, before continuing configuration. This is in accordance with the DSI Start-up procedure, found in the Technical Reference Manual of Texas Instrument's J721E SoC[0] which houses this DSI TX controller. If the previous bridge (or crtc/encoder) are configured pre-maturely, the input signal FIFO gets corrupt. This introduces a color-shift on the display. Allow the driver to wait for the clk and data lanes to get ready during DSI enable. [0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM TRM Link: http://www.ti.com/lit/pdf/spruil1 Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Tested-by: Dominik Haller Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index e4c0968313af..284c468db6c3 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -767,7 +767,7 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long tx_byte_period; struct cdns_dsi_cfg dsi_cfg; - u32 tmp, reg_wakeup, div; + u32 tmp, reg_wakeup, div, status; int nlanes; if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) @@ -784,6 +784,19 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) cdns_dsi_init_link(dsi); cdns_dsi_hs_init(dsi); + /* +* Now that the DSI Link and DSI Phy are initialized, +* wait for the CLK and Data Lanes to be ready. +*/ + tmp = CLK_LANE_RDY; + for (int i = 0; i < nlanes; i++) + tmp |= DATA_LANE_RDY(i); + + if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status, + status & tmp, 100, 50)) + dev_err(dsi->base.dev, + "Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n"); + writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa), dsi->regs + VID_HSIZE1); writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact), -- 2.34.1
[PATCH v5 05/13] drm/bridge: cdns-dsi: Fix the clock variable for mode_valid()
From: Aradhya Bhatia Allow the D-Phy config checks to use mode->clock instead of mode->crtc_clock during mode_valid checks, like everywhere else in the driver. Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 03a5af52ec0b..2fc24352d989 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -568,13 +568,14 @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long dsi_hss_hsa_hse_hbp; unsigned int nlanes = output->dev->lanes; + int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); int ret; ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); if (ret) return ret; - phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, + phy_mipi_dphy_get_default_config(mode_clock * 1000, mipi_dsi_pixel_format_to_bpp(output->dev->format), nlanes, phy_cfg); -- 2.34.1
Re: [PATCH v7 1/5] drm: Introduce device wedged event
On Thu, Oct 17, 2024 at 04:16:09PM -0300, André Almeida wrote: > Hi Raag, > > Em 30/09/2024 04:38, Raag Jadav escreveu: > > Introduce device wedged event, which will notify userspace of wedged > > (hanged/unusable) state of the DRM device through a uevent. This is > > useful especially in cases where the device is no longer operating as > > expected even after a hardware reset and has become unrecoverable from > > driver context. > > > > Purpose of this implementation is to provide drivers a generic way to > > recover with the help of userspace intervention. Different drivers may > > have different ideas of a "wedged device" depending on their hardware > > implementation, and hence the vendor agnostic nature of the event. > > It is up to the drivers to decide when they see the need for recovery > > and how they want to recover from the available methods. > > > > Current implementation defines three recovery methods, out of which, > > drivers can choose to support any one or multiple of them. Preferred > > recovery method will be sent in the uevent environment as WEDGED=. > > Userspace consumers (sysadmin) can define udev rules to parse this event > > and take respective action to recover the device. > > > > === == > > Recovery method Consumer expectations > > === == > > rebind unbind + rebind driver > > bus-reset unbind + reset bus device + rebind > > reboot reboot system > > === == > > > > > > I proposed something similar in the past: > https://lore.kernel.org/dri-devel/20221125175203.52481-1-andrealm...@igalia.com/ Thanks for sharing. I went through it and I think we can use some of the ideas with generic adaption. While we can always execute scripts on uevent, it'd be good to have a userspace daemon applying automated policies for wedge cases based on admin/user needs. This way we can also manage repeat offenders. Xe has devcoredump so telemetry would also be a nice addition. Great opportunity to collaborate here. > The motivation was that amdgpu was getting stuck after every GPU reset, and > there was just a black screen. The uevent would then trigger a daemon to > reset the compositor and getting things back together. As you can see in my > thread, the feature was blocked in favor of getting better overall GPU reset > from the kernel side. We have hardware level resets but (although rare) they're also prone to failure. We do what we can to recover from driver context but it adds on to the complexity overtime. Something like wedging, if done right, would be much more robust IMHO. Raag
[PATCH v3 5/6] drm/xe: Set XE_BO_FLAG_PINNED in migrate selftest BOs
We only allow continguous BOs to be vmapped, set XE_BO_FLAG_PINNED on BOs in migrate selftest as this forces continguous BOs and selftest uses vmaps. Signed-off-by: Matthew Brost --- drivers/gpu/drm/xe/tests/xe_migrate.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c index 1a192a2a941b..4cef3b20bd17 100644 --- a/drivers/gpu/drm/xe/tests/xe_migrate.c +++ b/drivers/gpu/drm/xe/tests/xe_migrate.c @@ -83,7 +83,8 @@ static void test_copy(struct xe_migrate *m, struct xe_bo *bo, bo->size, ttm_bo_type_kernel, region | - XE_BO_FLAG_NEEDS_CPU_ACCESS); + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_PINNED); if (IS_ERR(remote)) { KUNIT_FAIL(test, "Failed to allocate remote bo for %s: %pe\n", str, remote); @@ -642,7 +643,9 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til sys_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M, DRM_XE_GEM_CPU_CACHING_WC, - XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS); + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_PINNED); if (IS_ERR(sys_bo)) { KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n", @@ -666,7 +669,8 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til ccs_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M, DRM_XE_GEM_CPU_CACHING_WC, - bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS); + bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_PINNED); if (IS_ERR(ccs_bo)) { KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n", @@ -690,7 +694,8 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til vram_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M, DRM_XE_GEM_CPU_CACHING_WC, - bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS); + bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_PINNED); if (IS_ERR(vram_bo)) { KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n", PTR_ERR(vram_bo)); -- 2.34.1
[PATCH v5 08/13] drm/mipi-dsi: Add helper to find input format
From: Aradhya Bhatia Add a helper API that can be used by the DSI hosts to find the required input bus format for the given output dsi pixel format. Reviewed-by: Dmitry Baryshkov Reviewed-by: Tomi Valkeinen Signed-off-by: Aradhya Bhatia Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/drm_mipi_dsi.c | 37 ++ include/drm/drm_mipi_dsi.h | 1 + 2 files changed, 38 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 5e5c5f84daac..076826f2445a 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -36,6 +36,8 @@ #include #include +#include + #include /** @@ -870,6 +872,41 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, } EXPORT_SYMBOL(mipi_dsi_generic_read); +/** + * drm_mipi_dsi_get_input_bus_fmt() - Get the required MEDIA_BUS_FMT_* based + * input pixel format for a given DSI output + * pixel format + * @dsi_format: pixel format that a DSI host needs to output + * + * Various DSI hosts can use this function during their + * &drm_bridge_funcs.atomic_get_input_bus_fmts operation to ascertain + * the MEDIA_BUS_FMT_* pixel format required as input. + * + * RETURNS: + * a 32-bit MEDIA_BUS_FMT_* value on success or 0 in case of failure. + */ +u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format) +{ + switch (dsi_format) { + case MIPI_DSI_FMT_RGB888: + return MEDIA_BUS_FMT_RGB888_1X24; + + case MIPI_DSI_FMT_RGB666: + return MEDIA_BUS_FMT_RGB666_1X24_CPADHI; + + case MIPI_DSI_FMT_RGB666_PACKED: + return MEDIA_BUS_FMT_RGB666_1X18; + + case MIPI_DSI_FMT_RGB565: + return MEDIA_BUS_FMT_RGB565_1X16; + + default: + /* Unsupported DSI Format */ + return 0; + } +} +EXPORT_SYMBOL(drm_mipi_dsi_get_input_bus_fmt); + /** * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload * @dsi: DSI peripheral device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 94400a78031f..9e2804e3a2b0 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -293,6 +293,7 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, const void *payload, size_t size); ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size); +u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format); #define mipi_dsi_msleep(ctx, delay)\ do {\ -- 2.34.1