Re: [PATCH 1/2] dt-bindings: display: bridge: tc358768: switch to bus-width
On 03/10/2024 15:39, Krzysztof Kozlowski wrote: "data-lines" property is way too similar to "data-lanes". It is also duplicating "bus-width" from video-interfaces.yaml schema. Deprecate "data-lines" and use the common property. Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/display/bridge/toshiba,tc358768.yaml | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml index 779d8c57f854..bb5d3b543800 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml @@ -60,6 +60,10 @@ properties: data-lines: $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 16, 18, 24 ] +deprecated: true + + bus-width: +enum: [ 16, 18, 24 ] port@1: $ref: /schemas/graph.yaml#/properties/port Reviewed-by: Neil Armstrong
Re: [PATCH 2/2] drm/bridge: tc358768: switch to bus-width
On 03/10/2024 15:39, Krzysztof Kozlowski wrote: "data-lines" property is way too similar to "data-lanes". It is also duplicating "bus-width" from video-interfaces.yaml schema. "data-lines" was deprecated in the bindings and "bus-width" is preferred, so parse it instead while keeping things backwards compatible. Signed-off-by: Krzysztof Kozlowski --- drivers/gpu/drm/bridge/tc358768.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 0e8813278a2f..fc96fa5aab54 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -443,7 +443,9 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, ret = -EINVAL; ep = of_graph_get_endpoint_by_regs(host->dev->of_node, 0, 0); if (ep) { - ret = of_property_read_u32(ep, "data-lines", &priv->pd_lines); + ret = of_property_read_u32(ep, "bus-width", &priv->pd_lines); + if (ret) + ret = of_property_read_u32(ep, "data-lines", &priv->pd_lines); of_node_put(ep); } Reviewed-by: Neil Armstrong
Re: [PATCH v2 10/10] drm/meson: Allow build with COMPILE_TEST=y
On 03/10/2024 13:18, Ville Syrjala wrote: From: Ville Syrjälä Allow meson to be built with COMPILE_TEST=y for greater coverage. Builds fine on x86/x86_64 at least. Cc: Neil Armstrong Cc: linux-amlo...@lists.infradead.org Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/meson/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index b410e0d8015a..417f79829cf8 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config DRM_MESON tristate "DRM Support for Amlogic Meson Display Controller" - depends on DRM && OF && (ARM || ARM64) + depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on ARCH_MESON || COMPILE_TEST select DRM_CLIENT_SELECTION select DRM_KMS_HELPER Reviewed-by: Neil Armstrong
Re: [RFC PATCH 1/1] drm/meson: Support drm_panic
Hi, On 02/10/2024 13:02, Maxime Ripard wrote: + Jocelyn On Wed, Oct 02, 2024 at 09:59:57AM GMT, Neil Armstrong wrote: diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c index b43ac61201f3..b2def784c00d 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "meson_plane.h" #include "meson_registers.h" @@ -419,10 +421,49 @@ static void meson_plane_atomic_disable(struct drm_plane *plane, priv->viu.osd1_enabled = false; } +static int meson_plane_get_scanout_buffer(struct drm_plane *plane, + struct drm_scanout_buffer *sb) +{ + struct meson_plane *meson_plane = to_meson_plane(plane); + struct meson_drm *priv = meson_plane->priv; + struct drm_framebuffer *fb; + + if (!meson_plane->enabled) + return -ENODEV; + + if (priv->viu.osd1_afbcd) { + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) { This should be meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A) You should call: if (priv->afbcd.ops) { priv->afbcd.ops->reset(priv); priv->afbcd.ops->disable(priv); } I'm not sure it's a good idea. This code is run in the panic path, and it comes with strict requirements that these functions don't have. It'll be incredibly easy to add a sleeping call or a lock in there. On a more fundamental level, I'm not sure we should be disableing AFBC at all. Do we even have the guarantee that the buffer is large enough to hold XRGB pixels? Yes it does, "compressed" is in he way pixels are ordered in memory, meaning it will be faster to scanout when the image is simple, but with a fully random image the buffer will be larger. But per my comment, AFBC is really only used on Android producst since it requires DRM_FORMAT_XBGR, so the best is to bail out when AFBC is enabled. Neil Maxime
Re: [RFC PATCH 1/1] drm/meson: Support drm_panic
Hi ! On 01/10/2024 23:04, Yao Zi wrote: This patch implements drm_plane_helper_funcs.get_scanout_buffer for primary plane, enabling meson-drm to work with drm_panic. This implementation tries to use current framebuffer as scanout buffer. In case of AFBC enabled, we disable the decoder path and adjust OSD1 parameters in get_scanout_buffer to make the buffer linear. Tested on TTY and Wayland session (Sway). Thanks for enabling this! Signed-off-by: Yao Zi --- drivers/gpu/drm/meson/meson_plane.c | 47 +++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c index b43ac61201f3..b2def784c00d 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "meson_plane.h" #include "meson_registers.h" @@ -419,10 +421,49 @@ static void meson_plane_atomic_disable(struct drm_plane *plane, priv->viu.osd1_enabled = false; } +static int meson_plane_get_scanout_buffer(struct drm_plane *plane, + struct drm_scanout_buffer *sb) +{ + struct meson_plane *meson_plane = to_meson_plane(plane); + struct meson_drm *priv = meson_plane->priv; + struct drm_framebuffer *fb; + + if (!meson_plane->enabled) + return -ENODEV; + + if (priv->viu.osd1_afbcd) { + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) { This should be meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A) You should call: if (priv->afbcd.ops) { priv->afbcd.ops->reset(priv); priv->afbcd.ops->disable(priv); } + writel_relaxed(0, priv->io_base + + _REG(VIU_OSD1_BLK1_CFG_W4)); + writel_relaxed(0, priv->io_base + + _REG(VIU_OSD1_BLK2_CFG_W4)); + writel_bits_relaxed(OSD_ENDIANNESS_LE, OSD_ENDIANNESS_LE, + priv->io_base + + _REG(VIU_OSD1_BLK0_CFG_W0)); This won't work, drop it, the canvas isn't correctly configured, you should instead call: meson_canvas_config(priv->canvas, priv->canvas_id_osd1, priv->viu.osd1_addr, priv->viu.osd1_stride, priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE, MESON_CANVAS_BLKMODE_LINEAR, 0); + meson_viu_g12a_disable_osd1_afbc(priv); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { And here meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) + writel_bits_relaxed(OSD_DPATH_MALI_AFBCD, 0, + priv->io_base + + _REG(VIU_OSD1_CTRL_STAT2)); Ok, you should also call meson_canvas_config() You should call: if (priv->afbcd.ops) { priv->afbcd.ops->reset(priv); priv->afbcd.ops->disable(priv); } + meson_viu_gxm_disable_osd1_afbc(priv); + } + } I thing the code should look like: if (priv->viu.osd1_afbcd) { meson_canvas_config(priv->canvas, priv->canvas_id_osd1, priv->viu.osd1_addr, priv->viu.osd1_stride, priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE, MESON_CANVAS_BLKMODE_LINEAR, 0); if (priv->afbcd.ops) { priv->afbcd.ops->reset(priv); priv->afbcd.ops->disable(priv); } if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { writel_bits_relaxed(OSD_ENDIANNESS_LE, OSD_ENDIANNESS_LE, priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0)); meson_viu_g12a_disable_osd1_afbc(priv); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) { writel_bits_relaxed(OSD_DPATH_MALI_AFBCD, 0, priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); meson_viu_gxm_disable_osd1_afbc(priv); } } AFBC is quite hard to test since it requires DRM_FORMAT_XBGR, but I think sway should perhaps support it, Mesa should also support AFBC. At some point I made some memory dumps of AFBC buffers, perhaps they could be useful he
Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
Hi, On 30/09/2024 21:19, Jessica Zhang wrote: On 9/30/2024 7:17 AM, neil.armstr...@linaro.org wrote: On 25/09/2024 00:59, Jessica Zhang wrote: Cache the CWB block mask in the DPU virtual encoder and configure CWB according to the CWB block mask within the writeback phys encoder Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 - .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/ gpu/drm/msm/disp/dpu1/dpu_encoder.c index b2f0bf412451..2628f2d55cb3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -24,6 +24,7 @@ #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" #include "dpu_hw_ctl.h" +#include "dpu_hw_cwb.h" #include "dpu_hw_dspp.h" #include "dpu_hw_dsc.h" #include "dpu_hw_merge3d.h" @@ -139,6 +140,7 @@ enum dpu_enc_rc_states { * num_phys_encs. * @hw_dsc: Handle to the DSC blocks used for the display. * @dsc_mask: Bitmask of used DSC blocks. + * @cwb_mask Bitmask of used CWB muxes * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped * for partial update right-only cases, such as pingpong * split where virtual pingpong does not generate IRQs @@ -185,6 +187,7 @@ struct dpu_encoder_virt { struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; unsigned int dsc_mask; + unsigned int cwb_mask; bool intfs_swapped; @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, int num_cwb = 0; bool is_cwb_encoder; unsigned int dsc_mask = 0; + unsigned int cwb_mask = 0; int i; if (!drm_enc) { @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, ARRAY_SIZE(hw_pp)); } - for (i = 0; i < num_cwb; i++) + for (i = 0; i < num_cwb; i++) { dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]); + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0); + } + + dpu_enc->cwb_mask = cwb_mask; dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) } } + if (dpu_enc->cwb_mask) + dpu_encoder_helper_phys_setup_cwb(phys_enc, false); + /* reset the merge 3D HW block */ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc- >hw_pp->merge_3d, @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) ctl->ops.clear_pending_flush(ctl); } +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc, + bool enable) +{ + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc- >parent); + struct dpu_hw_cwb *hw_cwb; + struct dpu_hw_cwb_setup_cfg cwb_cfg; + + struct dpu_kms *dpu_kms; + struct dpu_global_state *global_state; + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC]; + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC]; + + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask) + return; + + dpu_kms = phys_enc->dpu_kms; + global_state = dpu_kms_get_existing_global_state(dpu_kms); + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + phys_enc->parent->crtc, + DPU_HW_BLK_PINGPONG, rt_pp_list, + ARRAY_SIZE(rt_pp_list)); + + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) { + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp); + return; + } + + for (int i = 0; i < num_pp; i++) { + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]); + + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) { + hw_cwb = dpu_enc->hw_cwb[i]; + + /* + * Even CWB muxes must take input from even real-time + * pingpongs and odd CWB muxes must take input from odd + * pingpongs + */ + if (hw_pp->idx % 2 == hw_cwb->idx % 2) { When running igt-test on QRD8650, I get: # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt- gpu-tools/kms_writeback -d Hi Neil, Thanks for reporting this. Unfortunately, I'm not able to recreate this on the MTP8650. How many/which non-WB outputs are you testing with? Here's the modetest output: ==>< Encoders: id crtctypepossible crtcs possible clones 32 103 DSI 0x0007 0x0005
Re: [PATCH] drm: panel: jd9365da-h3: Remove unused num_init_cmds structure member
On 30/09/2024 19:05, Hugo Villeneuve wrote: From: Hugo Villeneuve Now that the driver has been converted to use wrapped MIPI DCS functions, the num_init_cmds structure member is no longer needed, so remove it. Fixes: 35583e129995 ("drm/panel: panel-jadard-jd9365da-h3: use wrapped MIPI DCS functions") Cc: Signed-off-by: Hugo Villeneuve --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 44897e5218a6..45d09e6fa667 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -26,7 +26,6 @@ struct jadard_panel_desc { unsigned int lanes; enum mipi_dsi_pixel_format format; int (*init)(struct jadard *jadard); - u32 num_init_cmds; bool lp11_before_reset; bool reset_before_power_off_vcioo; unsigned int vcioo_to_lp11_delay_ms; base-commit: 9852d85ec9d492ebef56dc5f229416c925758edc Reviewed-by: Neil Armstrong
Re: [PATCH] drm: panel: jd9365da-h3: fix reset signal polarity
On 30/09/2024 17:05, Hugo Villeneuve wrote: On Mon, 30 Sep 2024 16:38:14 +0200 Neil Armstrong wrote: Hi, On 27/09/2024 15:53, Hugo Villeneuve wrote: From: Hugo Villeneuve In jadard_prepare() a reset pulse is generated with the following statements (delays ommited for clarity): gpiod_set_value(jadard->reset, 1); --> Deassert reset gpiod_set_value(jadard->reset, 0); --> Assert reset for 10ms gpiod_set_value(jadard->reset, 1); --> Deassert reset However, specifying second argument of "0" to gpiod_set_value() means to deassert the GPIO, and "1" means to assert it. If the reset signal is defined as GPIO_ACTIVE_LOW in the DTS, the above statements will incorrectly generate the reset pulse (inverted) and leave it asserted (LOW) at the end of jadard_prepare(). Did you check the polarity in DTS of _all_ users of this driver ? Hi Neil, I confirmed that no in-tree DTS is referencing this driver. I did a search of all the compatible strings defined in the "jadard,jd9365da-h3.yaml" file. I also did the same on Debian code search. OK then: Reviewed-by: Neil Armstrong Hugo. Neil Fix reset behavior by inverting gpiod_set_value() second argument in jadard_prepare(). Also modify second argument to devm_gpiod_get() in jadard_dsi_probe() to assert the reset when probing. Do not modify it in jadard_unprepare() as it is already properly asserted with "1", which seems to be the intended behavior. Fixes: 6b818c533dd8 ("drm: panel: Add Jadard JD9365DA-H3 DSI panel") Cc: Signed-off-by: Hugo Villeneuve --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 44897e5218a69..6fec99cf4d935 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -110,13 +110,13 @@ static int jadard_prepare(struct drm_panel *panel) if (jadard->desc->lp11_to_reset_delay_ms) msleep(jadard->desc->lp11_to_reset_delay_ms); - gpiod_set_value(jadard->reset, 1); + gpiod_set_value(jadard->reset, 0); msleep(5); - gpiod_set_value(jadard->reset, 0); + gpiod_set_value(jadard->reset, 1); msleep(10); - gpiod_set_value(jadard->reset, 1); + gpiod_set_value(jadard->reset, 0); msleep(130); ret = jadard->desc->init(jadard); @@ -1131,7 +1131,7 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes; - jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(jadard->reset)) { DRM_DEV_ERROR(&dsi->dev, "failed to get our reset GPIO\n"); return PTR_ERR(jadard->reset); base-commit: 18ba6034468e7949a9e2c2cf28e2e123b4fe7a50
Re: [PATCH] drm: panel: jd9365da-h3: fix reset signal polarity
Hi, On 27/09/2024 15:53, Hugo Villeneuve wrote: From: Hugo Villeneuve In jadard_prepare() a reset pulse is generated with the following statements (delays ommited for clarity): gpiod_set_value(jadard->reset, 1); --> Deassert reset gpiod_set_value(jadard->reset, 0); --> Assert reset for 10ms gpiod_set_value(jadard->reset, 1); --> Deassert reset However, specifying second argument of "0" to gpiod_set_value() means to deassert the GPIO, and "1" means to assert it. If the reset signal is defined as GPIO_ACTIVE_LOW in the DTS, the above statements will incorrectly generate the reset pulse (inverted) and leave it asserted (LOW) at the end of jadard_prepare(). Did you check the polarity in DTS of _all_ users of this driver ? Neil Fix reset behavior by inverting gpiod_set_value() second argument in jadard_prepare(). Also modify second argument to devm_gpiod_get() in jadard_dsi_probe() to assert the reset when probing. Do not modify it in jadard_unprepare() as it is already properly asserted with "1", which seems to be the intended behavior. Fixes: 6b818c533dd8 ("drm: panel: Add Jadard JD9365DA-H3 DSI panel") Cc: Signed-off-by: Hugo Villeneuve --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 44897e5218a69..6fec99cf4d935 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -110,13 +110,13 @@ static int jadard_prepare(struct drm_panel *panel) if (jadard->desc->lp11_to_reset_delay_ms) msleep(jadard->desc->lp11_to_reset_delay_ms); - gpiod_set_value(jadard->reset, 1); + gpiod_set_value(jadard->reset, 0); msleep(5); - gpiod_set_value(jadard->reset, 0); + gpiod_set_value(jadard->reset, 1); msleep(10); - gpiod_set_value(jadard->reset, 1); + gpiod_set_value(jadard->reset, 0); msleep(130); ret = jadard->desc->init(jadard); @@ -1131,7 +1131,7 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes; - jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(jadard->reset)) { DRM_DEV_ERROR(&dsi->dev, "failed to get our reset GPIO\n"); return PTR_ERR(jadard->reset); base-commit: 18ba6034468e7949a9e2c2cf28e2e123b4fe7a50
Re: [PATCH v5 2/2] drm/panel: Add support for S6E3HA8 panel driver
lice_count = 1440 / priv->dsc.slice_width; + priv->dsc.bits_per_component = 8; + priv->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */ + priv->dsc.block_pred_enable = true; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&priv->panel); + return ret; + } + + return 0; +} + +static void s6e3ha8_amb577px01_wqhd_remove(struct mipi_dsi_device *dsi) +{ + struct s6e3ha8 *priv = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&priv->panel); +} + +static const struct of_device_id s6e3ha8_amb577px01_wqhd_of_match[] = { + { .compatible = "samsung,s6e3ha8" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, s6e3ha8_amb577px01_wqhd_of_match); + +static struct mipi_dsi_driver s6e3ha8_amb577px01_wqhd_driver = { + .probe = s6e3ha8_amb577px01_wqhd_probe, + .remove = s6e3ha8_amb577px01_wqhd_remove, + .driver = { + .name = "panel-s6e3ha8", + .of_match_table = s6e3ha8_amb577px01_wqhd_of_match, + }, +}; +module_mipi_dsi_driver(s6e3ha8_amb577px01_wqhd_driver); + +MODULE_AUTHOR("Dzmitry Sankouski "); +MODULE_DESCRIPTION("DRM driver for S6E3HA8 panel"); +MODULE_LICENSE("GPL"); With that fixes: Reviewed-by: Neil Armstrong Thanks, Neil
Re: [PATCH 5/6] drm/panel: ili9322: Constify struct regmap_bus
On 25/09/2024 17:42, Javier Carrasco wrote: `ili9322_regmap_bus` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco --- drivers/gpu/drm/panel/panel-ilitek-ili9322.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index 4a6dcfd781e8..94b7dfef3b5e 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -318,7 +318,7 @@ static int ili9322_regmap_spi_read(void *context, const void *reg, return spi_write_then_read(spi, buf, 1, val, 1); } -static struct regmap_bus ili9322_regmap_bus = { +static const struct regmap_bus ili9322_regmap_bus = { .write = ili9322_regmap_spi_write, .read = ili9322_regmap_spi_read, .reg_format_endian_default = REGMAP_ENDIAN_BIG, Reviewed-by: Neil Armstrong
Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
On 25/09/2024 00:59, Jessica Zhang wrote: Cache the CWB block mask in the DPU virtual encoder and configure CWB according to the CWB block mask within the writeback phys encoder Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 83 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 - .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 4 +- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index b2f0bf412451..2628f2d55cb3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -24,6 +24,7 @@ #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" #include "dpu_hw_ctl.h" +#include "dpu_hw_cwb.h" #include "dpu_hw_dspp.h" #include "dpu_hw_dsc.h" #include "dpu_hw_merge3d.h" @@ -139,6 +140,7 @@ enum dpu_enc_rc_states { *num_phys_encs. * @hw_dsc: Handle to the DSC blocks used for the display. * @dsc_mask: Bitmask of used DSC blocks. + * @cwb_mask Bitmask of used CWB muxes * @intfs_swapped:Whether or not the phys_enc interfaces have been swapped *for partial update right-only cases, such as pingpong *split where virtual pingpong does not generate IRQs @@ -185,6 +187,7 @@ struct dpu_encoder_virt { struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; unsigned int dsc_mask; + unsigned int cwb_mask; bool intfs_swapped; @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, int num_cwb = 0; bool is_cwb_encoder; unsigned int dsc_mask = 0; + unsigned int cwb_mask = 0; int i; if (!drm_enc) { @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, ARRAY_SIZE(hw_pp)); } - for (i = 0; i < num_cwb; i++) + for (i = 0; i < num_cwb; i++) { dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]); + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0); + } + + dpu_enc->cwb_mask = cwb_mask; dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) } } + if (dpu_enc->cwb_mask) + dpu_encoder_helper_phys_setup_cwb(phys_enc, false); + /* reset the merge 3D HW block */ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) ctl->ops.clear_pending_flush(ctl); } +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc, + bool enable) +{ + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent); + struct dpu_hw_cwb *hw_cwb; + struct dpu_hw_cwb_setup_cfg cwb_cfg; + + struct dpu_kms *dpu_kms; + struct dpu_global_state *global_state; + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC]; + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC]; + + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask) + return; + + dpu_kms = phys_enc->dpu_kms; + global_state = dpu_kms_get_existing_global_state(dpu_kms); + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + phys_enc->parent->crtc, + DPU_HW_BLK_PINGPONG, rt_pp_list, + ARRAY_SIZE(rt_pp_list)); + + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) { + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp); + return; + } + + for (int i = 0; i < num_pp; i++) { + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]); + + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) { + hw_cwb = dpu_enc->hw_cwb[i]; + + /* +* Even CWB muxes must take input from even real-time +* pingpongs and odd CWB muxes must take input from odd +* pingpongs +*/ + if (hw_pp->idx % 2 == hw_cwb->idx % 2) { When running igt-test on QRD8650, I get: # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt-gpu-tools/kms_writeback -d [ 2566.668998] Console: switching to colour dummy device 80x25 IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-
Re: [PATCH 09/28] drm/meson: Use video aperture helpers
On 30/09/2024 15:03, 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: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl --- drivers/gpu/drm/meson/meson_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 2f76f48da38d..bbb662d2f184 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -8,6 +8,7 @@ * Jasper St. Pierre */ +#include #include #include #include @@ -15,7 +16,6 @@ #include #include -#include #include #include #include @@ -279,7 +279,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) * Remove early framebuffers (ie. simplefb). The framebuffer can be * located anywhere in RAM */ - ret = drm_aperture_remove_framebuffers(&meson_driver); + ret = aperture_remove_all_conflicting_devices(meson_driver.name); if (ret) goto free_canvas_vd1_2; Reviewed-by: Neil Armstrong
Re: [PATCH] drm: panel: nv3052c: correct spi_device_id for RG35XX panel
On 29/09/2024 10:19, Ryan Walklin wrote: The Anbernic RG35XX devices use an SPI LCD panel from an unknown OEM, with an NV3052C driver chip. As discussed previously, the integrating vendor and device name are preferred instead of the OEM serial. A previous patch corrected the device tree binding and of_device_id in the NV3052C driver, however the spi_device_id also needs correction. Correct the spi_device_id for the RG35XX panel. Signed-off-by: Ryan Walklin Fixes: 76dce2a9 ("drm: panel: nv3052c: Correct WL-355608-A8 panel compatible") --- drivers/gpu/drm/panel/panel-newvision-nv3052c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index d3baccfe6286b..06e16a7c14a75 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -917,7 +917,7 @@ static const struct nv3052c_panel_info wl_355608_a8_panel_info = { static const struct spi_device_id nv3052c_ids[] = { { "ltk035c5444t", }, { "fs035vg158", }, - { "wl-355608-a8", }, + { "rg35xx-plus-panel", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, nv3052c_ids); Reviewed-by: Neil Armstrong
Re: [PATCH v4 00/11] Preemption support for A7XX
Le 20/09/2024 à 19:09, Akhil P Oommen a écrit : On Wed, Sep 18, 2024 at 09:46:33AM +0200, Neil Armstrong wrote: Hi, On 17/09/2024 13:14, Antonino Maniscalco wrote: This series implements preemption for A7XX targets, which allows the GPU to switch to an higher priority ring when work is pushed to it, reducing latency for high priority submissions. This series enables L1 preemption with skip_save_restore which requires the following userspace patches to function: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544 A flag is added to `msm_submitqueue_create` to only allow submissions from compatible userspace to be preempted, therefore maintaining compatibility. Preemption is currently only enabled by default on A750, it can be enabled on other targets through the `enable_preemption` module parameter. This is because more testing is required on other targets. For testing on other HW it is sufficient to set that parameter to a value of 1, then using the branch of mesa linked above, `TU_DEBUG=hiprio` allows to run any application as high priority therefore preempting submissions from other applications. The `msm_gpu_preemption_trigger` and `msm_gpu_preemption_irq` traces added in this series can be used to observe preemption's behavior as well as measuring preemption latency. Some commits from this series are based on a previous series to enable preemption on A6XX targets: https://lkml.kernel.org/1520489185-21828-1-git-send-email-smase...@codeaurora.org Signed-off-by: Antonino Maniscalco --- Changes in v4: - Added missing register in pwrup list - Removed and rearrange barriers - Renamed `skip_inline_wptr` to `restore_wptr` - Track ctx seqno per ring - Removed secure preempt context - NOP out postamble to disable it instantly - Only emit pwrup reglist once - Document bv_rptr_addr - Removed unused A6XX_PREEMPT_USER_RECORD_SIZE - Set name on preempt record buffer - Link to v3: https://lore.kernel.org/r/20240905-preemption-a750-t-v3-0-fd947699f...@gmail.com Changes in v3: - Added documentation about preemption - Use quirks to determine which target supports preemption - Add a module parameter to force disabling or enabling preemption - Clear postamble when profiling - Define A6XX_CP_CONTEXT_SWITCH_CNTL_LEVEL fields in a6xx.xml - Make preemption records MAP_PRIV - Removed user ctx record (NON_PRIV) and patch 2/9 as it's not needed anymore - Link to v2: https://lore.kernel.org/r/20240830-preemption-a750-t-v2-0-86aeead2c...@gmail.com Changes in v2: - Added preept_record_size for X185 in PATCH 3/7 - Added patches to reset perf counters - Dropped unused defines - Dropped unused variable (fixes warning) - Only enable preemption on a750 - Reject MSM_SUBMITQUEUE_ALLOW_PREEMPT for unsupported targets - Added Akhil's Reviewed-By tags to patches 1/9,2/9,3/9 - Added Neil's Tested-By tags - Added explanation for UAPI changes in commit message - Link to v1: https://lore.kernel.org/r/20240815-preemption-a750-t-v1-0-7bda26c34...@gmail.com --- Antonino Maniscalco (11): drm/msm: Fix bv_fence being used as bv_rptr drm/msm/A6XX: Track current_ctx_seqno per ring drm/msm: Add a `preempt_record_size` field drm/msm: Add CONTEXT_SWITCH_CNTL bitfields drm/msm/A6xx: Implement preemption for A7XX targets drm/msm/A6xx: Sync relevant adreno_pm4.xml changes drm/msm/A6xx: Use posamble to reset counters on preemption drm/msm/A6xx: Add traces for preemption drm/msm/A6XX: Add a flag to allow preemption to submitqueue_create drm/msm/A6xx: Enable preemption for A750 Documentation: document adreno preemption Documentation/gpu/msm-preemption.rst | 98 + drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 +- drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 7 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 325 ++- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 174 drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 440 + drivers/gpu/drm/msm/adreno/adreno_gpu.h| 9 +- drivers/gpu/drm/msm/msm_drv.c | 4 + drivers/gpu/drm/msm/msm_gpu.c | 2 +- drivers/gpu/drm/msm/msm_gpu.h | 11 - drivers/gpu/drm/msm/msm_gpu_trace.h| 28 ++ drivers/gpu/drm/msm/msm_ringbuffer.h | 18 + drivers/gpu/drm/msm/msm_submitqueue.c | 3 + drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 7 +- .../gpu/drm/msm/registers/adreno/adreno_pm4.xml| 39 +- include/uapi/drm/msm_drm.h | 5 +- 20 files changed, 11
Re: [PATCH v2 09/10] drm: bridge: dw_hdmi: Update EDID during hotplug processing
On 19/09/2024 22:34, Jonas Karlman wrote: Hi Neil, On 2024-09-13 10:02, Neil Armstrong wrote: On 08/09/2024 15:28, Jonas Karlman wrote: Update successfully read EDID during hotplug processing to ensure the connector diplay_info is always up-to-date. Signed-off-by: Jonas Karlman --- v2: No change --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index c19307120909..7bd9f895f03f 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2457,6 +2457,18 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) status = dw_hdmi_detect(hdmi); + /* Update EDID during hotplug processing (force=false) */ + if (status == connector_status_connected && !force) { + const struct drm_edid *drm_edid; + + drm_edid = dw_hdmi_edid_read(hdmi, connector); + if (drm_edid) + drm_edid_connector_update(connector, drm_edid); + cec_notifier_set_phys_addr(hdmi->cec_notifier, + connector->display_info.source_physical_address); + drm_edid_free(drm_edid); + } + if (status == connector_status_disconnected) cec_notifier_phys_addr_invalidate(hdmi->cec_notifier); I wonder why we should read edid at each dw_hdmi_connector_detect() call, AFAIK it should only be when we have HPD pulses That is what this change intends to help do. As stated in the short comment EDID is only updated at HPD processing, i.e. when force=false. To be on the safe side EDID is also only updated here when connected and EDID could be read. drm_helper_probe_detect() is called with force=true in the fill_modes/get_modes call path that is triggered by userspace or the kernel kms client. After a HPD interrupt the call to drm_helper_hpd_irq_event() will call check_connector_changed() that in turn calls drm_helper_probe_detect() with force=false to check/detect if connector status has changed. It is in this call chain the EDID may be read and updated in this detect ops. Reading EDID here at HPD processing may not be fully needed, however it help kernel keep the internal EDID state in better sync with sink when userspace does not act on the HOTPLUG=1 uevent. I understand but if somehow a dw-hdmi integration fails to have HDP working properly, EDID will be read continuously which is really not what we want. HDMI 1.4b specifies in Section 8.5 and Appendix A: ><== An HDMI Sink shall not assert high voltage level on its Hot Plug Detect pin when the E-EDID is not available for reading. An HDMI Sink shall indicate any change to the contents of the E-EDID by driving a low voltage level pulse on the Hot Plug Detect pin. This pulse shall be at least 100 msec. ><== So this is OK with the first sentence, and should also work with the second one because right after the pulse we will read the EDID again, but I think we should have a much more robust way to detect those 100ms pulses, no ? Maxime, do you have an opinion on this ? Neil Regards, Jonas Neil
Re: [PATCH v4 00/11] Preemption support for A7XX
regards, I've been running vulkan-cts (1.3.7.3-0-gd71a36db16d98313c431829432a136dbda692a08 from Yocto) on SM8650-QRD, SM8550-QRD & SM8450-HDK boards with enable_preemption in default value and forced to 1, and I've seen no regression so far On SM8550, I've seen a few: platform 3d6a000.gmu: [drm:a6xx_hfi_send_msg.constprop.0 [msm]] *ERROR* Message HFI_H2F_MSG_GX_BW_PERF_VOTE id 2743 timed out waiting for response platform 3d6a000.gmu: [drm:a6xx_hfi_send_msg.constprop.0 [msm]] *ERROR* Unexpected message id 2743 on the response queue but it's unrelated to preempt and on SM8450: platform 3d6a000.gmu: [drm:a6xx_gmu_set_oob [msm]] *ERROR* Timeout waiting for GMU OOB set GPU_SET: 0x0 msm_dpu ae01000.display-controller: [drm:hangcheck_handler [msm]] *ERROR* 7.3.0.1: hangcheck detected gpu lockup rb 0! msm_dpu ae01000.display-controller: [drm:hangcheck_handler [msm]] *ERROR* 7.3.0.1: completed fence: 331235 msm_dpu ae01000.display-controller: [drm:hangcheck_handler [msm]] *ERROR* 7.3.0.1: submitted fence: 331236 adreno 3d0.gpu: [drm:a6xx_irq [msm]] *ERROR* gpu fault ring 0 fence 50de4 status 0085 rb /0699 ib1 / ib2 / msm_dpu ae01000.display-controller: [drm:recover_worker [msm]] *ERROR* 7.3.0.1: hangcheck recover! msm_dpu ae01000.display-controller: [drm:recover_worker [msm]] *ERROR* 7.3.0.1: offending task: deqp-vk (/usr/lib/vulkan-cts/deqp-vk) msm_dpu ae01000.display-controller: [drm:recover_worker [msm]] *ERROR* 7.3.0.1: hangcheck recover! leading to a VK_ERROR_DEVICE_LOST, but again unrelated to preempt support. So you can also add: Tested-by: Neil Armstrong # on SM8550-QRD Tested-by: Neil Armstrong # on SM8450-HDK Thanks, Neil
Re: [PATCH v1 1/1] drm/panel: sony-acx565akm: Use %*ph to print small buffer
Hi, On Wed, 11 Sep 2024 23:01:25 +0300, Andy Shevchenko wrote: > Use %*ph format to print small buffer as hex string. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: sony-acx565akm: Use %*ph to print small buffer https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/9550e2394fc09bf105a246221660da980c2dbd66 -- Neil
Re: [PATCH] drm/panel: khadas-ts050: make ts050[v2]_panel_data static
Hi, On Sun, 08 Sep 2024 21:35:30 +0800, Min-Hua Chen wrote: > make ts050_panel_data and ts050v2_panel_data static because they > are only used in drivers/gpu/drm/panel/panel-khadas-ts050.c, > and fix the following sparse warnings: > > drivers/gpu/drm/panel/panel-khadas-ts050.c:620:32: > sparse: warning: symbol 'ts050_panel_data' was not declared. Should it be > static? > drivers/gpu/drm/panel/panel-khadas-ts050.c:625:32: > sparse: warning: symbol 'ts050v2_panel_data' was not declared. Should it be > static? > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: khadas-ts050: make ts050[v2]_panel_data static https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/d5acba46ebf5a4fd9ea9ae5121dd381ce85e94ff -- Neil
Re: [PATCH] drm: panel: nt36523: use devm_mipi_dsi_* function to register and attach dsi
Hi, On Wed, 04 Sep 2024 22:29:07 +0800, Jianhua Lu wrote: > Switch to devm_mipi_dsi_* function, we don't need to detach and > unregister dsi manually any more. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm: panel: nt36523: use devm_mipi_dsi_* function to register and attach dsi https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/62f6bc14bbd12c13abe08b5a1bd8e55c843b776b -- Neil
Re: [PATCH v2 2/4] dt-bindings: display: panel-lvds: Add compatible for Jenson BL-JT60050-01A
Hi, On 28/08/2024 09:46, Frieder Schrempf wrote: From: Frieder Schrempf The Jenson BL-JT60050-01A is a 7" 1024x600 LVDS display. Signed-off-by: Frieder Schrempf Acked-by: Conor Dooley --- Changes for v2: * Add tag from Conor (thanks!) --- Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml index 155d8ffa8f6ef..5af2d69300751 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml @@ -50,6 +50,8 @@ properties: - hannstar,hsd101pww2 # Hydis Technologies 7" WXGA (800x1280) TFT LCD LVDS panel - hydis,hv070wx2-1e0 + # Jenson Display BL-JT60050-01A 7" WSVGA (1024x600) color TFT LCD LVDS panel + - jenson,bl-jt60050-01a - tbs,a711-panel - const: panel-lvds How do you want to deal with that, I can apply both patches 1 & 2 to drm-misc-next, is that ok ? Neil
Re: [PATCH v1 1/1] drm/panel: sony-acx565akm: Use %*ph to print small buffer
On 11/09/2024 22:01, Andy Shevchenko wrote: Use %*ph format to print small buffer as hex string. Signed-off-by: Andy Shevchenko --- drivers/gpu/drm/panel/panel-sony-acx565akm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c b/drivers/gpu/drm/panel/panel-sony-acx565akm.c index 217f03569494..d437f5c84f5f 100644 --- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c @@ -562,8 +562,7 @@ static int acx565akm_detect(struct acx565akm_panel *lcd) lcd->enabled ? "enabled" : "disabled ", status); acx565akm_read(lcd, MIPI_DCS_GET_DISPLAY_ID, lcd->display_id, 3); - dev_dbg(&lcd->spi->dev, "MIPI display ID: %02x%02x%02x\n", - lcd->display_id[0], lcd->display_id[1], lcd->display_id[2]); + dev_dbg(&lcd->spi->dev, "MIPI display ID: %3phN\n", lcd->display_id); switch (lcd->display_id[0]) { case 0x10: Reviewed-by: Neil Armstrong
Re: [PATCH] drm: panel: nt36523: use devm_mipi_dsi_* function to register and attach dsi
On 04/09/2024 16:29, Jianhua Lu wrote: Switch to devm_mipi_dsi_* function, we don't need to detach and unregister dsi manually any more. Signed-off-by: Jianhua Lu --- drivers/gpu/drm/panel/panel-novatek-nt36523.c | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index 18bd2ee71201..04f1d2676c78 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -1095,18 +1095,6 @@ static int nt36523_unprepare(struct drm_panel *panel) static void nt36523_remove(struct mipi_dsi_device *dsi) { struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi); - int ret; - - ret = mipi_dsi_detach(pinfo->dsi[0]); - if (ret < 0) - dev_err(&dsi->dev, "failed to detach from DSI0 host: %d\n", ret); - - if (pinfo->desc->is_dual_dsi) { - ret = mipi_dsi_detach(pinfo->dsi[1]); - if (ret < 0) - dev_err(&pinfo->dsi[1]->dev, "failed to detach from DSI1 host: %d\n", ret); - mipi_dsi_device_unregister(pinfo->dsi[1]); - } drm_panel_remove(&pinfo->panel); } @@ -1251,7 +1239,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) if (!dsi1_host) return dev_err_probe(dev, -EPROBE_DEFER, "cannot get secondary DSI host\n"); - pinfo->dsi[1] = mipi_dsi_device_register_full(dsi1_host, info); + pinfo->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi1_host, info); if (IS_ERR(pinfo->dsi[1])) { dev_err(dev, "cannot get secondary DSI device\n"); return PTR_ERR(pinfo->dsi[1]); @@ -1288,7 +1276,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) pinfo->dsi[i]->format = pinfo->desc->format; pinfo->dsi[i]->mode_flags = pinfo->desc->mode_flags; - ret = mipi_dsi_attach(pinfo->dsi[i]); + ret = devm_mipi_dsi_attach(dev, pinfo->dsi[i]); if (ret < 0) return dev_err_probe(dev, ret, "cannot attach to DSI%d host.\n", i); } Reviewed-by: Neil Armstrong
Re: [PATCH] drm/panel: raydium-rm69380: transition to mipi_dsi wrapped functions
Hi, On 07/09/2024 16:01, Tejas Vipin wrote: Changes the raydium-rm69380 panel to use multi style functions for improved error handling. Signed-off-by: Tejas Vipin --- drivers/gpu/drm/panel/panel-raydium-rm69380.c | 95 ++- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-raydium-rm69380.c b/drivers/gpu/drm/panel/panel-raydium-rm69380.c index 4dca6802faef..bdab844dab55 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm69380.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm69380.c @@ -46,108 +46,73 @@ static void rm69380_reset(struct rm69380_panel *ctx) static int rm69380_on(struct rm69380_panel *ctx) { struct mipi_dsi_device *dsi = ctx->dsi[0]; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; if (ctx->dsi[1]) ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd4); - mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd0); - mipi_dsi_dcs_write_seq(dsi, 0x48, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x26); - mipi_dsi_dcs_write_seq(dsi, 0x75, 0x3f); - mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1a); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); - mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x08); - - ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (ret < 0) { - dev_err(dev, "Failed to set tear on: %d\n", ret); - return ret; - } - - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to exit sleep mode: %d\n", ret); - return ret; - } - msleep(20); - - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display on: %d\n", ret); - return ret; - } - msleep(36); - - return 0; + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd4); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x80); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x26); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x3f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x1a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc2, 0x08); + + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 36); + + return dsi_ctx.accum_err; } -static int rm69380_off(struct rm69380_panel *ctx) +static void rm69380_off(struct rm69380_panel *ctx) { struct mipi_dsi_device *dsi = ctx->dsi[0]; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; if (ctx->dsi[1]) ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - return ret; - } - msleep(35); - - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - return ret; - } - msleep(20); - - return 0; + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 35); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); } static int rm69380_prepare(struct drm_panel *panel) { struct rm69380_panel *ctx = to_rm69380_panel(panel); - struct device *dev = &ctx->dsi[0]->dev; int ret; ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); - return ret; - } + if (ret < 0) + return ret; rm69380_reset(ctx); ret = rm69380_on(ctx); if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - return ret; } - return 0; + return ret; } static int rm69380_unprepare(struct drm_panel *panel) { struct rm69
Re: [PATCH 3/5] drm/fsl-dcu: constify regmap_config
On 08/09/2024 16:21, Krzysztof Kozlowski wrote: Mark local static 'struct regmap_config' as const for safer and more obvious code. Signed-off-by: Krzysztof Kozlowski --- drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_tcon.c b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c index 9eb5abaf7d66..49bbd00c77ae 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_tcon.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c @@ -29,7 +29,7 @@ void fsl_tcon_bypass_enable(struct fsl_tcon *tcon) FSL_TCON_CTRL1_TCON_BYPASS); } -static struct regmap_config fsl_tcon_regmap_config = { +static const struct regmap_config fsl_tcon_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, Reviewed-by: Neil Armstrong
Re: [PATCH v2] drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock
Hi, On Sat, 07 Sep 2024 14:54:33 +0900, Dominique Martinet wrote: > This allows the hdmi driver to pick e.g. 64.8MHz instead of 65Mhz when we > cannot output the exact frequency, enabling the imx8mp HDMI output to > support more modes > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/0d4b950e03fb1c1873c51916fd01ebafbbc48222 -- Neil
Re: [PATCH 1/6] drm/bridge: imx8mp-hdmi-tx: Switch to SYSTEM_SLEEP_PM_OPS()
Hi, On Wed, 26 Jun 2024 20:06:59 -0300, Fabio Estevam wrote: > Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() > alternative. > > The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() > allows the compiler to evaluate if the runtime suspend/resume() functions > are used at build time or are simply dead code. > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/6] drm/bridge: imx8mp-hdmi-tx: Switch to SYSTEM_SLEEP_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/017703370638c07cd6affe661118f697ee113881 [2/6] drm/bridge: imx8qm-ldb: Switch to RUNTIME_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/02b16c5236e1823047f001b9496e59458c9a7482 [3/6] drm/bridge: imx8qxp-pixel-combiner: Switch to RUNTIME_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/be227772f7e957f98c3c828459b1221cae84de2e [4/6] drm/bridge: samsung-dsim: Switch to RUNTIME_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/5de3c40a1dc503bf915bbc048aa8f5efb369650c [5/6] drm/bridge: dw-hdmi-cec: Switch to SYSTEM_SLEEP_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/46fe7763c65674be67828cdbe3a72d6d9b8f8aa7 [6/6] drm/bridge: imx8qxp-ldb: Switch to RUNTIME_PM_OPS() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/8fdd9cb4f8c03a943090ef55ffb552e05c6defc6 -- Neil
Re: [PATCH v3 0/3] Improve tc358767 debugging
Hi, On Wed, 04 Sep 2024 14:05:42 +0200, Alexander Stein wrote: > this small series improves debugging the tc358767 driver by using > dev_err_probe for additional information (patch 1) and print IRQ > debug output only if hotplug status actually changed. > > Changes inv 3: > * Collected Robert's and Dmitry' R-b > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/3] drm/bridge: tc358767: Use dev_err_probe https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/446967304b5671f9b9e5b1b7a620106b4fd6b1f2 [2/3] drm/bridge: tc358767: Only print GPIO debug output if they actually occur https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/31735a97cbd81bc3d858b44a56c8e8dc134a0a3c [3/3] drm/bridge: tc358767: Support write-only registers https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/0d317e820d40963a63eb61732784f23ca0e82d23 -- Neil
Re: [PATCH v2 05/10] drm: bridge: dw_hdmi: Fold poweron and setup functions
On 08/09/2024 15:28, Jonas Karlman wrote: Fold the poweron and setup functions into one function and use the adjusted_mode directly from the new crtc_state to remove the need of storing previous_mode. Signed-off-by: Jonas Karlman --- v2: No change --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 21 - 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 87fb6fd5cffd..1eefa633ff78 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2236,9 +2236,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) HDMI_IH_MUTE_FC_STAT2); } -static int dw_hdmi_setup(struct dw_hdmi *hdmi, -const struct drm_connector *connector, -const struct drm_display_mode *mode) +static int dw_hdmi_poweron(struct dw_hdmi *hdmi, + const struct drm_connector *connector, + const struct drm_display_mode *mode) { const struct drm_display_info *display = &connector->display_info; int ret; @@ -2378,15 +2378,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); } -static void dw_hdmi_poweron(struct dw_hdmi *hdmi) -{ - /* -* The curr_conn field is guaranteed to be valid here, as this function -* is only be called when !hdmi->disabled. -*/ - dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode); -} - static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) { if (hdmi->phy.enabled) { @@ -2936,15 +2927,19 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, { struct dw_hdmi *hdmi = bridge->driver_private; struct drm_atomic_state *state = old_state->base.state; + const struct drm_display_mode *mode; struct drm_connector *connector; + struct drm_crtc *crtc; connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + crtc = drm_atomic_get_new_connector_state(state, connector)->crtc; + mode = &drm_atomic_get_new_crtc_state(state, crtc)->adjusted_mode; mutex_lock(&hdmi->mutex); hdmi->disabled = false; hdmi->curr_conn = connector; - dw_hdmi_poweron(hdmi); + dw_hdmi_poweron(hdmi, connector, mode); dw_hdmi_update_phy_mask(hdmi); handle_plugged_change(hdmi, true); mutex_unlock(&hdmi->mutex); Reviewed-by: Neil Armstrong
Re: [PATCH v2 03/10] drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable
On 08/09/2024 15:28, Jonas Karlman wrote: Change to only call poweron/poweroff from atomic_enable/atomic_disable ops instead of trying to be clever by keeping a bridge_is_on state and poweron/off in the hotplug irq handler. The bridge is already enabled/disabled depending on connection state with the call to drm_helper_hpd_irq_event() in hotplug irq handler. A benefit of this is that drm mode_config mutex is always held at poweron/off, something that may reduce the need for our own mutex. Signed-off-by: Jonas Karlman --- v2: Update commit message --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 33 ++- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 055fc9848df4..5b67640b1d0a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -169,7 +169,6 @@ struct dw_hdmi { enum drm_connector_force force; /* mutex-protected force state */ struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */ bool disabled; /* DRM has disabled our bridge */ - bool bridge_is_on; /* indicates the bridge is on */ bool rxsense; /* rxsense state */ u8 phy_mask;/* desired phy int mask settings */ u8 mc_clkdis; /* clock disable register */ @@ -2382,8 +2381,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) static void dw_hdmi_poweron(struct dw_hdmi *hdmi) { - hdmi->bridge_is_on = true; - /* * The curr_conn field is guaranteed to be valid here, as this function * is only be called when !hdmi->disabled. @@ -2397,30 +2394,6 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) hdmi->phy.ops->disable(hdmi, hdmi->phy.data); hdmi->phy.enabled = false; } - - hdmi->bridge_is_on = false; -} - -static void dw_hdmi_update_power(struct dw_hdmi *hdmi) -{ - int force = hdmi->force; - - if (hdmi->disabled) { - force = DRM_FORCE_OFF; - } else if (force == DRM_FORCE_UNSPECIFIED) { - if (hdmi->rxsense) - force = DRM_FORCE_ON; - else - force = DRM_FORCE_OFF; - } - - if (force == DRM_FORCE_OFF) { - if (hdmi->bridge_is_on) - dw_hdmi_poweroff(hdmi); - } else { - if (!hdmi->bridge_is_on) - dw_hdmi_poweron(hdmi); - } } /* @@ -2545,7 +2518,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) mutex_lock(&hdmi->mutex); hdmi->force = connector->force; - dw_hdmi_update_power(hdmi); dw_hdmi_update_phy_mask(hdmi); mutex_unlock(&hdmi->mutex); } @@ -2954,7 +2926,7 @@ static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, mutex_lock(&hdmi->mutex); hdmi->disabled = true; hdmi->curr_conn = NULL; - dw_hdmi_update_power(hdmi); + dw_hdmi_poweroff(hdmi); dw_hdmi_update_phy_mask(hdmi); handle_plugged_change(hdmi, false); mutex_unlock(&hdmi->mutex); @@ -2973,7 +2945,7 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, mutex_lock(&hdmi->mutex); hdmi->disabled = false; hdmi->curr_conn = connector; - dw_hdmi_update_power(hdmi); + dw_hdmi_poweron(hdmi); dw_hdmi_update_phy_mask(hdmi); handle_plugged_change(hdmi, true); mutex_unlock(&hdmi->mutex); @@ -3072,7 +3044,6 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) if (hpd) hdmi->rxsense = true; - dw_hdmi_update_power(hdmi); dw_hdmi_update_phy_mask(hdmi); } mutex_unlock(&hdmi->mutex); Reviewed-by: Neil Armstrong
Re: [PATCH v2 04/10] drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode
On 08/09/2024 15:28, Jonas Karlman wrote: Use the passed mode instead of mixing use of passed mode and the stored previous_mode. The passed mode is currenly always the previous_mode. Also fix a small typo and add a variable to help shorten a code line. Signed-off-by: Jonas Karlman --- v2: Update commit message, s/type/typo/ --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 5b67640b1d0a..87fb6fd5cffd 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2240,6 +2240,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, const struct drm_connector *connector, const struct drm_display_mode *mode) { + const struct drm_display_info *display = &connector->display_info; int ret; hdmi_disable_overflow_interrupts(hdmi); @@ -2285,12 +2286,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, hdmi->hdmi_data.video_mode.mdataenablepolarity = true; /* HDMI Initialization Step B.1 */ - hdmi_av_composer(hdmi, &connector->display_info, mode); + hdmi_av_composer(hdmi, display, mode); - /* HDMI Initializateion Step B.2 */ - ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, - &connector->display_info, - &hdmi->previous_mode); + /* HDMI Initialization Step B.2 */ + ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, display, mode); if (ret) return ret; hdmi->phy.enabled = true; Reviewed-by: Neil Armstrong
Re: [PATCH v2 06/10] drm: bridge: dw_hdmi: Remove previous_mode and mode_set
On 08/09/2024 15:28, Jonas Karlman wrote: With the use of adjusted_mode directly from the crtc_state there is no longer a need to store a copy in previous_mode, remove it and the now unneeded mode_set ops. Signed-off-by: Jonas Karlman --- v2: No change --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 19 +-- 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 1eefa633ff78..6a94376a3da3 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -154,8 +154,6 @@ struct dw_hdmi { bool enabled; } phy; - struct drm_display_mode previous_mode; - struct i2c_adapter *ddc; void __iomem *regs; bool sink_is_hdmi; @@ -165,7 +163,7 @@ struct dw_hdmi { struct pinctrl_state *default_state; struct pinctrl_state *unwedge_state; - struct mutex mutex; /* for state below and previous_mode */ + struct mutex mutex; /* for state below */ enum drm_connector_force force; /* mutex-protected force state */ struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */ bool disabled; /* DRM has disabled our bridge */ @@ -2894,20 +2892,6 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, return mode_status; } -static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *orig_mode, - const struct drm_display_mode *mode) -{ - struct dw_hdmi *hdmi = bridge->driver_private; - - mutex_lock(&hdmi->mutex); - - /* Store the display mode for plugin/DKMS poweron events */ - drm_mode_copy(&hdmi->previous_mode, mode); - - mutex_unlock(&hdmi->mutex); -} - static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_state) { @@ -2971,7 +2955,6 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts, .atomic_enable = dw_hdmi_bridge_atomic_enable, .atomic_disable = dw_hdmi_bridge_atomic_disable, - .mode_set = dw_hdmi_bridge_mode_set, .mode_valid = dw_hdmi_bridge_mode_valid, .detect = dw_hdmi_bridge_detect, .edid_read = dw_hdmi_bridge_edid_read, Reviewed-by: Neil Armstrong
Re: [PATCH v2 09/10] drm: bridge: dw_hdmi: Update EDID during hotplug processing
On 08/09/2024 15:28, Jonas Karlman wrote: Update successfully read EDID during hotplug processing to ensure the connector diplay_info is always up-to-date. Signed-off-by: Jonas Karlman --- v2: No change --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index c19307120909..7bd9f895f03f 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2457,6 +2457,18 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) status = dw_hdmi_detect(hdmi); + /* Update EDID during hotplug processing (force=false) */ + if (status == connector_status_connected && !force) { + const struct drm_edid *drm_edid; + + drm_edid = dw_hdmi_edid_read(hdmi, connector); + if (drm_edid) + drm_edid_connector_update(connector, drm_edid); + cec_notifier_set_phys_addr(hdmi->cec_notifier, + connector->display_info.source_physical_address); + drm_edid_free(drm_edid); + } + if (status == connector_status_disconnected) cec_notifier_phys_addr_invalidate(hdmi->cec_notifier); I wonder why we should read edid at each dw_hdmi_connector_detect() call, AFAIK it should only be when we have HPD pulses Neil
Re: [PATCH 1/6] drm/bridge: imx8mp-hdmi-tx: Switch to SYSTEM_SLEEP_PM_OPS()
On 27/06/2024 01:06, Fabio Estevam wrote: From: Fabio Estevam Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 13bc570c5473..4a3a8a3ce250 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -111,12 +111,12 @@ static void imx8mp_dw_hdmi_remove(struct platform_device *pdev) dw_hdmi_remove(hdmi->dw_hdmi); } -static int __maybe_unused imx8mp_dw_hdmi_pm_suspend(struct device *dev) +static int imx8mp_dw_hdmi_pm_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) +static int imx8mp_dw_hdmi_pm_resume(struct device *dev) { struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev); @@ -126,8 +126,7 @@ static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) } static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, - imx8mp_dw_hdmi_pm_resume) + SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, imx8mp_dw_hdmi_pm_resume) }; static const struct of_device_id imx8mp_dw_hdmi_of_table[] = { @@ -142,7 +141,7 @@ static struct platform_driver imx8mp_dw_hdmi_platform_driver = { .driver = { .name = "imx8mp-dw-hdmi-tx", .of_match_table = imx8mp_dw_hdmi_of_table, - .pm = &imx8mp_dw_hdmi_pm_ops, + .pm = pm_ptr(&imx8mp_dw_hdmi_pm_ops), }, }; Reviewed-by: Neil Armstrong
Re: [PATCH] drm/bridge: nwl-dsi: Use vsync/hsync polarity from display mode
On 14/08/2024 12:37, Esben Haabendal wrote: Using the correct bit helps. The documentation specifies bit 0 in both registers to be controlling polarity of dpi_vsync_input and dpi_hsync_input polarity. Bit 1 is reserved, and should therefore not be set. Tested with panel that requires active high vsync and hsync. Signed-off-by: Esben Haabendal --- drivers/gpu/drm/bridge/nwl-dsi.c | 8 drivers/gpu/drm/bridge/nwl-dsi.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 8d54091ec66e..5f05647a3bea 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -289,13 +289,13 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi) nwl_dsi_write(dsi, NWL_DSI_INTERFACE_COLOR_CODING, NWL_DSI_DPI_24_BIT); nwl_dsi_write(dsi, NWL_DSI_PIXEL_FORMAT, color_format); - /* -* Adjusting input polarity based on the video mode results in -* a black screen so always pick active low: -*/ nwl_dsi_write(dsi, NWL_DSI_VSYNC_POLARITY, + dsi->mode.flags & DRM_MODE_FLAG_PVSYNC ? + NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH : NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW); nwl_dsi_write(dsi, NWL_DSI_HSYNC_POLARITY, + dsi->mode.flags & DRM_MODE_FLAG_PHSYNC ? + NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH : NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW); burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) && diff --git a/drivers/gpu/drm/bridge/nwl-dsi.h b/drivers/gpu/drm/bridge/nwl-dsi.h index a247a8a11c7c..61e7d65cb1eb 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.h +++ b/drivers/gpu/drm/bridge/nwl-dsi.h @@ -30,11 +30,11 @@ #define NWL_DSI_PIXEL_FORMAT 0x20c #define NWL_DSI_VSYNC_POLARITY0x210 #define NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW 0 -#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(1) +#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(0) #define NWL_DSI_HSYNC_POLARITY 0x214 #define NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW 0 -#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(1) +#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(0) #define NWL_DSI_VIDEO_MODE 0x218 #define NWL_DSI_HFP 0x21c --- base-commit: 7c626ce4bae1ac14f60076d00eafe71af30450ba change-id: 20240814-nwl-dsi-sync-polarity-ddc58435a4c4 Best regards, Reviewed-by: Neil Armstrong
Re: [PATCH 1/2] drm/bridge: dw-hdmi: Move vmalloc PCM buffer management into the driver
On 07/08/2024 17:27, Takashi Iwai wrote: The dw-hdmi drm bridge driver is the only one who still uses the ALSA vmalloc helper API functions. A previous attempt to change the way of buffer management wasn't taken for this legacy stuff, as we had little chance for test and some risk of major breaking. Instead, this patch moves the vmalloc buffer stuff into the dw-hdmi driver code itself, so that we can drop them from ALSA core code afterwards. There should be no functional changes. Link: https://lore.kernel.org/20191210154536.29819-1-ti...@suse.de Signed-off-by: Takashi Iwai --- .../drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 30 --- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c index 67b8d17a722a..221e9a4edb40 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -388,15 +389,36 @@ static int dw_hdmi_close(struct snd_pcm_substream *substream) static int dw_hdmi_hw_free(struct snd_pcm_substream *substream) { - return snd_pcm_lib_free_vmalloc_buffer(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + vfree(runtime->dma_area); + runtime->dma_area = NULL; + return 0; } static int dw_hdmi_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { + struct snd_pcm_runtime *runtime = substream->runtime; + size_t size = params_buffer_bytes(params); + /* Allocate the PCM runtime buffer, which is exposed to userspace. */ - return snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(params)); + if (runtime->dma_area) { + if (runtime->dma_bytes >= size) + return 0; /* already large enough */ + vfree(runtime->dma_area); + } + runtime->dma_area = vzalloc(size); + if (!runtime->dma_area) + return -ENOMEM; + runtime->dma_bytes = size; + return 1; +} + +static struct page *dw_hdmi_get_page(struct snd_pcm_substream *substream, +unsigned long offset) +{ + return vmalloc_to_page(substream->runtime->dma_area + offset); } static int dw_hdmi_prepare(struct snd_pcm_substream *substream) @@ -515,7 +537,7 @@ static const struct snd_pcm_ops snd_dw_hdmi_ops = { .prepare = dw_hdmi_prepare, .trigger = dw_hdmi_trigger, .pointer = dw_hdmi_pointer, - .page = snd_pcm_lib_get_vmalloc_page, + .page = dw_hdmi_get_page, }; static int snd_dw_hdmi_probe(struct platform_device *pdev) Reviewed-by: Neil Armstrong
Re: [PATCH 6/6] drm/bridge: imx8qxp-ldb: Switch to RUNTIME_PM_OPS()
On 27/06/2024 01:07, Fabio Estevam wrote: From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index 7984da9c0a35..b33011f397f0 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -678,12 +678,12 @@ static void imx8qxp_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_ldb_runtime_suspend(struct device *dev) +static int imx8qxp_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) +static int imx8qxp_ldb_runtime_resume(struct device *dev) { struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qxp_ldb->base; @@ -695,8 +695,7 @@ static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, - imx8qxp_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, imx8qxp_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_ldb_dt_ids[] = { @@ -709,7 +708,7 @@ static struct platform_driver imx8qxp_ldb_driver = { .probe = imx8qxp_ldb_probe, .remove_new = imx8qxp_ldb_remove, .driver = { - .pm = &imx8qxp_ldb_pm_ops, + .pm = pm_ptr(&imx8qxp_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_ldb_dt_ids, }, Reviewed-by: Neil Armstrong
Re: [PATCH 5/6] drm/bridge: dw-hdmi-cec: Switch to SYSTEM_SLEEP_PM_OPS()
On 27/06/2024 01:07, Fabio Estevam wrote: From: Fabio Estevam Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c index 673661160e54..d4614de1ae1e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c @@ -312,7 +312,7 @@ static void dw_hdmi_cec_remove(struct platform_device *pdev) cec_unregister_adapter(cec->adap); } -static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) +static int dw_hdmi_cec_resume(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -328,7 +328,7 @@ static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) return 0; } -static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) +static int dw_hdmi_cec_suspend(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -341,7 +341,7 @@ static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) } static const struct dev_pm_ops dw_hdmi_cec_pm = { - SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) + SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) }; static struct platform_driver dw_hdmi_cec_driver = { @@ -349,7 +349,7 @@ static struct platform_driver dw_hdmi_cec_driver = { .remove_new = dw_hdmi_cec_remove, .driver = { .name = "dw-hdmi-cec", - .pm = &dw_hdmi_cec_pm, + .pm = pm_ptr(&dw_hdmi_cec_pm), }, }; module_platform_driver(dw_hdmi_cec_driver); Reviewed-by: Neil Armstrong
Re: [PATCH 4/6] drm/bridge: samsung-dsim: Switch to RUNTIME_PM_OPS()
On 27/06/2024 01:07, Fabio Estevam wrote: From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/samsung-dsim.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index e7e53a9e42af..73ccf21ae446 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -2043,7 +2043,7 @@ void samsung_dsim_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(samsung_dsim_remove); -static int __maybe_unused samsung_dsim_suspend(struct device *dev) +static int samsung_dsim_suspend(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2073,7 +2073,7 @@ static int __maybe_unused samsung_dsim_suspend(struct device *dev) return 0; } -static int __maybe_unused samsung_dsim_resume(struct device *dev) +static int samsung_dsim_resume(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2108,7 +2108,7 @@ static int __maybe_unused samsung_dsim_resume(struct device *dev) } const struct dev_pm_ops samsung_dsim_pm_ops = { - SET_RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) + RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; @@ -2142,7 +2142,7 @@ static struct platform_driver samsung_dsim_driver = { .remove_new = samsung_dsim_remove, .driver = { .name = "samsung-dsim", - .pm = &samsung_dsim_pm_ops, + .pm = pm_ptr(&samsung_dsim_pm_ops), .of_match_table = samsung_dsim_of_match, }, }; Reviewed-by: Neil Armstrong
Re: [PATCH 3/6] drm/bridge: imx8qxp-pixel-combiner: Switch to RUNTIME_PM_OPS()
On 27/06/2024 01:07, Fabio Estevam wrote: From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index e6dbbdc87ce2..ce43e4069e21 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -371,7 +371,7 @@ static void imx8qxp_pc_bridge_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) +static int imx8qxp_pc_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -393,7 +393,7 @@ static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) return ret; } -static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) +static int imx8qxp_pc_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -415,8 +415,7 @@ static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_pc_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, - imx8qxp_pc_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, imx8qxp_pc_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_pc_dt_ids[] = { @@ -430,7 +429,7 @@ static struct platform_driver imx8qxp_pc_bridge_driver = { .probe = imx8qxp_pc_bridge_probe, .remove_new = imx8qxp_pc_bridge_remove, .driver = { - .pm = &imx8qxp_pc_pm_ops, + .pm = pm_ptr(&imx8qxp_pc_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_pc_dt_ids, }, Reviewed-by: Neil Armstrong
Re: [PATCH 2/6] drm/bridge: imx8qm-ldb: Switch to RUNTIME_PM_OPS()
On 27/06/2024 01:07, Fabio Estevam wrote: From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qm-ldb.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index 21471a9a28b2..c879e37f5811 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -542,12 +542,12 @@ static void imx8qm_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qm_ldb_runtime_suspend(struct device *dev) +static int imx8qm_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) +static int imx8qm_ldb_runtime_resume(struct device *dev) { struct imx8qm_ldb *imx8qm_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qm_ldb->base; @@ -559,8 +559,7 @@ static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qm_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, - imx8qm_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, imx8qm_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qm_ldb_dt_ids[] = { @@ -573,7 +572,7 @@ static struct platform_driver imx8qm_ldb_driver = { .probe = imx8qm_ldb_probe, .remove_new = imx8qm_ldb_remove, .driver = { - .pm = &imx8qm_ldb_pm_ops, + .pm = pm_ptr(&imx8qm_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qm_ldb_dt_ids, }, Reviewed-by: Neil Armstrong
Re: [PATCH -next 1/3] drm/bridge: it6505: Enable module autoloading
On 02/09/2024 13:33, Liao Chen wrote: Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based on the alias from of_device_id table. Signed-off-by: Liao Chen --- drivers/gpu/drm/bridge/ite-it6505.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 1e1c06fdf206..eef5ad449c16 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -3498,6 +3498,7 @@ static const struct of_device_id it6505_of_match[] = { { .compatible = "ite,it6505" }, { } }; +MODULE_DEVICE_TABLE(of, it6505_of_match); static struct i2c_driver it6505_i2c_driver = { .driver = { Reviewed-by: Neil Armstrong
Re: [PATCH v2] drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock
On 07/09/2024 07:54, Dominique Martinet wrote: From: Dominique Martinet This allows the hdmi driver to pick e.g. 64.8MHz instead of 65Mhz when we cannot output the exact frequency, enabling the imx8mp HDMI output to support more modes Tested-by: Adam Ford #imx8mp-beacon Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Dominique Martinet --- Changes in v2: - Improve comment about the tolerance - Link to v1: https://lore.kernel.org/r/20240904083103.1257480-1-dominique.marti...@atmark-techno.com --- drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 13bc570c5473..200d65184159 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -23,6 +23,7 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_mode *mode) { struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data; + long round_rate; if (mode->clock < 13500) return MODE_CLOCK_LOW; @@ -30,8 +31,14 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, if (mode->clock > 297000) return MODE_CLOCK_HIGH; - if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) != - mode->clock * 1000) + round_rate = clk_round_rate(hdmi->pixclk, mode->clock * 1000); + /* imx8mp's pixel clock generator (fsl-samsung-hdmi) cannot generate +* all possible frequencies, so allow some tolerance to support more +* modes. +* Allow 0.5% difference allowed in various standards (VESA, CEA861) +* 0.5% = 5/1000 tolerance (mode->clock is 1/1000) +*/ + if (abs(round_rate - mode->clock * 1000) > mode->clock * 5) return MODE_CLOCK_RANGE; /* We don't support double-clocked and Interlaced modes */ --- base-commit: 67784a74e258a467225f0e68335df77acd67b7ab change-id: 20240907-hdmi-tolerance-4d83074a4517 Best regards, Reviewed-by: Neil Armstrong
Re: [PATCH 5/5] drm/bridge: ti-dlpc3433: constify regmap_config
On 08/09/2024 16:21, Krzysztof Kozlowski wrote: Mark local static 'struct regmap_config' as const for safer and more obvious code. Signed-off-by: Krzysztof Kozlowski --- drivers/gpu/drm/bridge/ti-dlpc3433.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-dlpc3433.c b/drivers/gpu/drm/bridge/ti-dlpc3433.c index 6b559e071301..a0a1b5dd794e 100644 --- a/drivers/gpu/drm/bridge/ti-dlpc3433.c +++ b/drivers/gpu/drm/bridge/ti-dlpc3433.c @@ -94,7 +94,7 @@ static const struct regmap_access_table dlpc_volatile_table = { .n_yes_ranges = ARRAY_SIZE(dlpc_volatile_ranges), }; -static struct regmap_config dlpc_regmap_config = { +static const struct regmap_config dlpc_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = WR_DSI_PORT_EN, Reviewed-by: Neil Armstrong
Re: [PATCH] drm/panel: himax-hx83112a: transition to mipi_dsi wrapped functions
On 10/09/2024 23:19, Doug Anderson wrote: Hi, On Sat, Sep 7, 2024 at 1:32 AM Tejas Vipin wrote: On 9/7/24 3:53 AM, Jessica Zhang wrote: On 9/6/2024 3:14 PM, Jessica Zhang wrote: On 9/4/2024 7:15 AM, Tejas Vipin wrote: Changes the himax-hx83112a panel to use multi style functions for improved error handling. Signed-off-by: Tejas Vipin Reviewed-by: Jessica Zhang Hi Tejas, Just a heads up, it seems that this might be a duplicate of this change [1]? Thanks, Jessica Zhang [1] https://patchwork.freedesktop.org/patch/612367/?series=138155&rev=1 Ah, thanks for letting me know. I hadn't realized someone else had started working on this too. However, I would argue that my patch [2] is a better candidate for merging because of the following reasons: 1) Removes unnecessary error printing: The mipi_dsi_*_multi() functions all have inbuilt error printing which makes printing errors after hx83112a_on unnecessary as is addressed in [2] like so: - ret = hx83112a_on(ctx); + ret = hx83112a_on(ctx->dsi); if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - return ret; } [2] also removes the unnecessary dev_err after regulator_bulk_enable as was addressed in [3] like so: ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); + if (ret < 0) return ret; - } 2) Better formatting The mipi_dsi_dcs_write_seq_multi statements in [1] aren't formatted quite right according to what has been done so far. They are written as such in [1]: + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTP1, 0x02, 0x00, 0xa8, 0x01, 0xa8, 0x0d, 0xa4, 0x0e); Where they should be written as such in [2]: + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTP1, + 0x02, 0x00, 0xa8, 0x01, 0xa8, 0x0d, 0xa4, 0x0e); All in all, the module generated using my patch ends up being a teensy bit smaller (1% smaller). But if chronology is what is important, then it would at least be nice to see the above changes as part of Abhishek's patch too. And I'll be sure to look at the mail in the drm inbox now onwards :p [1] https://patchwork.freedesktop.org/patch/612367/?series=138155&rev=1 [2] https://lore.kernel.org/all/20240904141521.554451-1-tejasvipi...@gmail.com/ [3] https://lore.kernel.org/all/CAD=FV=xrzkl_ppjukdk61fqkwhhiqcjlfmvbs7wso4suux2...@mail.gmail.com/ I would tend to agree that Tejas's patch looks slightly better, but Abhishek's patch appears to have been posted first. Neil: any idea what to do here? Maybe a Co-Developed-by or something? ...or we could land Abhishek and Tejas could post a followup for the extra cleanup? Yeah usually I take the first one when they are equal, but indeed Tejas cleanup up a little further and better aligned the parameters so I think Tejas's one is a better looking version. In this case we should apply Teja's one, nothing personal Abhishek! Abhishek: are you planning to post more _multi cleanups? If so, please make sure to CC Tejas (who has been posting a bunch of them) and perhaps me since I've been helping to review them a bit. -Doug
Re: [PATCH v2 02/10] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt
On 08/09/2024 15:28, Jonas Karlman wrote: drm_helper_hpd_irq_event() and drm_bridge_hpd_notify() may incorrectly be called with a connected status when HPD is high and RX sense is changed. This typically happen when the HDMI cable is unplugged, shortly before the HPD is changed to low. Fix this by only notify connected status on the HPD interrupt when HPD is going high, not on the RX sense interrupt when RX sense is changed. Fixes: da09daf88108 ("drm: bridge: dw_hdmi: only trigger hotplug event on link change") Signed-off-by: Jonas Karlman --- v2: New patch --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 9e7f86a0bf5c..055fc9848df4 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3123,7 +3123,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) mutex_unlock(&hdmi->cec_notifier_mutex); } - if (phy_stat & HDMI_PHY_HPD) + if ((intr_stat & HDMI_IH_PHY_STAT0_HPD) && + (phy_stat & HDMI_PHY_HPD)) status = connector_status_connected; if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE))) Perhaps this should be also checked for the other lines checking HDMI_PHY_HPD ? Neil
Re: [PATCH v2 01/10] drm: bridge: dw_hdmi: Disable scrambler feature when not supported
On 08/09/2024 15:28, Jonas Karlman wrote: The scrambler feature can be left enabled when hotplugging from a sink and mode that require scrambling to a sink that does not support SCDC or scrambling. Typically a blank screen or 'no signal' message can be observed after using a HDMI 2.0 4K@60Hz mode and then hotplugging to a sink that only support HDMI 1.4. Fix this by disabling the scrambler feature when SCDC is not supported. Fixes: 264fce6cc2c1 ("drm/bridge: dw-hdmi: Add SCDC and TMDS Scrambling support") Reported-by: Christopher Obbard Signed-off-by: Jonas Karlman --- v2: New patch --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 0031f3c54882..9e7f86a0bf5c 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2117,6 +2117,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, HDMI_MC_SWRSTZ); drm_scdc_set_scrambling(hdmi->curr_conn, 0); } + } else if (hdmi->version >= 0x200a) { + hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL); } /* Set up horizontal active pixel width */ Reviewed-by: Neil Armstrong
Re: [PATCH] drm/panel: khadas-ts050: make ts050[v2]_panel_data static
On 08/09/2024 15:35, Min-Hua Chen wrote: make ts050_panel_data and ts050v2_panel_data static because they are only used in drivers/gpu/drm/panel/panel-khadas-ts050.c, and fix the following sparse warnings: drivers/gpu/drm/panel/panel-khadas-ts050.c:620:32: sparse: warning: symbol 'ts050_panel_data' was not declared. Should it be static? drivers/gpu/drm/panel/panel-khadas-ts050.c:625:32: sparse: warning: symbol 'ts050v2_panel_data' was not declared. Should it be static? No functional changes intended. Signed-off-by: Min-Hua Chen --- drivers/gpu/drm/panel/panel-khadas-ts050.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c index 14932cb3defc..0e5e8e57bd1e 100644 --- a/drivers/gpu/drm/panel/panel-khadas-ts050.c +++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c @@ -617,12 +617,12 @@ static const struct khadas_ts050_panel_cmd ts050_init_code[] = { {0xd4, {0x04}, 0x01}, /* RGBMIPICTRL: VSYNC front porch = 4 */ }; -struct khadas_ts050_panel_data ts050_panel_data = { +static struct khadas_ts050_panel_data ts050_panel_data = { .init_code = (struct khadas_ts050_panel_cmd *)ts050_init_code, .len = ARRAY_SIZE(ts050_init_code) }; -struct khadas_ts050_panel_data ts050v2_panel_data = { +static struct khadas_ts050_panel_data ts050v2_panel_data = { .init_code = (struct khadas_ts050_panel_cmd *)ts050v2_init_code, .len = ARRAY_SIZE(ts050v2_init_code) }; Reviewed-by: Neil Armstrong
Re: [PATCH 2/5] drm/meson: constify regmap_config
On 08/09/2024 16:21, Krzysztof Kozlowski wrote: Mark local static 'struct regmap_config' as const for safer and more obvious code. Signed-off-by: Krzysztof Kozlowski --- drivers/gpu/drm/meson/meson_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 4bd0baa2a4f5..6c8677d1f562 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -126,7 +126,7 @@ static bool meson_vpu_has_available_connectors(struct device *dev) return false; } -static struct regmap_config meson_regmap_config = { +static const struct regmap_config meson_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, Reviewed-by: Neil Armstrong
Re: [PATCH 1/5] drm/meson: drop unused staitc dw_hdmi_dwc_write_bits
On 08/09/2024 16:21, Krzysztof Kozlowski wrote: static inline dw_hdmi_dwc_write_bits() function is not used at all: drivers/gpu/drm/meson/meson_dw_hdmi.c:276:20: error: unused function 'dw_hdmi_dwc_write_bits' [-Werror,-Wunused-function] Signed-off-by: Krzysztof Kozlowski --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 14 -- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 5565f529..b75db829b1da 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -272,20 +272,6 @@ static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi, writeb(data, dw_hdmi->hdmitx + addr); } -/* Helper to change specific bits in controller registers */ -static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, - unsigned int addr, - unsigned int mask, - unsigned int val) -{ - unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); - - data &= ~mask; - data |= val; - - dw_hdmi->data->dwc_write(dw_hdmi, addr, data); -} - /* Bridge */ /* Setup PHY bandwidth modes */ Reviewed-by: Neil Armstrong
Re: [PATCH] drm/meson: switch to a managed drm device
On 30/08/2024 10:23, Anastasia Belova wrote: Hi, 29/08/24 15:14, Neil Armstrong пишет: Hi, On 28/08/2024 13:04, Anastasia Belova wrote: Switch to a managed drm device to cleanup some error handling and make future work easier. Fix dereference of NULL in meson_drv_bind_master by removing drm_dev_put(drm) before meson_encoder_*_remove where drm dereferenced. Please send the fix separately with a Fixes tag. This fix can't be separated from the patch. drm_dev_put may be removed only while switching to a managed drm. Otherwise a check could be added before calling meson_encoder_*_remove. But it would become redundant after switching to a managed drm. I may send the second version of this patch with Fixes tag, so all changes could be applied to older versions. Reading the currenrt code, component_unbind_all(dev, drm) is called after drm_dev_put(drm), which is quite wrong aswell. So perhaps we should keep the kref on drm until component_unbind_all() is called in the first case, no ? Neil Thanks, Anastasia Belova Thanks, Neil Co-developed by Linux Verification Center (linuxtesting.org). Signed-off-by: Anastasia Belova --- drivers/gpu/drm/meson/meson_crtc.c | 10 +-- drivers/gpu/drm/meson/meson_drv.c | 71 ++ drivers/gpu/drm/meson/meson_drv.h | 2 +- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 8 +-- drivers/gpu/drm/meson/meson_overlay.c | 8 +-- drivers/gpu/drm/meson/meson_plane.c | 10 +-- 6 files changed, 51 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c index d70616da8ce2..e1c0bf3baeea 100644 --- a/drivers/gpu/drm/meson/meson_crtc.c +++ b/drivers/gpu/drm/meson/meson_crtc.c @@ -662,13 +662,13 @@ void meson_crtc_irq(struct meson_drm *priv) drm_crtc_handle_vblank(priv->crtc); - spin_lock_irqsave(&priv->drm->event_lock, flags); + spin_lock_irqsave(&priv->drm.event_lock, flags); if (meson_crtc->event) { drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event); drm_crtc_vblank_put(priv->crtc); meson_crtc->event = NULL; } - spin_unlock_irqrestore(&priv->drm->event_lock, flags); + spin_unlock_irqrestore(&priv->drm.event_lock, flags); } int meson_crtc_create(struct meson_drm *priv) @@ -677,18 +677,18 @@ int meson_crtc_create(struct meson_drm *priv) struct drm_crtc *crtc; int ret; - meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc), + meson_crtc = devm_kzalloc(priv->drm.dev, sizeof(*meson_crtc), GFP_KERNEL); if (!meson_crtc) return -ENOMEM; meson_crtc->priv = priv; crtc = &meson_crtc->base; - ret = drm_crtc_init_with_planes(priv->drm, crtc, + ret = drm_crtc_init_with_planes(&priv->drm, crtc, priv->primary_plane, NULL, &meson_crtc_funcs, "meson_crtc"); if (ret) { - dev_err(priv->drm->dev, "Failed to init CRTC\n"); + dev_err(priv->drm.dev, "Failed to init CRTC\n"); return ret; } diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 4bd0baa2a4f5..2e7c2e7c7b82 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -182,7 +182,6 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) struct platform_device *pdev = to_platform_device(dev); const struct meson_drm_match_data *match; struct meson_drm *priv; - struct drm_device *drm; struct resource *res; void __iomem *regs; int ret, i; @@ -197,17 +196,13 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (!match) return -ENODEV; - drm = drm_dev_alloc(&meson_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + priv = devm_drm_dev_alloc(dev, &meson_driver, + struct meson_drm, drm); - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto free_drm; - } - drm->dev_private = priv; - priv->drm = drm; + if (IS_ERR(priv)) + return PTR_ERR(priv); + + priv->drm.dev_private = priv; priv->dev = dev; priv->compat = match->compat; priv->afbcd.ops = match->afbcd_ops; @@ -215,7 +210,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) regs = devm_platform_ioremap_resource_byname(pdev, "vpu"); if (IS_ERR(regs)) { ret = PTR_ERR(regs); - goto free_drm; + goto remove_encoders; } priv->io_base = regs; @@ -223,13 +218,13 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) res = platform_get_resource_byname(
Re: [PATCH 1/3] dt-bindings: display: panel: Rename WL-355608-A8 panel
On 30/08/2024 03:43, Ryan Walklin wrote: On 28 Aug 2024, at 7:07 PM, Maxime Ripard wrote: On Tue, Aug 27, 2024 at 06:28:21PM GMT, Neil Armstrong wrote: Thanks both for the further feedback, agreed logical to use the device vendor and panel serial number, ie "anbernic,wl-355608-a8". Will post a V2 with a comment to that effect. Well in this case we can keep "wl-355608-a8", because the panel vendor _is not_ anbernic. And it's not a generic or ubiquitous device either. We've been over this already, anbernic is the best we have. I don’t have a strong preference either way but agree the anbernic vendor string is the best compromise. The only valid compatible with anbernic would be to use the exact device in use and not a wildcard, so you said the 3 devices using this panel are: anbernic,rg35xx-2024 anbernic,rg35xx-plus anbernic,rg35xx-h you should introduce 3 compatibles: anbernic,rg35xx-2024-panel anbernic,rg35xx-plus-panel anbernic,rg35xx-h-panel but it's duplicating for nothing, to you should use fallbacks for 2 of them to have in DT : anbernic,rg35xx-2024-panel anbernic,rg35xx-plus-panel, anbernic,rg35xx-2024-panel anbernic,rg35xx-h-panel, anbernic,rg35xx-2024-panel and only use anbernic,rg35xx-2024-panel in the driver. In this case bindings should be like: properties: compatible: oneOf: - const: anbernic,rg35xx-2024-panel - items: - enum: - anbernic,rg35xx-plus-panel - anbernic,rg35xx-h-panel - const: anbernic,rg35xx-2024-panel (of course I selected rg35xx-2024 as the primary one, it could be another, usually the older one) Neil Regards, Ryan
Re: [PATCH] drm/meson: switch to a managed drm device
Hi, On 28/08/2024 13:04, Anastasia Belova wrote: Switch to a managed drm device to cleanup some error handling and make future work easier. Fix dereference of NULL in meson_drv_bind_master by removing drm_dev_put(drm) before meson_encoder_*_remove where drm dereferenced. Please send the fix separately with a Fixes tag. Thanks, Neil Co-developed by Linux Verification Center (linuxtesting.org). Signed-off-by: Anastasia Belova --- drivers/gpu/drm/meson/meson_crtc.c | 10 +-- drivers/gpu/drm/meson/meson_drv.c | 71 ++ drivers/gpu/drm/meson/meson_drv.h | 2 +- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 8 +-- drivers/gpu/drm/meson/meson_overlay.c | 8 +-- drivers/gpu/drm/meson/meson_plane.c| 10 +-- 6 files changed, 51 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c index d70616da8ce2..e1c0bf3baeea 100644 --- a/drivers/gpu/drm/meson/meson_crtc.c +++ b/drivers/gpu/drm/meson/meson_crtc.c @@ -662,13 +662,13 @@ void meson_crtc_irq(struct meson_drm *priv) drm_crtc_handle_vblank(priv->crtc); - spin_lock_irqsave(&priv->drm->event_lock, flags); + spin_lock_irqsave(&priv->drm.event_lock, flags); if (meson_crtc->event) { drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event); drm_crtc_vblank_put(priv->crtc); meson_crtc->event = NULL; } - spin_unlock_irqrestore(&priv->drm->event_lock, flags); + spin_unlock_irqrestore(&priv->drm.event_lock, flags); } int meson_crtc_create(struct meson_drm *priv) @@ -677,18 +677,18 @@ int meson_crtc_create(struct meson_drm *priv) struct drm_crtc *crtc; int ret; - meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc), + meson_crtc = devm_kzalloc(priv->drm.dev, sizeof(*meson_crtc), GFP_KERNEL); if (!meson_crtc) return -ENOMEM; meson_crtc->priv = priv; crtc = &meson_crtc->base; - ret = drm_crtc_init_with_planes(priv->drm, crtc, + ret = drm_crtc_init_with_planes(&priv->drm, crtc, priv->primary_plane, NULL, &meson_crtc_funcs, "meson_crtc"); if (ret) { - dev_err(priv->drm->dev, "Failed to init CRTC\n"); + dev_err(priv->drm.dev, "Failed to init CRTC\n"); return ret; } diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 4bd0baa2a4f5..2e7c2e7c7b82 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -182,7 +182,6 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) struct platform_device *pdev = to_platform_device(dev); const struct meson_drm_match_data *match; struct meson_drm *priv; - struct drm_device *drm; struct resource *res; void __iomem *regs; int ret, i; @@ -197,17 +196,13 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (!match) return -ENODEV; - drm = drm_dev_alloc(&meson_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + priv = devm_drm_dev_alloc(dev, &meson_driver, +struct meson_drm, drm); - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto free_drm; - } - drm->dev_private = priv; - priv->drm = drm; + if (IS_ERR(priv)) + return PTR_ERR(priv); + + priv->drm.dev_private = priv; priv->dev = dev; priv->compat = match->compat; priv->afbcd.ops = match->afbcd_ops; @@ -215,7 +210,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) regs = devm_platform_ioremap_resource_byname(pdev, "vpu"); if (IS_ERR(regs)) { ret = PTR_ERR(regs); - goto free_drm; + goto remove_encoders; } priv->io_base = regs; @@ -223,13 +218,13 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); if (!res) { ret = -EINVAL; - goto free_drm; + goto remove_encoders; } /* Simply ioremap since it may be a shared register zone */ regs = devm_ioremap(dev, res->start, resource_size(res)); if (!regs) { ret = -EADDRNOTAVAIL; - goto free_drm; + goto remove_encoders; } priv->hhi = devm_regmap_init_mmio(dev, regs, @@ -237,18 +232,18 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (IS_ERR(priv->hhi)) { dev_err(&pdev->dev
Re: [PATCH] drm/panel: nv3051d: Transition to mipi_dsi_dcs_write_seq_multi
Hi, On Tue, 27 Aug 2024 20:55:04 +0530, Abhishek Tamboli wrote: > Replace deprecated 'mipi_dsi_dcs_write_seq()' macro > to 'mipi_dsi_dcs_write_seq_multi' macro in > panel_nv3051d_init_sequence function. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: nv3051d: Transition to mipi_dsi_dcs_write_seq_multi https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/bfbdf72d6c145e008805f0745ff79f9b8e301e0e -- Neil
Re: [PATCH v2] drm/panel: novatek-nt35950: transition to mipi_dsi wrapped functions
Hi, On Wed, 28 Aug 2024 23:52:10 +0530, Tejas Vipin wrote: > Changes the novatek-nt35950 panel to use multi style functions for > improved error handling. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: novatek-nt35950: transition to mipi_dsi wrapped functions https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/076403a69837c1f8454ceced3ed6f0465835f4d1 -- Neil
Re: [PATCH 0/2] drm/panel: annual cleanup of visionox vtdr6130 driver
Hi, On Wed, 28 Aug 2024 18:03:38 +0200, Neil Armstrong wrote: > Switch to _multi() dsi functions and devm_regulator_bulk_get_const() > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] drm/panel: visionox-vtdr6130: switch to mipi_dsi wrapped functions https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/175d648be98bae22eb22444377dd9a0c497c9d46 [2/2] drm/panel: visionox-vtdr6130: switch to devm_regulator_bulk_get_const https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/e0cb0c785250d0565c19ba17fc95bd7ab97670ba -- Neil
Re: [PATCH v2] drm/panel: novatek-nt35950: transition to mipi_dsi wrapped functions
On 28/08/2024 21:26, Doug Anderson wrote: Hi, On Wed, Aug 28, 2024 at 11:26 AM Tejas Vipin wrote: Changes the novatek-nt35950 panel to use multi style functions for improved error handling. Reviewed-by: Neil Armstrong Signed-off-by: Tejas Vipin --- Changes in v2: - Style changes - Fixed changes in logic v1: https://lore.kernel.org/all/20240824084422.202946-1-tejasvipi...@gmail.com/ --- drivers/gpu/drm/panel/panel-novatek-nt35950.c | 211 ++ 1 file changed, 66 insertions(+), 145 deletions(-) Reviewed-by: Douglas Anderson Neil: Let me know if you want to land this or you want me to land it. Thanks! -Doug I was already applying stuff so I applied it ! Thanks Neil
Re: [PATCH 1/2] drm/panel: visionox-vtdr6130: switch to mipi_dsi wrapped functions
On 28/08/2024 18:32, Doug Anderson wrote: Hi, On Wed, Aug 28, 2024 at 9:03 AM Neil Armstrong wrote: Make usage of the new _multi() mipi_dsi functions instead of the deprecated macros, improving error handling and printing. bloat-o-meter gives a 12% gain on arm64: Function old new delta visionox_vtdr6130_unprepare 208 204 -4 visionox_vtdr6130_prepare 1192 896-296 Total: Before=2348, After=2048, chg -12.78% Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 186 +++- 1 file changed, 82 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index 540099253e1b..ebe92871dbb6 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -40,120 +40,103 @@ static void visionox_vtdr6130_reset(struct visionox_vtdr6130 *ctx) static int visionox_vtdr6130_on(struct visionox_vtdr6130 *ctx) { struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; This isn't something you introduced in your patch, but I wonder if we should avoid setting the "MIPI_DSI_MODE_LPM" bit when the function returns an error? Yeah it's unrelated to this change, but I'll investigate. In any case: Reviewed-by: Douglas Anderson Thanks, Neil
[PATCH 1/2] drm/panel: visionox-vtdr6130: switch to mipi_dsi wrapped functions
Make usage of the new _multi() mipi_dsi functions instead of the deprecated macros, improving error handling and printing. bloat-o-meter gives a 12% gain on arm64: Function old new delta visionox_vtdr6130_unprepare 208 204 -4 visionox_vtdr6130_prepare 1192 896-296 Total: Before=2348, After=2048, chg -12.78% Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 186 +++- 1 file changed, 82 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index 540099253e1b..ebe92871dbb6 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -40,120 +40,103 @@ static void visionox_vtdr6130_reset(struct visionox_vtdr6130 *ctx) static int visionox_vtdr6130_on(struct visionox_vtdr6130 *ctx) { struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (ret) - return ret; - - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0x00, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0x59, 0x09); - mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x01); - mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x01); - mipi_dsi_dcs_write_seq(dsi, 0x70, - 0x12, 0x00, 0x00, 0xab, 0x30, 0x80, 0x09, 0x60, 0x04, - 0x38, 0x00, 0x28, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x00, - 0x02, 0x0e, 0x00, 0x20, 0x03, 0xdd, 0x00, 0x07, 0x00, - 0x0c, 0x02, 0x77, 0x02, 0x8b, 0x18, 0x00, 0x10, 0xf0, - 0x07, 0x10, 0x20, 0x00, 0x06, 0x0f, 0x0f, 0x33, 0x0e, - 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, - 0x79, 0x7b, 0x7d, 0x7e, 0x02, 0x02, 0x22, 0x00, 0x2a, - 0x40, 0x2a, 0xbe, 0x3a, 0xfc, 0x3a, 0xfa, 0x3a, 0xf8, - 0x3b, 0x38, 0x3b, 0x78, 0x3b, 0xb6, 0x4b, 0xb6, 0x4b, - 0xf4, 0x4b, 0xf4, 0x6c, 0x34, 0x84, 0x74, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0xaa, 0x10); - mipi_dsi_dcs_write_seq(dsi, 0xb1, - 0x01, 0x38, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x01, 0x66, - 0x00, 0x14, 0x00, 0x14, 0x00, 0x01, 0x66, 0x00, 0x14, - 0x05, 0xcc, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0xaa, 0x13); - mipi_dsi_dcs_write_seq(dsi, 0xce, - 0x09, 0x11, 0x09, 0x11, 0x08, 0xc1, 0x07, 0xfa, 0x05, - 0xa4, 0x00, 0x3c, 0x00, 0x34, 0x00, 0x24, 0x00, 0x0c, - 0x00, 0x0c, 0x04, 0x00, 0x35); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0xaa, 0x14); - mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x03, 0x33); - mipi_dsi_dcs_write_seq(dsi, 0xb4, - 0x00, 0x33, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xb5, - 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x01); - mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0x00, 0x08, 0x09, 0x09, 0x09); - mipi_dsi_dcs_write_seq(dsi, 0xbc, - 0x10, 0x00, 0x00, 0x06, 0x11, 0x09, 0x3b, 0x09, 0x47, - 0x09, 0x47, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xbe, - 0x10, 0x10, 0x00, 0x08, 0x22, 0x09, 0x19, 0x09, 0x25, - 0x09, 0x25, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x5a, 0x80); - mipi_dsi_dcs_write_seq(dsi, 0x65, 0x14); - mipi_dsi_dcs_write_seq(dsi, 0xfa, 0x08, 0x08, 0x08); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x5a, 0x81); - mipi_dsi_dcs_write_seq(dsi, 0x65, 0x05); - mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x0f); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0xaa, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x5a, 0x82); - mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x51, 0x83); - mipi_dsi_dcs_write_seq(dsi, 0x65, 0x04); - mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x5a, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0x65, 0x01); - mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x9a); - mipi_dsi_dcs_write_seq(dsi, 0xff, 0x5a, 0x00);
[PATCH 2/2] drm/panel: visionox-vtdr6130: switch to devm_regulator_bulk_get_const
Switch to devm_regulator_bulk_get_const() to stop setting the supplies list in probe(), and move the regulator_bulk_data struct in static const. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 26 +++-- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index ebe92871dbb6..17b8defe79c1 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -19,7 +19,13 @@ struct visionox_vtdr6130 { struct drm_panel panel; struct mipi_dsi_device *dsi; struct gpio_desc *reset_gpio; - struct regulator_bulk_data supplies[3]; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data visionox_vtdr6130_supplies[] = { + { .supply = "vddio" }, + { .supply = "vci" }, + { .supply = "vdd" }, }; static inline struct visionox_vtdr6130 *to_visionox_vtdr6130(struct drm_panel *panel) @@ -139,7 +145,7 @@ static int visionox_vtdr6130_prepare(struct drm_panel *panel) struct visionox_vtdr6130 *ctx = to_visionox_vtdr6130(panel); int ret; - ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), + ret = regulator_bulk_enable(ARRAY_SIZE(visionox_vtdr6130_supplies), ctx->supplies); if (ret < 0) return ret; @@ -149,7 +155,8 @@ static int visionox_vtdr6130_prepare(struct drm_panel *panel) ret = visionox_vtdr6130_on(ctx); if (ret < 0) { gpiod_set_value_cansleep(ctx->reset_gpio, 1); - regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + regulator_bulk_disable(ARRAY_SIZE(visionox_vtdr6130_supplies), + ctx->supplies); return ret; } @@ -164,7 +171,8 @@ static int visionox_vtdr6130_unprepare(struct drm_panel *panel) gpiod_set_value_cansleep(ctx->reset_gpio, 1); - regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + regulator_bulk_disable(ARRAY_SIZE(visionox_vtdr6130_supplies), + ctx->supplies); return 0; } @@ -244,12 +252,10 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device *dsi) if (!ctx) return -ENOMEM; - ctx->supplies[0].supply = "vddio"; - ctx->supplies[1].supply = "vci"; - ctx->supplies[2].supply = "vdd"; - - ret = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ctx->supplies), - ctx->supplies); + ret = devm_regulator_bulk_get_const(&dsi->dev, + ARRAY_SIZE(visionox_vtdr6130_supplies), + visionox_vtdr6130_supplies, + &ctx->supplies); if (ret < 0) return ret; -- 2.34.1
[PATCH 0/2] drm/panel: annual cleanup of visionox vtdr6130 driver
Switch to _multi() dsi functions and devm_regulator_bulk_get_const() Signed-off-by: Neil Armstrong --- Neil Armstrong (2): drm/panel: visionox-vtdr6130: switch to mipi_dsi wrapped functions drm/panel: visionox-vtdr6130: switch to devm_regulator_bulk_get_const drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 212 +++- 1 file changed, 98 insertions(+), 114 deletions(-) --- base-commit: 195a402a75791e6e0d96d9da27ca77671bc656a8 change-id: 20240828-topic-sm8x50-upstream-vtdr6130-multi-d1f03595a394 Best regards, -- Neil Armstrong
Re: [PATCH v3 0/2] drm/panel: add support for the BOE TV101WUM-LL2 DSI Display Panel
Hi, On Wed, 28 Aug 2024 17:04:18 +0200, Neil Armstrong wrote: > Document and add support for the 1200x1920 BOE TV101WUM-LL2 DSI > Display Panel found in the Lenovo Smart Tab M10 tablet. > The controller powering the panel is unknown. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/1da04eac69197032813940426b73fff6f0a84c64 [2/2] drm/panel: add BOE tv101wum-ll2 panel driver https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/aec8485f226c36eb4eea1d489772cd6f2c40144d -- Neil
Re: [PATCH 0/2] drm/panel: add support for the BOE TV101WUM-LL2 DSI Display Panel
Hi, On Tue, 09 Jul 2024 15:05:43 +0200, Neil Armstrong wrote: > Document and add support for the 1200x1920 BOE TV101WUM-LL2 DSI > Display Panel found in the Lenovo Smart Tab M10 tablet. > The controller powering the panel is unknown. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/1da04eac69197032813940426b73fff6f0a84c64 [2/2] drm/panel: add BOE tv101wum-ll2 panel driver https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/aec8485f226c36eb4eea1d489772cd6f2c40144d -- Neil
Re: [PATCH] drm/panel: nv3051d: Transition to mipi_dsi_dcs_write_seq_multi
; + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9E, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9F, 0x06); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xA0, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x30); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x52); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xDA); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0xBA); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0xA8); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x9A); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x70); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0xFF); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x91); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x90); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0A, 0xFF); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0B, 0x8F); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x60); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0D, 0x58); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x48); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0F, 0x38); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x2B); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x30); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x52); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xFF, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x70); dev_dbg(ctx->dev, "Panel init sequence done\n"); -- 2.34.1 Reviewed-by: Neil Armstrong
[PATCH v3 2/2] drm/panel: add BOE tv101wum-ll2 panel driver
Add support for the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller is unknown. Reviewed-by: Douglas Anderson Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c | 241 + 3 files changed, 251 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 5d83ddc06ece..d3a9a9fafe4e 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -87,6 +87,15 @@ config DRM_PANEL_BOE_TV101WUM_NL6 Say Y here if you want to support for BOE TV101WUM and AUO KD101N80 45NA WUXGA PANEL DSI Video Mode panel +config DRM_PANEL_BOE_TV101WUM_LL2 + tristate "BOE TV101WUM LL2 1200x1920 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to support for BOE TV101WUM-LL2 + WUXGA PANEL DSI Video Mode panel + config DRM_PANEL_EBBG_FT8719 tristate "EBBG FT8719 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5581387707c6..987a08702410 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_PANEL_AUO_A030JTN01) += panel-auo-a030jtn01.o obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a.o +obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_LL2) += panel-boe-tv101wum-ll2.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c new file mode 100644 index ..50e4a5341bc6 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: +// Copyright (c) 2013, The Linux Foundation. All rights reserved. +// Copyright (c) 2024, Neil Armstrong + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct boe_tv101wum_ll2 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data boe_tv101wum_ll2_supplies[] = { + { .supply = "vsp" }, + { .supply = "vsn" }, +}; + +static inline struct boe_tv101wum_ll2 *to_boe_tv101wum_ll2(struct drm_panel *panel) +{ + return container_of(panel, struct boe_tv101wum_ll2, panel); +} + +static void boe_tv101wum_ll2_reset(struct boe_tv101wum_ll2 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + + msleep(120); +} + +static int boe_tv101wum_ll2_on(struct boe_tv101wum_ll2 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x0e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0xff, 0x81, 0x68, 0x6c, 0x22, +0x6d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x23); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x94, 0x2c, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa2, 0x38); + + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x0c); + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x80, 0xfd); + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x50, 0x00); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 20); + + return dsi_ctx.accum_err; +} + +static void boe_tv101wum_ll2_off(struct boe_tv101wum_ll2 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + + m
[PATCH v3 1/2] dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel
Document the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller is unknown. Reviewed-by: Conor Dooley Signed-off-by: Neil Armstrong --- .../bindings/display/panel/boe,tv101wum-ll2.yaml | 63 ++ 1 file changed, 63 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml new file mode 100644 index ..dced98e1c69a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/boe,tv101wum-ll2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BOE TV101WUM-LL2 DSI Display Panel + +maintainers: + - Neil Armstrong + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: boe,tv101wum-ll2 + + reg: +maxItems: 1 +description: DSI virtual channel + + backlight: true + reset-gpios: true + vsp-supply: true + vsn-supply: true + port: true + rotation: true + +required: + - compatible + - reg + - reset-gpios + - vsp-supply + - vsn-supply + - port + +additionalProperties: false + +examples: + - | +#include +dsi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "boe,tv101wum-ll2"; +reg = <0>; + +vsn-supply = <&vsn_lcd>; +vsp-supply = <&vsp_lcd>; + +reset-gpios = <&pio 45 GPIO_ACTIVE_LOW>; + +port { +panel_in: endpoint { +remote-endpoint = <&dsi_out>; +}; +}; +}; +}; + +... -- 2.34.1
[PATCH v3 0/2] drm/panel: add support for the BOE TV101WUM-LL2 DSI Display Panel
Document and add support for the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller powering the panel is unknown. Signed-off-by: Neil Armstrong --- Changes in v3: - switch boe_tv101wum_ll2_off() to void - add Doug's reviewed-by - Link to v2: https://lore.kernel.org/r/20240828-topic-sdm450-upstream-tbx605f-panel-v2-0-0a039d064...@linaro.org Changes in v2: - Collected bindings review tag - Driver changes: - reorder makefile - reorder includes - switch to devm_regulator_bulk_get_const() - remove useless dev_err() - add comments why we ignore boe_tv101wum_ll2_off() return - add comment why we don't set bpc - fix MODULE_DESCRIPTION - Link to v1: https://lore.kernel.org/r/20240709-topic-sdm450-upstream-tbx605f-panel-v1-0-af4733978...@linaro.org --- Neil Armstrong (2): dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel drm/panel: add BOE tv101wum-ll2 panel driver .../bindings/display/panel/boe,tv101wum-ll2.yaml | 63 ++ drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c | 241 + 4 files changed, 314 insertions(+) --- base-commit: ef14a2e943460970c95f7936fb3c26fcb223f76d change-id: 20240709-topic-sdm450-upstream-tbx605f-panel-f13d55fbd444 Best regards, -- Neil Armstrong
Re: [PATCH v2 2/2] drm/panel: add BOE tv101wum-ll2 panel driver
On 28/08/2024 16:11, Doug Anderson wrote: Hi, On Wed, Aug 28, 2024 at 2:22 AM Neil Armstrong wrote: +static int boe_tv101wum_ll2_off(struct boe_tv101wum_ll2 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 70); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 20); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x5a); + + mipi_dsi_msleep(&dsi_ctx, 150); + + return dsi_ctx.accum_err; +} optional nit: now that the single caller of this function isn't looking at the error code, you could make boe_tv101wum_ll2_off() return "void". Indeed, I'll spin a v3 with this and you review and apply it In any case, this looks good. Reviewed-by: Douglas Anderson Thanks! Neil
[PATCH v2 2/2] drm/panel: add BOE tv101wum-ll2 panel driver
Add support for the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller is unknown. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c | 243 + 3 files changed, 253 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 5d83ddc06ece..d3a9a9fafe4e 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -87,6 +87,15 @@ config DRM_PANEL_BOE_TV101WUM_NL6 Say Y here if you want to support for BOE TV101WUM and AUO KD101N80 45NA WUXGA PANEL DSI Video Mode panel +config DRM_PANEL_BOE_TV101WUM_LL2 + tristate "BOE TV101WUM LL2 1200x1920 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to support for BOE TV101WUM-LL2 + WUXGA PANEL DSI Video Mode panel + config DRM_PANEL_EBBG_FT8719 tristate "EBBG FT8719 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5581387707c6..987a08702410 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_PANEL_AUO_A030JTN01) += panel-auo-a030jtn01.o obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a.o +obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_LL2) += panel-boe-tv101wum-ll2.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c new file mode 100644 index ..ec6a177ef888 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: +// Copyright (c) 2013, The Linux Foundation. All rights reserved. +// Copyright (c) 2024, Neil Armstrong + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct boe_tv101wum_ll2 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data boe_tv101wum_ll2_supplies[] = { + { .supply = "vsp" }, + { .supply = "vsn" }, +}; + +static inline struct boe_tv101wum_ll2 *to_boe_tv101wum_ll2(struct drm_panel *panel) +{ + return container_of(panel, struct boe_tv101wum_ll2, panel); +} + +static void boe_tv101wum_ll2_reset(struct boe_tv101wum_ll2 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + + msleep(120); +} + +static int boe_tv101wum_ll2_on(struct boe_tv101wum_ll2 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x0e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0xff, 0x81, 0x68, 0x6c, 0x22, +0x6d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x23); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x94, 0x2c, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa2, 0x38); + + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x50, 0x5a, 0x0c); + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x80, 0xfd); + mipi_dsi_generic_write_seq_multi(&dsi_ctx, 0x50, 0x00); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 20); + + return dsi_ctx.accum_err; +} + +static int boe_tv101wum_ll2_off(struct boe_tv101wum_ll2 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + + mipi_dsi_msleep(&dsi_ctx, 70); + + mipi_dsi_dcs_enter
[PATCH v2 1/2] dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel
Document the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller is unknown. Reviewed-by: Conor Dooley Signed-off-by: Neil Armstrong --- .../bindings/display/panel/boe,tv101wum-ll2.yaml | 63 ++ 1 file changed, 63 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml new file mode 100644 index ..dced98e1c69a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-ll2.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/boe,tv101wum-ll2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BOE TV101WUM-LL2 DSI Display Panel + +maintainers: + - Neil Armstrong + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: boe,tv101wum-ll2 + + reg: +maxItems: 1 +description: DSI virtual channel + + backlight: true + reset-gpios: true + vsp-supply: true + vsn-supply: true + port: true + rotation: true + +required: + - compatible + - reg + - reset-gpios + - vsp-supply + - vsn-supply + - port + +additionalProperties: false + +examples: + - | +#include +dsi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "boe,tv101wum-ll2"; +reg = <0>; + +vsn-supply = <&vsn_lcd>; +vsp-supply = <&vsp_lcd>; + +reset-gpios = <&pio 45 GPIO_ACTIVE_LOW>; + +port { +panel_in: endpoint { +remote-endpoint = <&dsi_out>; +}; +}; +}; +}; + +... -- 2.34.1
[PATCH v2 0/2] drm/panel: add support for the BOE TV101WUM-LL2 DSI Display Panel
Document and add support for the 1200x1920 BOE TV101WUM-LL2 DSI Display Panel found in the Lenovo Smart Tab M10 tablet. The controller powering the panel is unknown. Signed-off-by: Neil Armstrong --- Changes in v2: - Collected bindings review tag - Driver changes: - reorder makefile - reorder includes - switch to devm_regulator_bulk_get_const() - remove useless dev_err() - add comments why we ignore boe_tv101wum_ll2_off() return - add comment why we don't set bpc - fix MODULE_DESCRIPTION - Link to v1: https://lore.kernel.org/r/20240709-topic-sdm450-upstream-tbx605f-panel-v1-0-af4733978...@linaro.org --- Neil Armstrong (2): dt-bindings: display: panel: document BOE TV101WUM-LL2 DSI Display Panel drm/panel: add BOE tv101wum-ll2 panel driver .../bindings/display/panel/boe,tv101wum-ll2.yaml | 63 ++ drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-ll2.c | 243 + 4 files changed, 316 insertions(+) --- base-commit: ef14a2e943460970c95f7936fb3c26fcb223f76d change-id: 20240709-topic-sdm450-upstream-tbx605f-panel-f13d55fbd444 Best regards, -- Neil Armstrong
Re: [PATCH 2/2] drm/panel: add BOE tv101wum-ll2 panel driver
On 24/07/2024 09:50, Neil Armstrong wrote: On 23/07/2024 21:17, Doug Anderson wrote: Hi, On Tue, Jul 9, 2024 at 6:06 AM Neil Armstrong wrote: +static int boe_tv101wum_ll2_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &boe_tv101wum_ll2_mode); Random question for you: on panels that don't use the drm_connector_helper the "bpc" gets set here. Is there a reason why some panel drivers (like this one) don't set bpc? Good question, I'll check Ok so the documentation says : https://elixir.bootlin.com/linux/v6.11-rc5/source/include/drm/drm_connector.h#L698 * @bpc: Maximum bits per color channel. Used by HDMI and DP outputs. and looking at the code, all drivers considers bpc=8 when unset. but yeah ultimately drm_connector_helper_get_modes_fixed should have a variant to set the bpc when != 8. In this case it's useless. Neil
Re: [PATCH] drm/panel: novatek-nt35950: transition to mipi_dsi wrapped functions
cs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (ret < 0) { - dev_err(dev, "Failed to set tear on: %d\n", ret); - return ret; - } - - ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0); - if (ret < 0) { - dev_err(dev, "Failed to set tear scanline: %d\n", ret); - return ret; - } + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + mipi_dsi_dcs_set_tear_scanline_multi(&dsi_ctx, 0); /* CMD2 Page 1 */ - ret = nt35950_set_cmd2_page(nt, 1); - if (ret < 0) - return ret; + nt35950_set_cmd2_page(&dsi_ctx, nt, 1); /* Unknown command */ - mipi_dsi_dcs_write_seq(dsi, 0xd4, 0x88, 0x88); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xd4, 0x88, 0x88); /* CMD2 Page 7 */ - ret = nt35950_set_cmd2_page(nt, 7); - if (ret < 0) - return ret; + nt35950_set_cmd2_page(&dsi_ctx, nt, 7); /* Enable SubPixel Rendering */ - mipi_dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_EN, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PARAM_SPR_EN, 0x01); /* SPR Mode: YYG Rainbow-RGB */ - mipi_dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_MODE, MCS_SPR_MODE_YYG_RAINBOW_RGB); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PARAM_SPR_MODE, +MCS_SPR_MODE_YYG_RAINBOW_RGB); /* CMD3 */ - ret = nt35950_inject_black_image(nt); - if (ret < 0) - return ret; + nt35950_inject_black_image(&dsi_ctx); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) - return ret; - msleep(120); - - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) - return ret; - msleep(120); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); nt->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM; nt->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM; - return 0; + return dsi_ctx.accum_err; } static int nt35950_off(struct nt35950 *nt) { - struct device *dev = &nt->dsi[0]->dev; - int ret; + struct mipi_dsi_device *dsi = nt->dsi[0]; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - ret = mipi_dsi_dcs_set_display_off(nt->dsi[0]); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - goto set_lpm; - } - usleep_range(1, 11000); + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_usleep_range(&dsi_ctx, 1, 11000); - ret = mipi_dsi_dcs_enter_sleep_mode(nt->dsi[0]); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - goto set_lpm; - } - msleep(150); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 150); -set_lpm: - nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM; - nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; + if (dsi_ctx.accum_err) { + nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM; + nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; + } - return 0; + return dsi_ctx.accum_err; } static int nt35950_sharp_init_vregs(struct nt35950 *nt, struct device *dev) @@ -427,7 +360,6 @@ static int nt35950_sharp_init_vregs(struct nt35950 *nt, struct device *dev) static int nt35950_prepare(struct drm_panel *panel) { struct nt35950 *nt = to_nt35950(panel); - struct device *dev = &nt->dsi[0]->dev; int ret; ret = regulator_enable(nt->vregs[0].consumer); @@ -452,10 +384,8 @@ static int nt35950_prepare(struct drm_panel *panel) nt35950_reset(nt); ret = nt35950_on(nt); - if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); + if (ret < 0) goto end; - } end: if (ret < 0) { @@ -469,12 +399,8 @@ static int nt35950_prepare(struct drm_panel *panel) static int nt35950_unprepare(struct drm_panel *panel) { struct nt35950 *nt = to_nt35950(panel); - struct device *dev = &nt->dsi[0]->dev; - int ret; - ret = nt35950_off(nt); - if (ret < 0) - dev_err(dev, "Failed to deinitialize panel: %d\n", ret); + nt35950_off(nt); gpiod_set_value_cansleep(nt->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(nt->vregs), nt->vregs); Looks fine! Reviewed-by: Neil Armstrong
Re: [PATCH 1/3] dt-bindings: display: panel: Rename WL-355608-A8 panel
On 30/06/2024 10:16, Ryan Walklin wrote: On Fri, 28 Jun 2024, at 5:59 AM, Maxime Ripard wrote: On Wed, Jun 26, 2024 at 04:34:11PM GMT, Conor Dooley wrote: On Wed, Jun 26, 2024 at 05:04:19PM +0200, Maxime Ripard wrote: On Wed, Jun 26, 2024 at 02:25:54PM GMT, Neil Armstrong wrote: Can it be more specific ? because there's a lot of rg35xx defined in bindings: anbernic,rg351m anbernic,rg351v anbernic,rg353p anbernic,rg353ps anbernic,rg353v anbernic,rg353vs anbernic,rg35xx-2024 anbernic,rg35xx-plus anbernic,rg35xx-h Just to note only the three rg35xx-* devices use this particular panel. Yeah, if we have an identified model name, we should probably use that, with a comment that we couldn't figure out what the vendor was and thus went for anbernic. What's wrong with using the wl name that already exists as the model? Using rg-panel is total invention on our part, especially seeing as the commit message says that multiple models can use it. Yeah, that makes sense, sorry for the noise Thanks both for the further feedback, agreed logical to use the device vendor and panel serial number, ie "anbernic,wl-355608-a8". Will post a V2 with a comment to that effect. Well in this case we can keep "wl-355608-a8", because the panel vendor _is not_ anbernic. Neil Regards, Ryan
Re: [PATCH v2 2/4] Revert "drm/panel-edp: Add SDC ATNA45AF01"
On 27/08/2024 17:36, Doug Anderson wrote: Hi, On Mon, Jul 22, 2024 at 8:49 AM Doug Anderson wrote: Hi, On Mon, Jul 15, 2024 at 6:51 AM Doug Anderson wrote: Hi, On Mon, Jul 15, 2024 at 6:02 AM Neil Armstrong wrote: On 15/07/2024 14:54, Stephan Gerhold wrote: On Mon, Jul 15, 2024 at 02:42:12PM +0200, Neil Armstrong wrote: On 15/07/2024 14:15, Stephan Gerhold wrote: This reverts commit 8ebb1fc2e69ab8b89a425e402c7bd85e053b7b01. The panel should be handled through the samsung-atna33xc20 driver for correct power up timings. Otherwise the backlight does not work correctly. We have existing users of this panel through the generic "edp-panel" compatible (e.g. the Qualcomm X1E80100 CRD), but the screen works only partially in that configuration: It works after boot but once the screen gets disabled it does not turn on again until after reboot. It behaves the same way with the default "conservative" timings, so we might as well drop the configuration from the panel-edp driver. That way, users with old DTBs will get a warning and can move to the new driver. Reviewed-by: Douglas Anderson Signed-off-by: Stephan Gerhold --- drivers/gpu/drm/panel/panel-edp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 3a574a9b46e7..d2d682385e89 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1960,8 +1960,6 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('L', 'G', 'D', 0x05af, &delay_200_500_e200_d200, "Unknown"), EDP_PANEL_ENTRY('L', 'G', 'D', 0x05f1, &delay_200_500_e200_d200, "Unknown"), - EDP_PANEL_ENTRY('S', 'D', 'C', 0x416d, &delay_100_500_e200, "ATNA45AF01"), - EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &delay_80_500_e50, "LQ140M1JW46"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x153a, &delay_200_500_e50, "LQ140T1JH01"), How will we handle current/old crd DT with new kernels ? I think this is answered in the commit message: We have existing users of this panel through the generic "edp-panel" compatible (e.g. the Qualcomm X1E80100 CRD), but the screen works only partially in that configuration: It works after boot but once the screen gets disabled it does not turn on again until after reboot. It behaves the same way with the default "conservative" timings, so we might as well drop the configuration from the panel-edp driver. That way, users with old DTBs will get a warning and can move to the new driver. Basically with the entry removed, the panel-edp driver will fallback to default "conservative" timings when using old DTBs. There will be a warning in dmesg, but otherwise the panel will somewhat work just as before. I think this is a good way to remind users to upgrade. I consider this as a regression Same question for patch 3, thie serie introduces a bindings that won't be valid if we backport patch 3. I don't think patch should be backported, and this patch should be dropped. There would be a dtbs_check warning, yeah. Functionally, it would work just fine. Is that reason enough to keep display partially broken for 6.11? We could also apply the minor binding change for 6.11 if needed. I don't know how to answer this, I'll let the DT maintainer comment this. The problem is I do not think we can pass the whole patchset as fixes for v6.11, patches 2 & 3 could, patches 1 & 4 definitely can't. Neil IMO: patch #3 (dts) and #4 (CONFIG) go through the Qualcomm tree whenever those folks agree to it. If we're worried about the dtbs_check breakage I personally wouldn't mind "Ack"ing patch #1 to go through the Qualcomm tree as long as it made it into 6.11-rc1. I have a hunch that there are going to be more Samsung OLED panels in the future that will need to touch the same file, but if the change is in -rc1 it should make it back into drm-misc quickly, right? Personally I think patch #2 could go in anytime since, as people have said, things are pretty broken today and the worst that happens is that someone gets an extra warning. That would be my preference. That being said, we could also snooze that patch for a month or two and land it later. There's no real hurry. For now I'm going to snooze this patch for a month just to avoid any controversy. I'll plan to apply it (to drm-misc-next) when I see the device tree patch land. Since the device tree patch should land as a fix that should keep things landing in the correct order. ...and, as per above, the worst case is that if some
Re: [PATCH 0/7] Preemption support for A7XX
On 23/08/2024 11:54, Connor Abbott wrote: On Fri, Aug 23, 2024 at 9:30 AM wrote: On 15/08/2024 20:26, Antonino Maniscalco wrote: This series implements preemption for A7XX targets, which allows the GPU to switch to an higher priority ring when work is pushed to it, reducing latency for high priority submissions. This series enables L1 preemption with skip_save_restore which requires the following userspace patches to function: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544 A flag is added to `msm_gem_submit` to only allow submissions from compatible userspace to be preempted, therefore maintaining compatibility. Some commits from this series are based on a previous series to enable preemption on A6XX targets: https://lkml.kernel.org/1520489185-21828-1-git-send-email-smase...@codeaurora.org Signed-off-by: Antonino Maniscalco --- Antonino Maniscalco (7): drm/msm: Fix bv_fence being used as bv_rptr drm/msm: Add submitqueue setup and close drm/msm: Add a `preempt_record_size` field drm/msm/A6xx: Implement preemption for A7XX targets drm/msm/A6xx: Add traces for preemption drm/msm/A6XX: Add a flag to allow preemption to submitqueue_create drm/msm/A6xx: Enable preemption for A7xx targets drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 3 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 339 ++- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 168 drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 441 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 7 + drivers/gpu/drm/msm/msm_gpu_trace.h | 28 ++ drivers/gpu/drm/msm/msm_ringbuffer.h | 8 + drivers/gpu/drm/msm/msm_submitqueue.c | 10 + include/uapi/drm/msm_drm.h| 5 +- 11 files changed, 995 insertions(+), 16 deletions(-) --- base-commit: 7c626ce4bae1ac14f60076d00eafe71af30450ba change-id: 20240815-preemption-a750-t-fcee9a844b39 Best regards, For what is worth, I've tested it on the SM8650 QRD with the Mesa 30544 MR & vkcube Tested-by: Neil Armstrong # on SM8650-QRD If you think of more tests to run, please tell me. Neil Hi Neil, I think it would help to test this on SM8550 and SM8450 too. I don't have SM8450 to test with. Maybe also worth mentioning that there are now vulkan CTS tests that try to test L1 preemption: https://github.com/KhronosGroup/VK-GL-CTS/commit/7e0e4a000f34e748bb527b39f730f78b595140b9 although it's not in a released version yet. Sure, It's in my plans, I'm currently testing it on SM8550. Thanks, Neil Connor
Re: [PATCH 0/7] Preemption support for A7XX
On 15/08/2024 20:26, Antonino Maniscalco wrote: This series implements preemption for A7XX targets, which allows the GPU to switch to an higher priority ring when work is pushed to it, reducing latency for high priority submissions. This series enables L1 preemption with skip_save_restore which requires the following userspace patches to function: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544 A flag is added to `msm_gem_submit` to only allow submissions from compatible userspace to be preempted, therefore maintaining compatibility. Some commits from this series are based on a previous series to enable preemption on A6XX targets: https://lkml.kernel.org/1520489185-21828-1-git-send-email-smase...@codeaurora.org Signed-off-by: Antonino Maniscalco --- Antonino Maniscalco (7): drm/msm: Fix bv_fence being used as bv_rptr drm/msm: Add submitqueue setup and close drm/msm: Add a `preempt_record_size` field drm/msm/A6xx: Implement preemption for A7XX targets drm/msm/A6xx: Add traces for preemption drm/msm/A6XX: Add a flag to allow preemption to submitqueue_create drm/msm/A6xx: Enable preemption for A7xx targets drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 3 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 339 ++- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 168 drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 441 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 7 + drivers/gpu/drm/msm/msm_gpu_trace.h | 28 ++ drivers/gpu/drm/msm/msm_ringbuffer.h | 8 + drivers/gpu/drm/msm/msm_submitqueue.c | 10 + include/uapi/drm/msm_drm.h| 5 +- 11 files changed, 995 insertions(+), 16 deletions(-) --- base-commit: 7c626ce4bae1ac14f60076d00eafe71af30450ba change-id: 20240815-preemption-a750-t-fcee9a844b39 Best regards, For what is worth, I've tested it on the SM8650 QRD with the Mesa 30544 MR & vkcube Tested-by: Neil Armstrong # on SM8650-QRD If you think of more tests to run, please tell me. Neil
Re: [PATCH v2 27/86] drm/meson: Run DRM default client setup
On 21/08/2024 14:59, Thomas Zimmermann wrote: Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The meson driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. Signed-off-by: Thomas Zimmermann Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl --- drivers/gpu/drm/meson/meson_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 4bd0baa2a4f5..2f76f48da38d 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -98,6 +99,7 @@ static const struct drm_driver meson_driver = { /* DMA Ops */ DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(meson_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, /* Misc */ .fops = &fops, @@ -353,7 +355,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (ret) goto uninstall_irq; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; Reviewed-by: Neil Armstrong
Re: [PATCH v2] drm/panel: ili9341: Add comments for registers in ili9341_config()
Hi, On Mon, 19 Aug 2024 23:21:22 +0530, Abhishek Tamboli wrote: > Add detail comments for registers definitions in struct ili9341_config(). > Replace TODO with comment for each registers. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: ili9341: Add comments for registers in ili9341_config() https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/1453323eac4f13817a07f40e78e76dfc635aab34 -- Neil
Re: [PATCH v2 0/2] convert mantix-mlaf057we51 to use multi style functions and cleanup
Hi, On Tue, 20 Aug 2024 14:45:52 +0530, Tejas Vipin wrote: > Uses mipi_dsi_*_multi function in the mantix-mlaf057we51 panel and > converting uppercase hex to lowercase hex for cleanup. > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] drm/panel: mantix-mlaf057we51: transition to mipi_dsi wrapped functions https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/e139c0eb22ce5b2ab6a2056c1ff495f3a38322d7 [2/2] drm/panel: mantix-mlaf057we51: write hex in lowercase https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/b61c4bc674c6032827f2682a0c72ff577c36143f -- Neil
Re: [PATCH v2 2/2] drm/panel: mantix-mlaf057we51: write hex in lowercase
On 20/08/2024 11:15, Tejas Vipin wrote: Converts uppercase hex to lowercase hex for cleanup. Signed-off-by: Tejas Vipin --- drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c index 2a365eaa4ad4..4db852ffb0f6 100644 --- a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c +++ b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c @@ -23,7 +23,7 @@ /* Manufacturer specific Commands send via DSI */ #define MANTIX_CMD_OTP_STOP_RELOAD_MIPI 0x41 -#define MANTIX_CMD_INT_CANCEL 0x4C +#define MANTIX_CMD_INT_CANCEL 0x4c #define MANTIX_CMD_SPI_FINISH 0x90 struct mantix { @@ -50,18 +50,18 @@ static void mantix_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) /* * Init sequence was supplied by the panel vendor. */ - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A); + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a); mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_INT_CANCEL, 0x03); - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x03); - mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0xA9, 0x00); + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x03); + mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0xa9, 0x00); - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x09); + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x09); mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0x64, 0x00, 0x64, 0x00, 0x00); mipi_dsi_msleep(dsi_ctx, 20); - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_SPI_FINISH, 0xA5); - mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2F); + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_SPI_FINISH, 0xa5); + mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2f); mipi_dsi_msleep(dsi_ctx, 20); } Reviewed-by: Neil Armstrong
Re: [PATCH v2] drm/panel: ili9341: Add comments for registers in ili9341_config()
On 19/08/2024 19:51, Abhishek Tamboli wrote: Add detail comments for registers definitions in struct ili9341_config(). Replace TODO with comment for each registers. Signed-off-by: Abhishek Tamboli --- Changes in v2: - Rephrased the commit message. drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 775d5d5e828c..1fbc5d433d75 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -121,19 +121,19 @@ struct ili9341_config { const struct drm_display_mode mode; /* ca: TODO: need comments for this register */ u8 ca[ILI9341_CA_LEN]; - /* power_b: TODO: need comments for this register */ + /* power_b: Power control B (CFh) */ u8 power_b[ILI9341_POWER_B_LEN]; - /* power_seq: TODO: need comments for this register */ + /* power_seq: Power on sequence control (EDh) */ u8 power_seq[ILI9341_POWER_SEQ_LEN]; - /* dtca: TODO: need comments for this register */ + /* dtca: Driver timing control A (E8h) */ u8 dtca[ILI9341_DTCA_LEN]; - /* dtcb: TODO: need comments for this register */ + /* dtcb: Driver timing control B (EAh) */ u8 dtcb[ILI9341_DTCB_LEN]; - /* power_a: TODO: need comments for this register */ + /* power_a: Power control A (CBh) */ u8 power_a[ILI9341_POWER_A_LEN]; /* frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */ u8 frc[ILI9341_FRC_LEN]; - /* prc: TODO: need comments for this register */ + /* prc: Pump ratio control (F7h) */ u8 prc; /* dfc_1: B6h DISCTRL (Display Function Control) */ u8 dfc_1[ILI9341_DFC_1_LEN]; @@ -147,7 +147,7 @@ struct ili9341_config { u8 vcom_2; /* address_mode: Memory Access Control (36h) */ u8 address_mode; - /* g3amma_en: TODO: need comments for this register */ + /* g3amma_en: Enable 3G (F2h) */ u8 g3amma_en; /* rgb_interface: RGB Interface Signal Control (B0h) */ u8 rgb_interface; -- 2.34.1 Reviewed-by: Neil Armstrong
Re: [PATCH] drm/panel: mantix-mlaf057we51: transition to mipi_dsi wrapped functions
On 19/08/2024 18:14, Doug Anderson wrote: Hi, On Mon, Aug 19, 2024 at 8:36 AM wrote: Hi, On 18/08/2024 09:23, Tejas Vipin wrote: Changes the mantix-mlaf057we51 panel to use multi style functions for improved error handling. Signed-off-by: Tejas Vipin --- .../gpu/drm/panel/panel-mantix-mlaf057we51.c | 79 +++ 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c index ea4a6bf6d35b..4db852ffb0f6 100644 --- a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c +++ b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c @@ -23,7 +23,7 @@ /* Manufacturer specific Commands send via DSI */ #define MANTIX_CMD_OTP_STOP_RELOAD_MIPI 0x41 -#define MANTIX_CMD_INT_CANCEL 0x4C +#define MANTIX_CMD_INT_CANCEL 0x4c Please move cleanups to separate patches LOL, in a previous patch series I had the upper-to-lowercase in a separate patch and someone yelled at me to do the opposite and squash it together [1]. It doesn't really matter too much to me, but given the previous feedback I've just been suggesting that Tejas squash it together with his conversions. I'm OK either way, though. Yeah it heavily depends on the rename, but I guess here it's fine to be applied as-is! Neil [1] https://lore.kernel.org/r/caa8ejpo4wzmpnjpnkht-_gje2taf_i_g+etajrgipmezppc...@mail.gmail.com -Doug
Re: [PATCH LATER 8/9] drm/meson: dw-hdmi: don't write power controller registers
On 30/07/2024 14:50, Jerome Brunet wrote: The HDMI phy has a power domain properly set in DT. Writing the power controller register directly from the hdmi driver is incorrect. The power domain framework should be used for that. HHI is a collection of Amlogic devices, such as clocks, reset, power domains and phys. This is another step to get rid of HHI access in Amlogic display drivers and possibly stop using the component API. Signed-off-by: Jerome Brunet --- This change depends on: * f1ab099d6591 ("arm64: dts: amlogic: add power domain to hdmitx") Time is needed for these changes to sink in u-boot and distros, making this change safe to apply. Well no, we will basically need to wait until none of the stable and long-stable kernel stops shipping a kernel without this change, but you can check if a power-domain have been associated with the device and do the same. drivers/gpu/drm/meson/meson_dw_hdmi.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index ef059c5ef520..6c18d97b8b16 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -111,7 +111,6 @@ #define HDMITX_TOP_G12A_OFFSET0x8000 /* HHI Registers */ -#define HHI_MEM_PD_REG00x100 /* 0x40 */ #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ #define HHI_HDMI_PHY_CNTL00x3a0 /* 0xe8 */ #define HHI_HDMI_PHY_CNTL10x3a4 /* 0xe9 */ @@ -423,9 +422,6 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) /* Enable clocks */ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0x, 0x100); - /* Bring HDMITX MEM output of power down */ - regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); - /* Bring out of reset */ regmap_write(meson_dw_hdmi->top, HDMITX_TOP_SW_RESET, 0); msleep(20);
Re: [PATCH 7/9] drm/meson: dw-hdmi: use matched data
On 30/07/2024 14:50, Jerome Brunet wrote: Using several string comparisons with if/else if/else clauses is fairly inefficient and does not scale well. Inefficient in which way ? speed ? code size ? It doesn't scale, but AFAIK Amlogic stopped using the Synopsys DWC controller after the G12B SoCs Use matched data to tweak the driver depending on the matched SoC instead. This leads to a very overcomplicated code I'll need some time to review and understand Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 209 +- 1 file changed, 139 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 7c39e5c99043..ef059c5ef520 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -125,8 +125,17 @@ #define HHI_HDMI_PHY_CNTL40x3b0 /* 0xec */ #define HHI_HDMI_PHY_CNTL50x3b4 /* 0xed */ +struct meson_dw_hdmi_speed { + const struct reg_sequence *regs; + unsigned int reg_num; + unsigned int limit; +}; + struct meson_dw_hdmi_data { int (*reg_init)(struct device *dev); + const struct meson_dw_hdmi_speed *speeds; + unsigned int speed_num; + bool use_drm_infoframe; u32 cntl0_init; u32 cntl1_init; }; @@ -185,78 +194,33 @@ struct meson_dw_hdmi { struct regmap *top; }; -static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, - const char *compat) -{ - return of_device_is_compatible(dw_hdmi->dev->of_node, compat); -} - -/* Bridge */ - /* Setup PHY bandwidth modes */ -static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, +static int meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, const struct drm_display_mode *mode, bool mode_is_420) { struct meson_drm *priv = dw_hdmi->priv; unsigned int pixel_clock = mode->clock; + int i; /* For 420, pixel clock is half unlike venc clock */ - if (mode_is_420) pixel_clock /= 2; - - if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || - dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { - if (pixel_clock >= 371250) { - /* 5.94Gbps, 3.7125Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); - } else if (pixel_clock >= 297000) { - /* 2.97Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); - } else if (pixel_clock >= 148500) { - /* 1.485Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); - } else { - /* 742.5Mbps, and below */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); - } - } else if (dw_hdmi_is_compatible(dw_hdmi, -"amlogic,meson-gxbb-dw-hdmi")) { - if (pixel_clock >= 371250) { - /* 5.94Gbps, 3.7125Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); - } else if (pixel_clock >= 297000) { - /* 2.97Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); - } else { - /* 1.485Gbps, and below */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); - } - } else if (dw_hdmi_is_compatible(dw_hdmi, -"amlogic,meson-g12a-dw-hdmi")) { - if (pixel_clock >= 371250) { - /* 5.94Gbps, 3.7125Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x080b); - } else if (pixel_clock >= 297000) { - /* 2.97Gbps */ - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); - regmap
Re: [PATCH 6/9] drm/meson: dw-hdmi: convert to regmap
On 30/07/2024 14:50, Jerome Brunet wrote: The Amlogic mixes direct register access and regmap ones, with several custom helpers. Using a single API makes rework and maintenance easier. Convert the Amlogic phy driver to regmap and use it to have more consistent access to the registers in the driver, with less custom helpers. Add register bit definitions when missing. Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 475 -- drivers/gpu/drm/meson/meson_dw_hdmi.h | 49 +-- 2 files changed, 239 insertions(+), 285 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 47aa3e184e98..7c39e5c99043 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -90,16 +90,25 @@ * - CEC Management */ -/* TOP Block Communication Channel */ -#define HDMITX_TOP_ADDR_REG0x0 -#define HDMITX_TOP_DATA_REG0x4 -#define HDMITX_TOP_CTRL_REG0x8 -#define HDMITX_TOP_G12A_OFFSET 0x8000 +/* Indirect channel definition for GX */ +#define HDMITX_TOP_REGS0x0 +#define HDMITX_DWC_REGS0x10 + +#define GX_ADDR_OFFSET 0x0 +#define GX_DATA_OFFSET 0x4 +#define GX_CTRL_OFFSET 0x8 I don't see the point renaming thos defines +#define GX_CTRL_APB3_ERRFAIL BIT(15) -/* Controller Communication Channel */ -#define HDMITX_DWC_ADDR_REG0x10 -#define HDMITX_DWC_DATA_REG0x14 -#define HDMITX_DWC_CTRL_REG0x18 +/* + * NOTE: G12 use direct addressing: + * Ideally it should receive one memory region for each of the top + * and dwc register regions but fixing this would require to change + * the DT bindings. Doing so is a pain. Keep the region as it and work + * around the problem, at least for now. + * Future supported SoCs should properly describe the regions in the + * DT bindings instead of using this trick. well I disagree here, there's a single memory region for the HDMITX module, and the DWC region is controlled by the TOP registers, so the DWC region _cannot_ be accessed without correctly configuring the TOP registers. So I disagree strongly with this comment. + */ +#define HDMITX_TOP_G12A_OFFSET 0x8000 /* HHI Registers */ #define HHI_MEM_PD_REG0 0x100 /* 0x40 */ @@ -108,28 +117,59 @@ #define HHI_HDMI_PHY_CNTL10x3a4 /* 0xe9 */ #define PHY_CNTL1_INIT 0x0390 #define PHY_INVERT BIT(17) +#define PHY_FIFOS GENMASK(3, 2) +#define PHY_CLOCK_EN BIT(1) +#define PHY_SOFT_RST BIT(0) Please move those changes before or after this patch #define HHI_HDMI_PHY_CNTL20x3a8 /* 0xea */ #define HHI_HDMI_PHY_CNTL30x3ac /* 0xeb */ #define HHI_HDMI_PHY_CNTL40x3b0 /* 0xec */ #define HHI_HDMI_PHY_CNTL50x3b4 /* 0xed */ -static DEFINE_SPINLOCK(reg_lock); - -struct meson_dw_hdmi; - struct meson_dw_hdmi_data { - unsigned int(*top_read)(struct meson_dw_hdmi *dw_hdmi, - unsigned int addr); - void(*top_write)(struct meson_dw_hdmi *dw_hdmi, -unsigned int addr, unsigned int data); - unsigned int(*dwc_read)(struct meson_dw_hdmi *dw_hdmi, - unsigned int addr); - void(*dwc_write)(struct meson_dw_hdmi *dw_hdmi, -unsigned int addr, unsigned int data); + int (*reg_init)(struct device *dev); u32 cntl0_init; u32 cntl1_init; }; +static int hdmi_tx_indirect_reg_read(void *context, +unsigned int reg, +unsigned int *result) +{ + void __iomem *base = context; + + /* Must write the read address twice ... */ + writel(reg, base + GX_ADDR_OFFSET); + writel(reg, base + GX_ADDR_OFFSET); + + /* ... and read the data twice as well */ + *result = readl(base + GX_DATA_OFFSET); + *result = readl(base + GX_DATA_OFFSET); Why did you change the comments ? + + return 0; +} + +static int hdmi_tx_indirect_reg_write(void *context, + unsigned int reg, + unsigned int val) +{ + void __iomem *base = context; + + /* Must write the read address twice ... */ + writel(reg, base + GX_ADDR_OFFSET); + writel(reg, base + GX_ADDR_OFFSET); + + /* ... but write the data only once */ + writel(val, base + GX_DATA_OFFSET); Ditto ? were they wrong ? + + return 0; +} + +static const struct regmap_bus hdmi_tx_indirect_mmio = { + .fast_io = true, + .reg_read = hdmi_tx_indirect_reg_read, + .reg_write = hdmi_tx_indirect_reg_write, +}; + struct meson_dw_hdmi { struct dw_hdmi_plat_data dw_plat_data; struct meson_drm *priv; @@ -139,9 +179,10 @@ struct meson_dw_hdmi {
Re: [PATCH 5/9] drm/meson: dw-hdmi: split resets out of hw init.
On 30/07/2024 14:50, Jerome Brunet wrote: This prepares the migration to regmap usage. To properly setup regmap, the APB needs to be in working order. This is easier handled if the resets are not mixed with hw init. More checks are required to determine if the resets are needed on resume or not. Add a note for this. Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 5cd3264ab874..47aa3e184e98 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -581,11 +581,6 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) /* Bring HDMITX MEM output of power down */ regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); - /* Reset HDMITX APB & TX & PHY */ - reset_control_reset(meson_dw_hdmi->hdmitx_apb); - reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); - reset_control_reset(meson_dw_hdmi->hdmitx_phy); - /* Enable APB3 fail on error */ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { writel_bits_relaxed(BIT(15), BIT(15), @@ -675,6 +670,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, return PTR_ERR(meson_dw_hdmi->hdmitx_phy); } + reset_control_reset(meson_dw_hdmi->hdmitx_apb); + reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); + reset_control_reset(meson_dw_hdmi->hdmitx_phy); + meson_dw_hdmi->hdmitx = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(meson_dw_hdmi->hdmitx)) return PTR_ERR(meson_dw_hdmi->hdmitx); @@ -765,6 +764,11 @@ static int __maybe_unused meson_dw_hdmi_pm_resume(struct device *dev) if (!meson_dw_hdmi) return 0; + /* TODO: Is this really necessary/desirable on resume ? */ Yes to reset the HDMI controller to it's default state, not sure if the note is important here. + reset_control_reset(meson_dw_hdmi->hdmitx_apb); + reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); + reset_control_reset(meson_dw_hdmi->hdmitx_phy); + meson_dw_hdmi_init(meson_dw_hdmi); dw_hdmi_resume(meson_dw_hdmi->hdmi);
Re: [PATCH 4/9] drm/meson: dw-hdmi: fix incorrect comment in suspend
On 30/07/2024 14:50, Jerome Brunet wrote: Comment in suspend says TOP is put in suspend, but the register poke following is actually de-asserting the reset, like in init. It is doing the opposite of what the comment says. Align the comment with what the code is doing for now and add a FIXME note to sort this out later Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 2890796f9d49..5cd3264ab874 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -751,7 +751,7 @@ static int __maybe_unused meson_dw_hdmi_pm_suspend(struct device *dev) if (!meson_dw_hdmi) return 0; - /* Reset TOP */ + /* FIXME: This actually bring top out reset on suspend, why ? */ meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_SW_RESET, 0); Yes, this is probably useless and should: meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_SW_RESET, 0x); but I think it can be safely removed. Neil
Re: [PATCH 0/2] drm/panel: simple: Add ON Tat Industrial Company KD50G21-40NT-A1 panel
Hi, On Fri, 16 Aug 2024 16:50:02 +0800, Liu Ying wrote: > This patch series aims at adding ON Tat Industrial Company KD50G21-40NT-A1 > 5" WVGA LCD panel support. The panel has a DPI interface. > > The LCD module specification can be found at: > https://cdn-shop.adafruit.com/datasheets/KD50G21-40NT-A1.pdf > > Liu Ying (2): > dt-bindings: display: panel-simple: Add On Tat Industrial Company > KD50G21-40NT-A1 > drm/panel: simple: Add ON Tat Industrial Company KD50G21-40NT-A1 panel > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] dt-bindings: display: panel-simple: Add On Tat Industrial Company KD50G21-40NT-A1 https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/773a0e3e89b354f14ec9ea8bddf3e86a602d162d [2/2] drm/panel: simple: Add ON Tat Industrial Company KD50G21-40NT-A1 panel https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/91a759d402b5c17263f82097c647e784f217e2d4 -- Neil
Re: [PATCH v3 0/2] Modify the method of sending "exit sleep
Hi, On Wed, 07 Aug 2024 18:04:27 +0800, Zhaoxiong Lv wrote: > This "exit sleep mode" and "set display on" command needs to > be sent in LP mode, so move "exit sleep mode" and "set display > on" command to the init() function. > > Modify the Melfas panel init code to satisfy the gamma value of 2.2. > > Changes between V3 and V2: > - PATCH 1/2: Modify the commit message and subject. > - PATCH 2/2: No changes. > - Link to v2: > https://lore.kernel.org/all/20240806034015.11884-1-lvzhaoxi...@huaqin.corp-partner.google.com/ > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] drm/panel: jd9365da: Move "exit sleep mode" and "set display on" cmds https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/97d1f449c359207b2fb5bc62eaefb7e21ad619ae [2/2] drm/panel: jd9365da: Modify the init code of Melfas https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/64ddf5123eff2edf47202e08744c3c14a9d28f59 -- Neil
Re: [PATCH v4 0/5] drm/panel: st7701: Add Anbernic RG28XX panel support
Hi, On Sun, 04 Aug 2024 15:14:44 +0900, Hironori KIKUCHI wrote: > Add support for the display panel of the Anbernic RG28XX, a handheld > gaming device from Anbernic. "RG28XX" is the actual name of the device. > > This panel is driven by a variant of the ST7701 driver IC internally, > and is connected via an RGB parallel interface for image transmission and > an SPI interface for configuration. > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/5] drm/panel: st7701: Rename macros https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/00b8a47d8ebe0419e649dc81b96033f6db6a4746 [2/5] drm/panel: st7701: Decouple DSI and DRM parts https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/a055c91ac6ea493c2508401537e8732dd2a7bbf8 [3/5] dt-bindings: display: st7701: Add Anbernic RG28XX panel https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/9a01fb40fda3de773eabd87d0d10f9c1f49ad581 [4/5] drm/panel: st7701: Add support for SPI for configuration https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/6a60273a0e8274820210abcfe7ec0d5f1f38f458 [5/5] drm/panel: st7701: Add Anbernic RG28XX panel support https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/f7c4a15225faeffe1e9f9a752097e7d85603ffef -- Neil
Re: [PATCH v2 0/2] drm/panel: simple: add Innolux G070ACE-LH3
Hi, On Mon, 29 Jul 2024 09:02:37 +0200, Steffen Trumtrar wrote: > This series adds support for the Innolux G070ACE-LH3 to the panel-simple > driver and adds the according compatible to the devicetree bindings. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] dt-bindings: display: simple: Document support for Innolux G070ACE-LH3 https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/99d79eacd1286bafbf5878a510b3ceb49360872c [2/2] drm/panel: simple: add Innolux G070ACE-LH3 LVDS display support https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/b9d228a5b2ebcb1f1f63170f5b20bc2f9d276168 -- Neil
Re: [PATCH 3/9] drm/meson: dw-hdmi: use generic clock helpers
On 30/07/2024 14:50, Jerome Brunet wrote: The Amlogic HDMI phy driver is not doing anything with the clocks besides enabling on probe. CCF provides generic helpers to do that. Use the generic clock helpers rather than using a custom one to get and enable clocks. Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 36 +++ 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index bcf4f83582f2..2890796f9d49 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -619,29 +619,6 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) } -static void meson_disable_clk(void *data) -{ - clk_disable_unprepare(data); -} - -static int meson_enable_clk(struct device *dev, char *name) -{ - struct clk *clk; - int ret; - - clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) { - dev_err(dev, "Unable to get %s pclk\n", name); - return PTR_ERR(clk); - } - - ret = clk_prepare_enable(clk); - if (!ret) - ret = devm_add_action_or_reset(dev, meson_disable_clk, clk); - - return ret; -} - static int meson_dw_hdmi_bind(struct device *dev, struct device *master, void *data) { @@ -651,6 +628,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, struct drm_device *drm = data; struct meson_drm *priv = drm->dev_private; struct dw_hdmi_plat_data *dw_plat_data; + struct clk_bulk_data *clks; int irq; int ret; @@ -701,17 +679,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, if (IS_ERR(meson_dw_hdmi->hdmitx)) return PTR_ERR(meson_dw_hdmi->hdmitx); - ret = meson_enable_clk(dev, "isfr"); - if (ret) - return ret; - - ret = meson_enable_clk(dev, "iahb"); + ret = devm_clk_bulk_get_all_enable(dev, &clks); if (ret) - return ret; - - ret = meson_enable_clk(dev, "venci"); - if (ret) - return ret; + return dev_err_probe(dev, ret, "Failed to enable all clocks\n"); dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, &meson_dw_hdmi_regmap_config); Reviewed-by: Neil Armstrong
Re: [PATCH 2/9] drm/meson: vclk: drop hdmi system clock setup
On 30/07/2024 14:50, Jerome Brunet wrote: Poking the HHI syscon is a way to setup clocks behind CCF's back. Also, 2 drm code paths, the encoder and the hdmi-phy, are racing to do the same setup of the HDMI system clock. This clock is used is used by the HDMI phy and should not be set by the encoder, so drop those HHI pokes from vclk. Signed-off-by: Jerome Brunet --- drivers/gpu/drm/meson/meson_vclk.c | 8 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index 2a942dc6a6dc..bf5cc5d92346 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -813,14 +813,6 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, { unsigned int m = 0, frac = 0; - /* Set HDMI-TX sys clock */ - regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, - CTS_HDMI_SYS_SEL_MASK, 0); - regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, - CTS_HDMI_SYS_DIV_MASK, 0); - regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, - CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN); - /* Set HDMI PLL rate */ if (!od1 && !od2 && !od3) { meson_hdmi_pll_generic_set(priv, pll_base_freq); Reviewed-by: Neil Armstrong
Re: [PATCH 1/9] drm/meson: hdmi: move encoder settings out of phy driver
writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP, + priv->io_base + _REG(VPU_HDMI_SETTING)); } static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge, @@ -257,6 +271,8 @@ static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge, writel_bits_relaxed(0x3, 0, priv->io_base + _REG(VPU_HDMI_SETTING)); + writel_bits_relaxed(0xf << 8, 0, + priv->io_base + _REG(VPU_HDMI_SETTING)); writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); Nice usage of the split bridge architecture! Now we must make sure the atomic enable order doesn't change... Reviewed-by: Neil Armstrong
Re: [PATCH v2 2/2] drm/panel: simple: add Innolux G070ACE-LH3 LVDS display support
On 29/07/2024 09:02, Steffen Trumtrar wrote: The G070ACE-LH3 is a 7" TFT Color LCD module with WLED backlight. https://www.data-modul.com/sites/default/files/products/G070ACE-LH3-specification-12058417.pdf Signed-off-by: Steffen Trumtrar --- drivers/gpu/drm/panel/panel-simple.c | 35 +++ 1 file changed, 35 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index dcb6d0b6ced06..d3200dd035662 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2509,6 +2509,38 @@ static const struct panel_desc innolux_g070y2_l01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing innolux_g070ace_lh3_timing = { + .pixelclock = { 2520, 2540, 3570 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 30, 32, 87 }, + .hback_porch = { 29, 31, 86 }, + .hsync_len = { 1, 1, 1 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 4, 5, 65 }, + .vback_porch = { 3, 4, 65 }, + .vsync_len = { 1, 1, 1 }, + .flags = DISPLAY_FLAGS_DE_HIGH, +}; + +static const struct panel_desc innolux_g070ace_lh3 = { + .timings = &innolux_g070ace_lh3_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 152, + .height = 91, + }, + .delay = { + .prepare = 10, + .enable = 450, + .disable = 200, + .unprepare = 510, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode innolux_g070y2_t02_mode = { .clock = 3, .hdisplay = 800, @@ -4599,6 +4631,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "innolux,g070ace-l01", .data = &innolux_g070ace_l01, + }, { + .compatible = "innolux,g070ace-lh3", + .data = &innolux_g070ace_lh3, }, { .compatible = "innolux,g070y2-l01", .data = &innolux_g070y2_l01, Reviewed-by: Neil Armstrong
Re: [PATCH v3 1/2] drm/panel: jd9365da: Move "exit sleep mode" and "set display on" cmds
On 12/08/2024 17:45, Doug Anderson wrote: Jessica, On Thu, Aug 8, 2024 at 3:56 PM Jessica Zhang wrote: On 8/7/2024 3:04 AM, Zhaoxiong Lv wrote: Move the "exit sleep mode" and "set display on" command from enable() to init() function. As mentioned in the patch: https://lore.kernel.org/all/20240624141926.5250-2-lvzhaoxi...@huaqin.corp-partner.google.com/ The Mediatek Soc DSI host has different modes in prepare() and enable() functions, prepare() is in LP mode and enable() is in HS mode. Since the "exit sleep mode" and "set display on" command must also be sent in LP mode, so we also move "exit sleep mode" and "set display on" command to the init() function. We have no other actions in the enable() function after moves "exit sleep mode" and "set display on", and we checked the call of the enable() function during the "startup" process. It seems that only one judgment was made in drm_panel_enabel(). If the panel does not define enable(), the judgment will skip the enable() and continue execution. This does not seem to have any other effect, and we found that some drivers also seem to have no enable() function added, for example: panel-asus-z00t-tm5p5-n35596 / panel-boe-himax8279d... In addition, we briefly tested the kingdisplay_kd101ne3 panel and melfas_lmfbx101117480 panel, and it seems that there is no garbage on the panel, so we delete enable() function. After moving the "exit sleep mode" and "set display on" command to the init() function, we no longer need additional delay judgment, so we delete variables "exit_sleep_to_display_on_delay_ms" and "display_on_delay_ms". Reviewed-by: Douglas Anderson Signed-off-by: Zhaoxiong Lv Acked-by: Jessica Zhang Does this Ack mean you're confident enough about this patch that we should go ahead and merge it, or do you think we should wait on anything else (like Neil getting a chance to look at it)? As I mentioned in my reply to the cover letter [1] the patches look OK to me but I still don't consider myself to have a wonderful understanding of the intricacies of MIPI DSI. If you think this is OK from a MIPI DSI point of view then we can land it... I don't have an advanced MIPI DSI knowledge, but they simple remove unneeded sleeps between dcs commands, so if they are confident they can be removed I agree... Neil [1] https://lore.kernel.org/r/CAD=FV=WCw6pAump-PUFCW0cgbRY+5_2tPNLe=hN3-dnXD=b...@mail.gmail.com Thanks! -Doug
Re: [PATCH] drm/panel: ili9341: Add comments for ILI9341 register
On 12/08/2024 19:10, Abhishek Tamboli wrote: TODO : Add missing comments for ILI9341 register definition. Please rephrase the commit message, and explain why in a proper english sentence. Neil Signed-off-by: Abhishek Tamboli --- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 775d5d5e828c..cba6a6952568 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -121,19 +121,19 @@ struct ili9341_config { const struct drm_display_mode mode; /* ca: TODO: need comments for this register */ u8 ca[ILI9341_CA_LEN]; - /* power_b: TODO: need comments for this register */ + /* power_b: Power control B (CFh) */ u8 power_b[ILI9341_POWER_B_LEN]; - /* power_seq: TODO: need comments for this register */ + /* pdtcaower_seq: Power on sequence control (EDh) */ u8 power_seq[ILI9341_POWER_SEQ_LEN]; - /* dtca: TODO: need comments for this register */ + /* dtca: Driver timing control A (E8h) */ u8 dtca[ILI9341_DTCA_LEN]; - /* dtcb: TODO: need comments for this register */ + /* dtcb: Driver timing control B (EAh) */ u8 dtcb[ILI9341_DTCB_LEN]; - /* power_a: TODO: need comments for this register */ + /* power_a: Power control A (CBh) */ u8 power_a[ILI9341_POWER_A_LEN]; /* frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */ u8 frc[ILI9341_FRC_LEN]; - /* prc: TODO: need comments for this register */ + /* prc: Pump ratio control (F7h) */ u8 prc; /* dfc_1: B6h DISCTRL (Display Function Control) */ u8 dfc_1[ILI9341_DFC_1_LEN]; @@ -147,7 +147,7 @@ struct ili9341_config { u8 vcom_2; /* address_mode: Memory Access Control (36h) */ u8 address_mode; - /* g3amma_en: TODO: need comments for this register */ + /* g3amma_en: Enable 3G (F2h) */ u8 g3amma_en; /* rgb_interface: RGB Interface Signal Control (B0h) */ u8 rgb_interface; -- 2.34.1
Re: [PATCH 31/86] drm/panel/ili9341: Run DRM default client setup
On 16/08/2024 14:22, Thomas Zimmermann wrote: Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. Signed-off-by: Thomas Zimmermann Cc: Neil Armstrong Cc: Jessica Zhang --- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 775d5d5e828c..0ef9f7b59ccb 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -591,6 +592,7 @@ static struct drm_driver ili9341_dbi_driver = { .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ili9341_dbi_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "ili9341", .desc = "Ilitek ILI9341", @@ -651,7 +653,7 @@ static int ili9341_dbi_probe(struct spi_device *spi, struct gpio_desc *dc, spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } So which one is right, this one or : https://lore.kernel.org/all/20240813091258.1625646-1-andriy.shevche...@linux.intel.com/ ? Neil
Re: [PATCH 2/2] drm/panel: simple: Add ON Tat Industrial Company KD50G21-40NT-A1 panel
On 16/08/2024 10:50, Liu Ying wrote: ON Tat Industrial Company KD50G21-40NT-A1 is a 5" WVGA LCD panel with DPI interface. The LCD module specification can be found at: https://cdn-shop.adafruit.com/datasheets/KD50G21-40NT-A1.pdf Signed-off-by: Liu Ying --- drivers/gpu/drm/panel/panel-simple.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index bf40057c5cf3..89963df80917 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3478,6 +3478,39 @@ static const struct panel_desc olimex_lcd_olinuxino_43ts = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; +static const struct display_timing ontat_kd50g21_40nt_a1_timing = { + .pixelclock = { 3000, 3000, 5000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 1, 40, 255 }, + .hback_porch = { 1, 40, 87 }, + .hsync_len = { 1, 48, 87 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 1, 13, 255 }, + .vback_porch = { 1, 29, 29 }, + .vsync_len = { 3, 3, 31 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | +DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static const struct panel_desc ontat_kd50g21_40nt_a1 = { + .timings = &ontat_kd50g21_40nt_a1_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 108, + .height = 65, + }, + .delay = { + .prepare = 147, /* 5 VSDs */ + .enable = 147, /* 5 VSDs */ + .disable = 88, /* 3 VSDs */ + .unprepare = 117, /* 4 VSDs */ + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + /* * 800x480 CVT. The panel appears to be quite accepting, at least as far as * pixel clocks, but this is the timing that was being used in the Adafruit @@ -4837,6 +4870,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "olimex,lcd-olinuxino-43-ts", .data = &olimex_lcd_olinuxino_43ts, + }, { + .compatible = "ontat,kd50g21-40nt-a1", + .data = &ontat_kd50g21_40nt_a1, }, { .compatible = "ontat,yx700wv03", .data = &ontat_yx700wv03, Reviewed-by: Neil Armstrong