Re: [PATCH V3 drm-dp 4/4] drm/hisilicon/hibmc: add dp module in hibmc
On Fri, Nov 01, 2024 at 06:50:28PM +0800, Yongbang Shi wrote: > From: baihan li > > To support DP interface displaying in hibmc driver. Add > a encoder and connector for DP modual. > > Signed-off-by: baihan li > Signed-off-by: yongbang shi > --- > ChangeLog: > v2 -> v3: > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410251136.1m7blr68-...@intel.com/ > v1 -> v2: > - deleting struct dp_mode and dp_mode_cfg function, suggested by Dmitry > Baryshkov. > - modifying drm_simple_encoder_init function, suggested by Dmitry Baryshkov. > - refactoring struct hibmc_connector, suggested by Dmitry Baryshkov. > - withdrawing the modification in hibmc_kms_init, suggested by Dmitry > Baryshkov. > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c| 128 ++ > .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 16 +++ > .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 21 +-- > .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 41 +++--- > .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 20 +-- > 6 files changed, 188 insertions(+), 40 deletions(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 214228052ccf..95a4ed599d98 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o dp/dp_link.o dp/dp_hw.o > +dp/dp_aux.o dp/dp_link.o dp/dp_hw.o hibmc_drm_dp.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > new file mode 100644 > index ..1e0f2ef39ba6 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c > @@ -0,0 +1,128 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "hibmc_drm_drv.h" > +#include "dp/dp_hw.h" > + > +static int hibmc_dp_connector_get_modes(struct drm_connector *connector) > +{ > + int count; > + > + count = drm_add_modes_noedid(connector, > connector->dev->mode_config.max_width, > + connector->dev->mode_config.max_height); > + drm_set_preferred_mode(connector, 1024, 768); // temporary > implementation > + > + return count; > +} > + > +static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = { > + .get_modes = hibmc_dp_connector_get_modes, > +}; > + > +static const struct drm_connector_funcs hibmc_dp_conn_funcs = { > + .reset = drm_atomic_helper_connector_reset, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .destroy = drm_connector_cleanup, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > +}; > + > +static int hibmc_dp_prepare(struct hibmc_dp *dp, struct drm_display_mode > *mode) inline at the calling site > +{ > + int ret; > + > + hibmc_dp_display_en(dp, false); > + > + ret = hibmc_dp_mode_set(dp, mode); > + if (ret) > + drm_err(dp->drm_dev, "hibmc dp mode set failed: %d\n", ret); > + > + return ret; > +} > + > +static void hibmc_dp_encoder_enable(struct drm_encoder *drm_encoder, > + struct drm_atomic_state *state) > +{ > + struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, > encoder); > + struct drm_display_mode *mode = &drm_encoder->crtc->state->mode; > + > + if (hibmc_dp_prepare(dp, mode)) > + return; > + > + hibmc_dp_display_en(dp, true); > +} > + > +static void hibmc_dp_encoder_disable(struct drm_encoder *drm_encoder, > + struct drm_atomic_state *state) > +{ > + struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, > encoder); > + > + hibmc_dp_display_en(dp, false); > +} > + > +static const struct drm_encoder_helper_funcs hibmc_dp_encoder_helper_funcs = > { > + .atomic_enable = hibmc_dp_enc
Re: [PATCH V3 drm-dp 3/4] drm/hisilicon/hibmc: add dp hw moduel in hibmc
On Fri, Nov 01, 2024 at 06:50:27PM +0800, Yongbang Shi wrote: > From: baihan li > > Build a dp level that hibmc driver can enable dp by > calling their functions. > > Signed-off-by: baihan li > Signed-off-by: yongbang shi > --- > ChangeLog: > v2 -> v3: > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410250931.udq9s66h-...@intel.com/ > v1 -> v2: > - changed some defines and functions to former patch, suggested by Dmitry > Baryshkov. > - sorting the headers including in dp_hw.h and hibmc_drm_drv.c files, > suggested by Dmitry Baryshkov. > - deleting struct dp_mode and dp_mode_cfg function, suggested by Dmitry > Baryshkov. > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410040328.vevxm9yb-...@intel.com/ > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile| 2 +- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 237 > drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 31 +++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 41 > 4 files changed, 310 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 94d77da88bbf..214228052ccf 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o dp/dp_link.o > +dp/dp_aux.o dp/dp_link.o dp/dp_hw.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c > new file mode 100644 > index ..214897798bdb > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c > @@ -0,0 +1,237 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > +#include > +#include "dp_config.h" > +#include "dp_comm.h" > +#include "dp_reg.h" > +#include "dp_hw.h" > +#include "dp_link.h" > +#include "dp_aux.h" > + > +static int hibmc_dp_link_init(struct dp_dev *dp) > +{ > + dp->link.cap.lanes = 2; > + dp->link.train_set = devm_kzalloc(dp->dev->dev, > + dp->link.cap.lanes * sizeof(u8), > GFP_KERNEL); Can you replace it just with an array, removing a need for an additional allocation? > + if (!dp->link.train_set) > + return -ENOMEM; > + > + dp->link.cap.link_rate = 1; Ok, this is why I don't link using indices for link rates. Which rate is this? Unlike cap.lanes this is pure magic number. I think it should be handled other way around: store actual link rate and convert to the register value when required. > + > + return 0; > +} > + > +static void hibmc_dp_set_tu(struct dp_dev *dp, struct drm_display_mode *mode) > +{ > + u32 tu_symbol_frac_size; > + u32 tu_symbol_size; > + u32 rate_ks; > + u8 lane_num; > + u32 value; > + u32 bpp; > + > + lane_num = dp->link.cap.lanes; > + if (lane_num == 0) { > + drm_err(dp->dev, "set tu failed, lane num cannot be 0!\n"); > + return; > + } > + > + bpp = DP_BPP; Where is this defined? Is it hibmc-specific or a generic value? > + rate_ks = hibmc_dp_get_link_rate(dp->link.cap.link_rate) * > DP_LINK_RATE_CAL; same question > + value = (mode->clock * bpp * 5) / (61 * lane_num * rate_ks); > + > + if (value % 10 == 9) { /* 9 carry */ > + tu_symbol_size = value / 10 + 1; > + tu_symbol_frac_size = 0; > + } else { > + tu_symbol_size = value / 10; > + tu_symbol_frac_size = value % 10 + 1; > + } > + > + drm_info(dp->dev, "tu value: %u.%u value: %u\n", > + tu_symbol_size, tu_symbol_frac_size, value); > + > + dp_reg_write_field(dp->base + DP_VIDEO_PACKET, > +DP_CFG_STREAM_TU_SYMBOL_SIZE, tu_symbol_size); > + dp_reg_write_field(dp->base + DP_VIDEO_PACKET, > +DP_CFG_STREAM_TU_SYMBOL_FRAC_SIZE, > tu_symbol_frac_size); > +} > + > +static void hibmc_dp_set_sst(st
Re: [PATCH V3 drm-dp 2/4] drm/hisilicon/hibmc: add dp link moduel in hibmc
On Fri, Nov 01, 2024 at 06:50:26PM +0800, Yongbang Shi wrote: > From: baihan li > > Add link training process functions in this moduel. > > Signed-off-by: baihan li > Signed-off-by: yongbang shi > --- > Changelog: > v2 -> v3: > - using switchcase in dp_link_reduce_lane, suggested by Dmitry Baryshkov. > - deleting dp_link_pattern2dpcd function and using macros directly, > suggested by Dmitry Baryshkov. > - deleting EFAULT error codes, suggested by Dmitry Baryshkov. > v1 -> v2: > - using drm_dp_* functions implement dp link training process, suggested by > Jani Nikula. > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410031735.8irzzr6t-...@intel.com/ > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 346 +++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h | 25 ++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 8 + > 4 files changed, 380 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 8770ec6dfffd..94d77da88bbf 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o > +dp/dp_aux.o dp/dp_link.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > new file mode 100644 > index ..7146de020c93 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > @@ -0,0 +1,346 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > +#include > +#include > +#include "dp_comm.h" > +#include "dp_reg.h" > +#include "dp_link.h" > +#include "dp_aux.h" > + > +const u8 link_rate_map[] = {DP_LINK_BW_1_62, DP_LINK_BW_2_7, > + DP_LINK_BW_5_4, DP_LINK_BW_8_1}; hibmc_dp_link_rate_map[] > + > +static int hibmc_dp_link_training_configure(struct dp_dev *dp) > +{ > + u8 buf[2]; > + int ret; > + > + /* DP 2 lane */ > + dp_reg_write_field(dp->base + DP_PHYIF_CTRL0, DP_CFG_LANE_DATA_EN, > +dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x3 : 0x1); > + dp_reg_write_field(dp->base + DP_DPTX_GCTL0, DP_CFG_PHY_LANE_NUM, > +dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x1 : 0); > + > + /* enhanced frame */ > + dp_reg_write_field(dp->base + DP_VIDEO_CTRL, DP_CFG_STREAM_FRAME_MODE, > 0x1); > + > + /* set rate and lane count */ > + buf[0] = hibmc_dp_get_link_rate(dp->link.cap.link_rate); > + buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes; > + ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); > + if (ret != sizeof(buf)) { > + drm_dbg_dp(dp->dev, "dp aux write link rate and lanes failed, > ret: %d\n", ret); > + return ret >= 0 ? -EIO : ret; > + } > + > + /* set 8b/10b and downspread */ > + buf[0] = 0x10; > + buf[1] = 0x1; > + ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, sizeof(buf)); > + if (ret != sizeof(buf)) { > + drm_dbg_dp(dp->dev, "dp aux write 8b/10b and downspread failed, > ret: %d\n", ret); > + return ret >= 0 ? -EIO : ret; > + } > + > + ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd); > + if (ret) > + drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); > + > + return ret; > +} > + > +static int hibmc_dp_link_set_pattern(struct dp_dev *dp, int pattern) > +{ > + int ret; > + u8 val; > + u8 buf; > + > + buf = (u8)pattern; > + if (pattern != DP_TRAINING_PATTERN_DISABLE && pattern != > DP_TRAINING_PATTERN_4) { > + buf |= DP_LINK_SCRAMBLING_DISABLE; > + dp_reg_write_field(dp->base + DP_PHYIF_CTRL0, > DP_CFG_SCRAMBLE_EN, 0x1); > + } else { > + dp_reg_write_field(dp->base + DP_PHYIF_CTRL0, > DP_CFG_SCRAMBLE_EN, 0); > +
Re: [PATCH V3 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc
On Fri, Nov 01, 2024 at 06:50:25PM +0800, Yongbang Shi wrote: > From: baihan li > > Add dp aux read/write functions. They are basic functions > and will be used later. > > Signed-off-by: baihan li > Signed-off-by: yongbang shi Is this a proper capitalization of your names? Usually the first letter of each of them is capital. > --- > ChangeLog: > v2 -> v3: > - put the macro definations in latter patch where they are actually used, > suggested by Dmitry Baryshkov. > - rename some macro definations to make them sensible, suggested by Dmitry > Baryshkov. > - using FIELD_PREP and FIELD_GET, suggested by Dmitry Baryshkov. > - using DP_DPCD_REV_foo, suggested by Dmitry Baryshkov. > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410250305.uhkdhtxy-...@intel.com/ > v1 -> v2: > - using drm_dp_aux frame implement dp aux read and write functions, > suggested by Jani Nikula. > - using drm dp header files' dp macros instead, suggested by Andy Yan. > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 3 +- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c | 162 ++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.h | 23 +++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 58 +++ > .../gpu/drm/hisilicon/hibmc/dp/dp_config.h| 19 ++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 27 +++ > 6 files changed, 291 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index d25c75e60d3d..8770ec6dfffd 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,4 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o > +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > +dp/dp_aux.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > new file mode 100644 > index ..49ecda672109 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > @@ -0,0 +1,162 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > +#include > +#include > +#include > +#include > +#include "dp_comm.h" > +#include "dp_reg.h" > +#include "dp_aux.h" > + > +#define DP_MIN_PULSE_NUM 0x9 > + > +static void hibmc_dp_aux_reset(const struct dp_dev *dp) > +{ > + dp_reg_write_field(dp->base + DP_DPTX_RST_CTRL, DP_CFG_AUX_RST_N, 0x0); > + usleep_range(10, 15); > + dp_reg_write_field(dp->base + DP_DPTX_RST_CTRL, DP_CFG_AUX_RST_N, 0x1); > +} > + > +static void hibmc_dp_aux_read_data(struct dp_dev *dp, u8 *buf, u8 size) > +{ > + u32 reg_num; > + u32 value; > + u32 num; > + u8 i, j; > + > + reg_num = DIV_ROUND_UP(size, BYTES_IN_U32); > + for (i = 0; i < reg_num; i++) { > + /* number of bytes read from a single register */ > + num = min(size - i * BYTES_IN_U32, BYTES_IN_U32); > + value = readl(dp->base + DP_AUX_RD_DATA0 + i * BYTES_IN_U32); > + /* convert the 32-bit value of the register to the buffer. */ > + for (j = 0; j < num; j++) > + buf[i * BYTES_IN_U32 + j] = value >> (j * BITS_IN_U8); put_unaligned_le32() > + } > +} > + > +static void hibmc_dp_aux_write_data(struct dp_dev *dp, u8 *buf, u8 size) > +{ > + u32 reg_num; > + u32 value; > + u8 i, j; > + u32 num; > + > + reg_num = DIV_ROUND_UP(size, BYTES_IN_U32); > + for (i = 0; i < reg_num; i++) { > + /* number of bytes written to a single register */ > + num = min_t(u8, size - i * BYTES_IN_U32, BYTES_IN_U32); > + value = 0; > + /* obtain the 32-bit value written to a single register. */ > + for (j = 0; j < num; j++) > + value |= buf[i * BYTES_IN_U32 + j] << (j * BITS_IN_U8); get_unaligned_le32()
Re: [PATCH RESEND v9 1/2] drm/atomic: Let drivers decide which planes to async flip
On Fri, Nov 01, 2024 at 03:23:47PM -0300, André Almeida wrote: > Currently, DRM atomic uAPI allows only primary planes to be flipped > asynchronously. However, each driver might be able to perform async > flips in other different plane types. To enable drivers to set their own > restrictions on which type of plane they can or cannot flip, use the > existing atomic_async_check() from struct drm_plane_helper_funcs to > enhance this flexibility, thus allowing different plane types to be able > to do async flips as well. > > In order to prevent regressions and such, we keep the current policy: we > skip the driver check for the primary plane, because it is always > allowed to do async flips on it. > > Signed-off-by: André Almeida > --- > Changes from v8: > - Rebased on top of 6.12-rc1 > --- > drivers/gpu/drm/drm_atomic_uapi.c | 39 > +-- > 1 file changed, 29 insertions(+), 10 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v2 2/3] drm/sysfs: Remove device type drm_sysfs_device_minor
On Sat, Nov 02, 2024 at 10:47:25PM +0100, Heiner Kallweit wrote: > Only user of this device type was struct dev_pm_ops of drm_class which > was removed in d14d2a8453d6 ("drm: Remove dev_pm_ops from drm_class"). > So remove this now unused device type. > > Signed-off-by: Heiner Kallweit > --- > drivers/gpu/drm/drm_sysfs.c | 5 - > 1 file changed, 5 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v2 3/3] drm/sysfs: Constify struct drm_sysfs_device_connector
On Sat, Nov 02, 2024 at 10:48:42PM +0100, Heiner Kallweit wrote: > Constify struct drm_sysfs_device_connector to eliminate the risk of code > trying to change it. > > Signed-off-by: Heiner Kallweit > --- > drivers/gpu/drm/drm_sysfs.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
[PATCH] drm/msm/dpu: rework documentation comments
Unfortunately the tooling doesn't check documents placed before funciton prototypes. Such comments frequently become outdated, miss several params, etc. Move documentation for the functions to be placed before the actual function body, allowing 'make W=1' to actually check these comments and report an error. Signed-off-by: Dmitry Baryshkov --- The documentation can further be improved, but let's move the comments now, close to the end of the development window, reducing the risk of the possible conflicts. --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 46 -- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 23 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 27 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 31 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 38 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 179 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h| 105 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 90 --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 6 + .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 6 + drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c| 11 +- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h| 7 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 8 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h | 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 9 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 9 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c| 8 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h| 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 52 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 8 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 7 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c | 8 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h | 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c| 9 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h| 9 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c| 9 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 9 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c| 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h| 7 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 8 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 22 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h| 34 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 26 --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 46 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 38 - drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 13 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h | 18 --- 47 files changed, 502 insertions(+), 543 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index 7c286bafb948d1b797d1837074f27549f8f3dd06..e7183cf057768f7a2c892b1e9c88d8996421049f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -8,72 +8,26 @@ #include "dpu_kms.h" #include "dpu_hw_interrupts.h" -/** - * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler - * @kms: MSM KMS handle - * @return:none - */ void dpu_core_irq_preinstall(struct msm_kms *kms); -/** - * dpu_core_irq_uninstall - uninstall core IRQ handler - * @kms: MSM KMS handle - * @return:none - */ void dpu_core_irq_uninstall(struct msm_kms *kms); -/** - * dpu_core_irq - core IRQ handler - * @kms: MSM KMS handle - * @return:interrupt handling status - */ irqreturn_t dpu_core_irq(struct msm_kms *kms); -/** - * dpu_core_irq_read - IRQ helper function for reading IRQ status - * @dpu_kms: DPU handle - * @irq_idx: irq index - * @return:non-zero if irq detected; otherwise no irq detected - */ u32 dpu_core_irq_read( struct dpu_kms *dpu_kms, unsigned int irq_idx); -/** - * dpu_core_irq_register_callback - For registering callback function on IRQ - * interrupt - * @dpu_kms: DPU handle - * @irq_idx:
Re: [PATCH v6 0/9] drm/msm/dpu: support virtual wide planes
On Fri, 25 Oct 2024 03:20:07 +0300, Dmitry Baryshkov wrote: > As promised in the basic wide planes support ([1]) here comes a series > supporting 2*max_linewidth for all the planes. > > Note: Unlike v1 and v2 this series finally includes support for > additional planes - having more planes than the number of SSPP blocks. > > Note: this iteration features handling of rotation and reflection of the > wide plane. However rot90 is still not tested: it is enabled on sc7280 > and it only supports UBWC (tiled) framebuffers, it was quite low on my > priority list. > > [...] Applied, thanks! After additional consideration, apply only basic patches, leaving the virtual planes enablement into the 6.14 material in order to be able to get more testing for those patches. [1/9] drm/msm/dpu: use drm_rect_fp_to_int() https://gitlab.freedesktop.org/lumag/msm/-/commit/5002c44c [2/9] drm/msm/dpu: move pstate->pipe initialization to dpu_plane_atomic_check https://gitlab.freedesktop.org/lumag/msm/-/commit/31f7148fd370 [3/9] drm/msm/dpu: drop virt_formats from SSPP subblock configuration https://gitlab.freedesktop.org/lumag/msm/-/commit/b96ca23fdd03 [4/9] drm/msm/dpu: move scaling limitations out of the hw_catalog https://gitlab.freedesktop.org/lumag/msm/-/commit/8f15005783b8 [5/9] drm/msm/dpu: split dpu_plane_atomic_check() https://gitlab.freedesktop.org/lumag/msm/-/commit/dbbf57dfd04e [6/9] drm/msm/dpu: move rot90 checking to dpu_plane_atomic_check_sspp() https://gitlab.freedesktop.org/lumag/msm/-/commit/ab52d2717ac0 Best regards, -- Dmitry Baryshkov
Re: [PATCH 0/4] drm/msm/mdss: rework UBWC registers programming
On Sat, 21 Sep 2024 11:17:28 +0300, Dmitry Baryshkov wrote: > Current way of programming of the UBWC-related registers has been > inherited from vendor's drivers. The ubwc_static was supposed to contain > raw data to be programmed to the hardware, but was later repurposed to > define of the bits. As it can be seen by the commit 3e30296b374a > ("drm/msm: fix the highest_bank_bit for sc7180") sometimes this data > gets out of sync. > > [...] Applied, thanks! [1/4] drm/msm: move MDSS registers to separate header file https://gitlab.freedesktop.org/lumag/msm/-/commit/92de8137d619 [2/4] drm/msm/mdss: use register definitions instead of hand-coding them https://gitlab.freedesktop.org/lumag/msm/-/commit/d742f7e06840 Best regards, -- Dmitry Baryshkov
Re: [PATCH] drm/msm/hdmi: mark interlace_allowed as true
On Fri, Nov 01, 2024 at 05:40:46PM -0700, Abhinav Kumar wrote: > > > On 11/1/2024 3:26 PM, Dmitry Baryshkov wrote: > > On Fri, 1 Nov 2024 at 23:41, Abhinav Kumar > > wrote: > > > > > > > > > > > > On 10/18/2024 2:10 PM, Dmitry Baryshkov wrote: > > > > The MSM HDMI driver supports interlaced modes. Set the corresponding > > > > flag to allow interlaced modes on the corresponding connectors. > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > --- > > > >drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 1 + > > > >1 file changed, 1 insertion(+) > > > > > > > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > > > b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > > > index 4a5b5112227f..643c152e6380 100644 > > > > --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > > > @@ -336,6 +336,7 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi) > > > >bridge->funcs = &msm_hdmi_bridge_funcs; > > > >bridge->ddc = hdmi->i2c; > > > >bridge->type = DRM_MODE_CONNECTOR_HDMIA; > > > > + bridge->interlace_allowed = true; > > > >bridge->ops = DRM_BRIDGE_OP_HPD | > > > >DRM_BRIDGE_OP_DETECT | > > > >DRM_BRIDGE_OP_EDID; > > > > > > > > > > I had quite a bit of discussion on this internally because this spans > > > quite a few generations of chipsets. > > > > > > On very old hardware, even before msm8996, there was dedicated hardware > > > de-interlacer. But even on msm8996 or other HDMI supported chipsets > > > where the handling of if (mode->flags & DRM_MODE_FLAG_INTERLACE) is > > > present, these were because its carry forward of older interface code. > > > > > > The way we handle interlaced formats today, is software needs to handle > > > the part of dividing height / 2 and width * 2 and adjust the source crop > > > if necessary. This part has moved to userspace for recent chips. > > > > > > Othwerise, we will need to add this part in the dpu driver to adjust > > > this. I am not seeing this part there yet. So may I know how you > > > validated this change? Something similar to : > > > > > > https://git.codelinaro.org/clo/la/kernel/msm-4.4/-/blob/caf_migration/LE.UM.1.3.r3.25/drivers/gpu/drm/msm/sde/sde_plane.c#L1340 > > > > > > If we add this part first to dpu code, then we can mark interlace_allowed. > > > > I think you are mixing the interlaced formats and interlaced output. > > The code that you have pointed to is related to hardware deinterlacing > > - in other words taking the interlaced framebuffer and outputting it > > to the progressive display. > > > > The interlace_allowed flag controls a different feature - filtering of > > the internalced modes (aka 576i, 1080i, etc). In this case we are > > using progressive frames, but the HDMI outputs a picture as two > > separate fields. I have validated this by outputting image (modetest) > > to the external HDMI display on IFC6410 and on DB820c boards. > > > > Yes I did think that this was to show interlaced content but that being > said, I traced through the HDMI code a bit, it does have support for > changing the HDMI timing but without the support of dpu, progressive content > really cannot be converted to interlaced. So I think the HDMI pieces there > were supposed to go along with the rest of the dpu pipeline that is the > entire pipeline shows out interlaced content. But dpu support for giving out > interlaced content is not there, so this hdmi piece by itself is not > complete enough to mark interlace_allowed as true. I could not find corresponding bits in the original fbdev or SDE drivers. My quick tests showed the correct context, but most likely I need to revertify that. Unfortunately next week I won't be able to run the tests, so this gets into the 6.14 area. -- With best wishes Dmitry
Re: [PATCH] drm/msm/hdmi: mark interlace_allowed as true
On Fri, 1 Nov 2024 at 23:41, Abhinav Kumar wrote: > > > > On 10/18/2024 2:10 PM, Dmitry Baryshkov wrote: > > The MSM HDMI driver supports interlaced modes. Set the corresponding > > flag to allow interlaced modes on the corresponding connectors. > > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > index 4a5b5112227f..643c152e6380 100644 > > --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c > > @@ -336,6 +336,7 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi) > > bridge->funcs = &msm_hdmi_bridge_funcs; > > bridge->ddc = hdmi->i2c; > > bridge->type = DRM_MODE_CONNECTOR_HDMIA; > > + bridge->interlace_allowed = true; > > bridge->ops = DRM_BRIDGE_OP_HPD | > > DRM_BRIDGE_OP_DETECT | > > DRM_BRIDGE_OP_EDID; > > > > I had quite a bit of discussion on this internally because this spans > quite a few generations of chipsets. > > On very old hardware, even before msm8996, there was dedicated hardware > de-interlacer. But even on msm8996 or other HDMI supported chipsets > where the handling of if (mode->flags & DRM_MODE_FLAG_INTERLACE) is > present, these were because its carry forward of older interface code. > > The way we handle interlaced formats today, is software needs to handle > the part of dividing height / 2 and width * 2 and adjust the source crop > if necessary. This part has moved to userspace for recent chips. > > Othwerise, we will need to add this part in the dpu driver to adjust > this. I am not seeing this part there yet. So may I know how you > validated this change? Something similar to : > > https://git.codelinaro.org/clo/la/kernel/msm-4.4/-/blob/caf_migration/LE.UM.1.3.r3.25/drivers/gpu/drm/msm/sde/sde_plane.c#L1340 > > If we add this part first to dpu code, then we can mark interlace_allowed. I think you are mixing the interlaced formats and interlaced output. The code that you have pointed to is related to hardware deinterlacing - in other words taking the interlaced framebuffer and outputting it to the progressive display. The interlace_allowed flag controls a different feature - filtering of the internalced modes (aka 576i, 1080i, etc). In this case we are using progressive frames, but the HDMI outputs a picture as two separate fields. I have validated this by outputting image (modetest) to the external HDMI display on IFC6410 and on DB820c boards. -- With best wishes Dmitry
Re: [PATCH v6 7/9] drm/msm/dpu: add support for virtual planes
On Fri, Nov 01, 2024 at 01:37:03PM -0700, Abhinav Kumar wrote: > > > On 10/31/2024 2:03 PM, Dmitry Baryshkov wrote: > > On Thu, Oct 31, 2024 at 01:06:34PM -0700, Abhinav Kumar wrote: > > > > > > > > > On 10/31/2024 8:11 AM, Dmitry Baryshkov wrote: > > > > Hi Abhinav, > > > > > > > > On Wed, 30 Oct 2024 at 21:26, Abhinav Kumar > > > > wrote: > > > > > > > > > > > > > > > > > > > > On 10/30/2024 3:48 AM, Dmitry Baryshkov wrote: > > > > > > On Tue, Oct 29, 2024 at 02:30:12PM -0700, Abhinav Kumar wrote: > > > > > > > > > > > > > > > > > > > > > On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > > > > > > > Only several SSPP blocks support such features as YUV output or > > > > > > > > scaling, > > > > > > > > thus different DRM planes have different features. Properly > > > > > > > > utilizing > > > > > > > > all planes requires the attention of the compositor, who should > > > > > > > > prefer simpler planes to YUV-supporting ones. Otherwise it is > > > > > > > > very easy > > > > > > > > to end up in a situation when all featureful planes are already > > > > > > > > allocated for simple windows, leaving no spare plane for YUV > > > > > > > > playback. > > > > > > > > > > > > > > > > To solve this problem make all planes virtual. Each plane is > > > > > > > > registered > > > > > > > > as if it supports all possible features, but then at the > > > > > > > > runtime during > > > > > > > > the atomic_check phase the driver selects backing SSPP block > > > > > > > > for each > > > > > > > > plane. > > > > > > > > > > > > > > > > As the planes are attached to the CRTC and not the encoder, the > > > > > > > > SSPP > > > > > > > > blocks are also allocated per CRTC ID (all other resources are > > > > > > > > currently > > > > > > > > allocated per encoder ID). This also matches the hardware > > > > > > > > requirement, > > > > > > > > where both rectangles of a single SSPP can only be used with > > > > > > > > the LM > > > > > > > > pair. > > > > > > > > > > > > > > > > Note, this does not provide support for using two different > > > > > > > > SSPP blocks > > > > > > > > for a single plane or using two rectangles of an SSPP to drive > > > > > > > > two > > > > > > > > planes. Each plane still gets its own SSPP and can utilize > > > > > > > > either a solo > > > > > > > > rectangle or both multirect rectangles depending on the > > > > > > > > resolution. > > > > > > > > > > > > > > > > Note #2: By default support for virtual planes is turned off > > > > > > > > and the > > > > > > > > driver still uses old code path with preallocated SSPP block > > > > > > > > for each > > > > > > > > plane. To enable virtual planes, pass > > > > > > > > 'msm.dpu_use_virtual_planes=1' > > > > > > > > kernel parameter. > > > > > > > > > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > > > > > --- > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 237 > > > > > > > > ++ > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 16 ++ > > > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 68 + > > > > > > > > drivers/gpu/drm/m
Re: [PATCH RFC 1/4] drm/dp: Add helper to set LTTPRs in transparent mode
On Fri, Nov 01, 2024 at 03:43:40PM +0200, Imre Deak wrote: > On Fri, Nov 01, 2024 at 11:22:13AM +0200, Jani Nikula wrote: > > On Thu, 31 Oct 2024, Imre Deak wrote: > > > On Thu, Oct 31, 2024 at 05:12:45PM +0200, Abel Vesa wrote: > > >> According to the DisplayPort standard, LTTPRs have two operating > > >> modes: > > >> - non-transparent - it replies to DPCD LTTPR field specific AUX > > >>requests, while passes through all other AUX requests > > >> - transparent - it passes through all AUX requests. > > >> > > >> Switching between this two modes is done by the DPTX by issuing > > >> an AUX write to the DPCD PHY_REPEATER_MODE register. > > >> > > >> Add a generic helper that allows switching between these modes. > > >> > > >> Signed-off-by: Abel Vesa > > >> --- > > >> drivers/gpu/drm/display/drm_dp_helper.c | 17 + > > >> include/drm/display/drm_dp_helper.h | 1 + > > >> 2 files changed, 18 insertions(+) > > >> > > >> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c > > >> b/drivers/gpu/drm/display/drm_dp_helper.c > > >> index > > >> 6ee51003de3ce616c3a52653c2f1979ad7658e21..38d612345986ad54b42228902ea718a089d169c4 > > >> 100644 > > >> --- a/drivers/gpu/drm/display/drm_dp_helper.c > > >> +++ b/drivers/gpu/drm/display/drm_dp_helper.c > > >> @@ -2694,6 +2694,23 @@ int drm_dp_lttpr_max_link_rate(const u8 > > >> caps[DP_LTTPR_COMMON_CAP_SIZE]) > > >> } > > >> EXPORT_SYMBOL(drm_dp_lttpr_max_link_rate); > > >> > > >> +/** > > >> + * drm_dp_lttpr_set_transparent_mode - set the LTTPR in transparent mode > > >> + * @aux: DisplayPort AUX channel > > >> + * @enable: Enable or disable transparent mode > > >> + * > > >> + * Returns 0 on success or a negative error code on failure. > > > > > > Should be "Returns 1 on success". > > > > But is that a sensible return value? > > It matches what the function returns, but yes, would make more sense to > fix the return value instead to be 0 in case of success. I think returning 0 is better in case of this function. > > > > > > >> + */ > > >> + > > > > Superfluous newline. > > > > >> +int drm_dp_lttpr_set_transparent_mode(struct drm_dp_aux *aux, bool > > >> enable) > > >> +{ > > >> +u8 val = enable ? DP_PHY_REPEATER_MODE_TRANSPARENT : > > >> + DP_PHY_REPEATER_MODE_NON_TRANSPARENT; > > >> + > > >> +return drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE, val); > > >> +} > > >> +EXPORT_SYMBOL(drm_dp_lttpr_set_transparent_mode); > > >> + > > >> /** > > >> * drm_dp_lttpr_max_lane_count - get the maximum lane count supported > > >> by all LTTPRs > > >> * @caps: LTTPR common capabilities > > >> diff --git a/include/drm/display/drm_dp_helper.h > > >> b/include/drm/display/drm_dp_helper.h > > >> index > > >> 279624833ea9259809428162f4e845654359f8c9..8821ab2d36b0e04d38ccbdddcb703b34de7ed680 > > >> 100644 > > >> --- a/include/drm/display/drm_dp_helper.h > > >> +++ b/include/drm/display/drm_dp_helper.h > > >> @@ -625,6 +625,7 @@ int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux > > >> *aux, > > >> u8 caps[DP_LTTPR_PHY_CAP_SIZE]); > > >> int drm_dp_lttpr_count(const u8 cap[DP_LTTPR_COMMON_CAP_SIZE]); > > >> int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]); > > >> +int drm_dp_lttpr_set_transparent_mode(struct drm_dp_aux *aux, bool > > >> enable); > > >> int drm_dp_lttpr_max_lane_count(const u8 > > >> caps[DP_LTTPR_COMMON_CAP_SIZE]); > > >> bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 > > >> caps[DP_LTTPR_PHY_CAP_SIZE]); > > >> bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 > > >> caps[DP_LTTPR_PHY_CAP_SIZE]); > > >> > > >> -- > > >> 2.34.1 > > >> > > > > -- > > Jani Nikula, Intel -- With best wishes Dmitry
Re: [PATCH RFC v2 6/7] drm/display/hdmi: implement connector update functions
On Fri, Nov 01, 2024 at 12:59:38PM +0200, Jani Nikula wrote: > On Fri, 01 Nov 2024, Dmitry Baryshkov wrote: > > The HDMI Connectors need to perform a variety of tasks when the HDMI > > connector state changes. Such tasks include setting or invalidating CEC > > address, notifying HDMI codec driver, updating scrambler data, etc. > > > > Implementing such tasks in a driver-specific callbacks is error prone. > > Start implementing the generic helper function (currently handling only > > the HDMI Codec framework) to be used by driver utilizing HDMI Connector > > framework. > > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 56 > > + > > include/drm/display/drm_hdmi_state_helper.h | 4 ++ > > 2 files changed, 60 insertions(+) > > > > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c > > b/drivers/gpu/drm/display/drm_hdmi_state_helper.c > > index > > feb7a3a759811aed70c679be8704072093e2a79b..dc9d0cc162b2197dcbadda26686a9c5652e74107 > > 100644 > > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c > > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c > > @@ -748,3 +748,59 @@ > > drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector > > *con > > return ret; > > } > > EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe); > > + > > +/** > > + * __drm_atomic_helper_connector_hdmi_update_edid - Update the HDMI > > Connector basing on passed EDID > > + * @connector: A pointer to the HDMI connector > > + * @drm_edid: EDID to process > > + * > > + * This function should be called as a part of the .detect() / > > .detect_ctx() > > + * and .force() callbacks, updating the HDMI-specific connector's data. The > > + * function consumes passed EDID, there is no need to free it afterwards. > > Most > > + * of the drivers should be able to use > > + * @drm_atomic_helper_connector_hdmi_update() instead. > > + * > > + * Returns: > > + * Zero on success, error code on failure. > > + */ > > +int > > +__drm_atomic_helper_connector_hdmi_update_edid(struct drm_connector > > *connector, > > + const struct drm_edid *drm_edid) > > +{ > > + drm_edid_connector_update(connector, drm_edid); > > + drm_edid_free(drm_edid); > > Not fond of splitting resource management responsibilities > asymmetrically like this. Ack, I can remove drm_edid_free() call. > > > + > > + if (!drm_edid) { > > + drm_connector_hdmi_codec_plugged_notify(connector, false); > > Is it a good idea to tie connection status to EDID presence at the > helper level? Nearly the same, but still orthogonal. Yes. We have been discussing this in v1 review. Basically, CEC, HDMI codec and some other features should be pinged without any userspace interaction. This means that get_modes / fill_modes is mostly out of question. The final agreement was that the .detect is the best place to handle them (BTW: this matches the i915 driver, see intel_hdmi_detect()). > > > + > > + // TODO: also handle CEC and scramber, HDMI sink disconnected. > > + > > + return 0; > > + } > > + > > + drm_connector_hdmi_codec_plugged_notify(connector, true); > > + > > + // TODO: also handle CEC and scramber, HDMI sink is now connected. > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_update_edid); > > Feels wrong to export and document double underscored functions to > actually be used. We have enough examples of EXPORT_SYMBOL(__drm_foo) in DRM helpers. But I can drop double-underscore if that's the issue. > > > + > > +/** > > + * drm_atomic_helper_connector_hdmi_update - Update the HDMI Connector > > after reading the EDID > > + * @connector: A pointer to the HDMI connector > > + * > > + * This function should be called as a part of the .detect() / > > .detect_ctx() > > + * and .force() callbacks, updating the HDMI-specific connector's data. > > + * > > + * Returns: > > + * Zero on success, error code on failure. > > + */ > > +int > > +drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector) > > +{ > > + const struct drm_edid *drm_edid = drm_edid_read(connector); > > + > > + return __drm_atomic_helper_connector_hdmi_update_edid(connector, > > drm_edid); > > +} > > +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi
Re: [PATCH v2] drm/bridge: Fix assignment of the of_node of the parent to aux bridge
On Fri, 1 Nov 2024 at 11:20, Laurent Pinchart wrote: > > On Fri, Nov 01, 2024 at 11:49:07AM +0800, Sui Jingfeng wrote: > > > > On 2024/11/1 00:23, Johan Hovold wrote: > > > On Thu, Oct 31, 2024 at 11:06:38PM +0800, Sui Jingfeng wrote: > > > > > >> But I think Johan do need more times to understand what exactly > > >> the real problem is. We do need times to investigate new method. > > > No, I know perfectly well what the (immediate) problem is here (I was > > > the one adding support for the of_node_reused flag some years back). > > > > > > I just wanted to make sure that the commit message was correct and > > > complete before merging (and also to figure out whether this particular > > > patch needed to be backported). > > > > Well under such a design, having the child device sharing the 'OF' device > > node with it parent device means that one parent device can *only* > > create one AUX bridge child device. > > > > Since If you create two or more child AUX bridge, *all* of them will > > call devm_drm_of_get_bridge(&auxdev->dev, auxdev->dev.of_node, 0, 0), > > then we will *contend* the same next bridge resource. > > > > Because of the 'auxdev->dev.of_node' is same for all its instance. > > While other display bridges seems don't has such limitations. > > Brainstorming a bit, I wonder if we could create a swnode for the > auxiliary device, instead of reusing the parent's OF node. This will break bridge lookup which is performed by following the OF graph links. So the aux bridges should use corresponding of_node or fwnode. > This would > require switching the DRM OF-based APIs to fwnode, but that's easy and > mostly a mechanical change. -- With best wishes Dmitry
[PATCH RFC v2 3/7] drm/connector: implement generic HDMI codec helpers
Several DRM drivers implement HDMI codec support (despite its name it applies to both HDMI and DisplayPort drivers). Implement generic framework to be used by these drivers. This removes a requirement to implement get_eld() callback and provides default implementation for codec's plug handling. The framework is integrated with the DRM HDMI Connector framework, but can be used by DisplayPort drivers. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_connector.c| 10 ++ drivers/gpu/drm/drm_connector_hdmi_codec.c | 186 + drivers/gpu/drm/drm_internal.h | 5 + include/drm/drm_connector.h| 80 + 5 files changed, 282 insertions(+) diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 463afad1b5ca6275e61223adc8ca036c3d4d6b03..ab5b052ad5229229ac46e3804be77dd1d1680f58 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -42,6 +42,7 @@ drm-y := \ drm_cache.o \ drm_color_mgmt.o \ drm_connector.o \ + drm_connector_hdmi_codec.o \ drm_crtc.o \ drm_displayid.o \ drm_drv.o \ diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index fc35f47e2849ed6786d6223ac9c69e1c359fc648..1a155a9fb401f687e5a88e72faca1e81d944b6d2 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -279,6 +279,7 @@ static int __drm_connector_init(struct drm_device *dev, mutex_init(&connector->mutex); mutex_init(&connector->edid_override_mutex); mutex_init(&connector->hdmi.infoframes.lock); + mutex_init(&connector->hdmi_codec.lock); connector->edid_blob_ptr = NULL; connector->epoch_counter = 0; connector->tile_blob_ptr = NULL; @@ -533,6 +534,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector->hdmi.funcs = hdmi_funcs; + if (connector->hdmi_codec.i2s || connector->hdmi_codec.spdif) { + ret = drm_connector_hdmi_codec_init(connector); + if (ret) + return ret; + } + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); @@ -631,6 +638,8 @@ void drm_connector_cleanup(struct drm_connector *connector) DRM_CONNECTOR_REGISTERED)) drm_connector_unregister(connector); + drm_connector_hdmi_codec_cleanup(connector); + if (connector->privacy_screen) { drm_privacy_screen_put(connector->privacy_screen); connector->privacy_screen = NULL; @@ -669,6 +678,7 @@ void drm_connector_cleanup(struct drm_connector *connector) connector->funcs->atomic_destroy_state(connector, connector->state); + mutex_destroy(&connector->hdmi_codec.lock); mutex_destroy(&connector->hdmi.infoframes.lock); mutex_destroy(&connector->mutex); diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c new file mode 100644 index ..cec727d3fc1493684e954195264b1a5d85a7a2ff --- /dev/null +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (c) 2024 Linaro Ltd + */ + +#include +#include +#include + +#include +#include + +#include + +#include "drm_internal.h" + +static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data) +{ + struct drm_connector *connector = data; + const struct drm_connector_hdmi_codec_funcs *funcs = + connector->hdmi.funcs->codec_funcs; + + if (funcs->audio_startup) + return funcs->audio_startup(connector); + + return 0; +} + +static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data, + struct hdmi_codec_daifmt *fmt, + struct hdmi_codec_params *hparms) +{ + struct drm_connector *connector = data; + const struct drm_connector_hdmi_codec_funcs *funcs = + connector->hdmi.funcs->codec_funcs; + + return funcs->prepare(connector, fmt, hparms); +} + +static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data) +{ + struct drm_connector *connector = data; + const struct drm_connector_hdmi_codec_funcs *funcs = + connector->hdmi.funcs->codec_funcs; + + return funcs->audio_shutdown(connector); +} + +static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data, + bool enable, int direction) +{ + struct drm_connector *connector = data; + const struct drm_connector_hdmi
[PATCH RFC v2 0/7] drm: add DRM HDMI Codec framework
While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector framework, I stumbled upon an issue while handling the Audio InfoFrames. The HDMI codec callbacks weren't receiving the drm_atomic_state, so there was no simple way to get the drm_connector that stayed at the end of the bridge chain. At the same point the drm_hdmi_connector functions expected to get drm_connector instance. While looking for a way to solve the issue, I stumbled upon several deficiencies in existing hdmi_codec_ops implementations. Only few of the implementations were able to handle codec's 'plugged' callback. One third of the drivers didn't implement the get_eld() callback. Most of the issues can be solved if drm_connector handles hdmi-audio-codec on its own, delegating functionality to the actual implementation, be it a driver that implements drm_connector or drm_bridge. Implement such high-level framework, adding proper support for Audio InfoFrame generation to the LT9611 driver. Several design decisions to be kept in mind: - drm_connector_hdmi_codec is kept as simple as possible. It implements generic functionality (ELD, hotplug, registration). - drm_hdmi_connector sets up HDMI codec device if the connector is setup correspondingly (either I2S or S/PDIF is marked as supported). - drm_bridge_connector provides a way to link HDMI audio codec funcionality in the drm_bridge with the drm_connector_hdmi_codec framework. - It might be worth reverting the no_i2s_capture / no_spdif_capture bits. Only TDA889x driver sets them, while it's safe to assume that most of HDMI / DP devices do not support ARC / capture. I think the drivers should opt-in capture support rather than having to opt-out of it. This series is in the RFC stage, so some bits are underdocumented. Signed-off-by: Dmitry Baryshkov --- Changes in v2: - Use drm_atomic_get_old_connector_for_encoder in atomic_disable() to prevent it from crashing - Reworked HDMI codec init/exit, removing drmm_ calls (Maxime) - Drafted the helper to be called from .detect_ctx() that performs HDMI Connector maintenance duties (Maxime) - Moved no_capture_mute to struct hdmi_codec_pdata - Link to v1: https://lore.kernel.org/r/20240615-drm-bridge-hdmi-connector-v1-0-d59fc7865...@linaro.org --- Dmitry Baryshkov (7): ASoC: hdmi-codec: pass data to get_dai_id too ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata drm/connector: implement generic HDMI codec helpers drm/bridge: connector: add support for HDMI codec framework drm/bridge: lt9611: switch to using the DRM HDMI codec framework drm/display/hdmi: implement connector update functions drm/bridge_connector: hook __drm_atomic_helper_connector_hdmi_update_edid() drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 3 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 3 +- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- drivers/gpu/drm/bridge/lontium-lt9611.c| 170 --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 +- drivers/gpu/drm/bridge/sii902x.c | 5 +- .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c| 3 +- drivers/gpu/drm/display/drm_bridge_connector.c | 160 -- drivers/gpu/drm/display/drm_hdmi_state_helper.c| 56 +++ drivers/gpu/drm/drm_connector.c| 10 ++ drivers/gpu/drm/drm_connector_hdmi_codec.c | 186 + drivers/gpu/drm/drm_internal.h | 5 + drivers/gpu/drm/exynos/exynos_hdmi.c | 2 +- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- drivers/gpu/drm/mediatek/mtk_dp.c | 2 +- drivers/gpu/drm/mediatek/mtk_hdmi.c| 2 +- drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +- drivers/gpu/drm/sti/sti_hdmi.c | 2 +- include/drm/display/drm_hdmi_state_helper.h| 4 + include/drm/drm_bridge.h | 23 +++ include/drm/drm_connector.h| 80 + include/sound/hdmi-codec.h | 7 +- sound/soc/codecs/hdmi-codec.c | 4 +- 24 files changed, 601 insertions(+), 136 deletions(-) --- base-commit: f9f24ca362a4d84dd8aeb4b8f3ec28cb6c43dd06 change-id: 20240530-drm-bridge-hdmi-connector-9b0f6725973e Best regards, -- Dmitry Baryshkov
[PATCH RFC v2 6/7] drm/display/hdmi: implement connector update functions
The HDMI Connectors need to perform a variety of tasks when the HDMI connector state changes. Such tasks include setting or invalidating CEC address, notifying HDMI codec driver, updating scrambler data, etc. Implementing such tasks in a driver-specific callbacks is error prone. Start implementing the generic helper function (currently handling only the HDMI Codec framework) to be used by driver utilizing HDMI Connector framework. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 56 + include/drm/display/drm_hdmi_state_helper.h | 4 ++ 2 files changed, 60 insertions(+) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index feb7a3a759811aed70c679be8704072093e2a79b..dc9d0cc162b2197dcbadda26686a9c5652e74107 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -748,3 +748,59 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con return ret; } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe); + +/** + * __drm_atomic_helper_connector_hdmi_update_edid - Update the HDMI Connector basing on passed EDID + * @connector: A pointer to the HDMI connector + * @drm_edid: EDID to process + * + * This function should be called as a part of the .detect() / .detect_ctx() + * and .force() callbacks, updating the HDMI-specific connector's data. The + * function consumes passed EDID, there is no need to free it afterwards. Most + * of the drivers should be able to use + * @drm_atomic_helper_connector_hdmi_update() instead. + * + * Returns: + * Zero on success, error code on failure. + */ +int +__drm_atomic_helper_connector_hdmi_update_edid(struct drm_connector *connector, + const struct drm_edid *drm_edid) +{ + drm_edid_connector_update(connector, drm_edid); + drm_edid_free(drm_edid); + + if (!drm_edid) { + drm_connector_hdmi_codec_plugged_notify(connector, false); + + // TODO: also handle CEC and scramber, HDMI sink disconnected. + + return 0; + } + + drm_connector_hdmi_codec_plugged_notify(connector, true); + + // TODO: also handle CEC and scramber, HDMI sink is now connected. + + return 0; +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_update_edid); + +/** + * drm_atomic_helper_connector_hdmi_update - Update the HDMI Connector after reading the EDID + * @connector: A pointer to the HDMI connector + * + * This function should be called as a part of the .detect() / .detect_ctx() + * and .force() callbacks, updating the HDMI-specific connector's data. + * + * Returns: + * Zero on success, error code on failure. + */ +int +drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector) +{ + const struct drm_edid *drm_edid = drm_edid_read(connector); + + return __drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid); +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update); diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h index 2d45fcfa461985065a5e5ad67eddc0b1c556d526..ea0980aa25cbbfdd36f44201888c139b0ee943da 100644 --- a/include/drm/display/drm_hdmi_state_helper.h +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -20,4 +20,8 @@ int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_state *state); +int __drm_atomic_helper_connector_hdmi_update_edid(struct drm_connector *connector, + const struct drm_edid *drm_edid); +int drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector); + #endif // DRM_HDMI_STATE_HELPER_H_ -- 2.39.5
[PATCH RFC v2 4/7] drm/bridge: connector: add support for HDMI codec framework
Add necessary glue code to be able to use new HDMI codec framework from the DRM bridge drivers. The drm_bridge implements a limited set of the hdmi_codec_ops interface, with the functions accepting both drm_connector and drm_bridge instead of just a generic void pointer. This framework is integrated with the DRM HDMI Connector framework, but can also be used for DisplayPort connectors. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 95 +- include/drm/drm_bridge.h | 23 +++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 320c297008aaa8b6ef5b1f4c71928849b202e8ac..12ab9f14cc8a8672478ae2804c9a68d766d88ea5 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -20,6 +20,8 @@ #include #include +#include + /** * DOC: overview * @@ -354,10 +356,80 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); } +static int drm_bridge_connector_audio_startup(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->funcs->hdmi_codec_audio_startup) + return bridge->funcs->hdmi_codec_audio_startup(connector, bridge); + else + return 0; +} + +static int drm_bridge_connector_prepare(struct drm_connector *connector, + struct hdmi_codec_daifmt *fmt, + struct hdmi_codec_params *hparms) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_codec_prepare(connector, bridge, fmt, hparms); +} + +static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return; + + bridge->funcs->hdmi_codec_audio_shutdown(connector, bridge); +} + +static int drm_bridge_connector_mute_stream(struct drm_connector *connector, + bool enable, int direction) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->funcs->hdmi_codec_mute_stream) + return bridge->funcs->hdmi_codec_mute_stream(connector, bridge, +enable, direction); + else + return -ENOTSUPP; +} + +static const struct drm_connector_hdmi_codec_funcs drm_bridge_connector_hdmi_codec_funcs = { + .audio_startup = drm_bridge_connector_audio_startup, + .prepare = drm_bridge_connector_prepare, + .audio_shutdown = drm_bridge_connector_audio_shutdown, + .mute_stream = drm_bridge_connector_mute_stream, +}; + static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, .clear_infoframe = drm_bridge_connector_clear_infoframe, .write_infoframe = drm_bridge_connector_write_infoframe, + .codec_funcs = &drm_bridge_connector_hdmi_codec_funcs, }; /* - @@ -459,7 +531,25 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, if (connector_type == DRM_MODE_CONNECTOR_Unknown) return ERR_PTR(-EINVAL); - if (bridge_connector->bridge_hdmi) + if (bridge_connector->bridge_hdmi) { + bridge = bridge_connector->bridge_hdmi; + + if (bridge->hdmi_codec_i2s || + bridge->hdmi_codec_spdif) { + if (!bridge->funcs->hdmi_codec_prepare || + !bridge->funcs->hdmi_codec_audio_shutdown) + return ERR_PTR(-EINVAL); + + bridge_connector->bridge_hdmi = bridge; + + connector->hdmi_codec.dev = bridge->hdmi_codec_dev; +
[PATCH RFC v2 7/7] drm/bridge_connector: hook __drm_atomic_helper_connector_hdmi_update_edid()
Extend drm_bridge_connector code to read the EDID and use it to update connector status if the bridge chain implements HDMI bridge. Performing it from the generic location minimizes individual bridge's code and enforces standard behaviour from all corresponding drivers. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 65 -- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 12ab9f14cc8a8672478ae2804c9a68d766d88ea5..4069e0f972d5fcabf7e07238583fc9ea89ab113f 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -175,17 +176,53 @@ static void drm_bridge_connector_disable_hpd(struct drm_connector *connector) * Bridge Connector Functions */ +static const struct drm_edid * +drm_bridge_connector_read_edid(struct drm_connector *connector, + enum drm_connector_status status) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + const struct drm_edid *drm_edid; + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_edid; + if (!bridge) + return NULL; + + if (status != connector_status_connected) + return NULL; + + drm_edid = drm_bridge_edid_read(bridge, connector); + if (!drm_edid_valid(drm_edid)) { + drm_edid_free(drm_edid); + return NULL; + } + + return drm_edid; +} + static enum drm_connector_status drm_bridge_connector_detect(struct drm_connector *connector, bool force) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); struct drm_bridge *detect = bridge_connector->bridge_detect; + struct drm_bridge *hdmi = bridge_connector->bridge_hdmi; enum drm_connector_status status; if (detect) { status = detect->funcs->detect(detect); + if (hdmi) { + const struct drm_edid *drm_edid = drm_bridge_connector_read_edid(connector, + status); + int ret; + + ret = __drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid); + if (ret) + drm_warn(connector->dev, "updating EDID failed with %d\n", ret); + } + drm_bridge_connector_hpd_notify(connector, status); } else { switch (connector->connector_type) { @@ -246,29 +283,29 @@ static const struct drm_connector_funcs drm_bridge_connector_funcs = { static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector, struct drm_bridge *bridge) { + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *hdmi = bridge_connector->bridge_hdmi; enum drm_connector_status status; const struct drm_edid *drm_edid; - int n; status = drm_bridge_connector_detect(connector, false); if (status != connector_status_connected) - goto no_edid; + return 0; - drm_edid = drm_bridge_edid_read(bridge, connector); - if (!drm_edid_valid(drm_edid)) { + /* In HDMI setup the EDID has been read and handled as a part of .detect() */ + if (!hdmi) { + drm_edid = drm_bridge_connector_read_edid(connector, status); + if (!drm_edid) { + drm_edid_connector_update(connector, NULL); + return 0; + } + + drm_edid_connector_update(connector, drm_edid); drm_edid_free(drm_edid); - goto no_edid; } - drm_edid_connector_update(connector, drm_edid); - n = drm_edid_connector_add_modes(connector); - - drm_edid_free(drm_edid); - return n; - -no_edid: - drm_edid_connector_update(connector, NULL); - return 0; + return drm_edid_connector_add_modes(connector); } static int drm_bridge_connector_get_modes(struct drm_connector *connector) -- 2.39.5
[PATCH RFC v2 2/7] ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata
The no_capture_mute flag might differ from platform to platform, especially in the case of the wrapping implementations, like the upcoming DRM HDMI Codec framework. Move the flag next to all other flags in struct hdmi_codec_pdata. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- drivers/gpu/drm/bridge/sii902x.c | 2 +- drivers/gpu/drm/exynos/exynos_hdmi.c | 2 +- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- drivers/gpu/drm/mediatek/mtk_dp.c | 2 +- drivers/gpu/drm/mediatek/mtk_hdmi.c| 2 +- drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +- drivers/gpu/drm/sti/sti_hdmi.c | 2 +- include/sound/hdmi-codec.h | 4 +--- sound/soc/codecs/hdmi-codec.c | 2 +- 10 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 35ae3f0e8f51f768229e055a086b53a419ffcd9f..98669470d1e955fef36bb4592795fed6ca97139c 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -1464,7 +1464,6 @@ static const struct hdmi_codec_ops it66121_audio_codec_ops = { .audio_shutdown = it66121_audio_shutdown, .mute_stream = it66121_audio_mute, .get_eld = it66121_audio_get_eld, - .no_capture_mute = 1, }; static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev) @@ -1474,6 +1473,7 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev) .i2s = 1, /* Only i2s support for now */ .spdif = 0, .max_i2s_channels = 8, + .no_capture_mute = 1, }; dev_dbg(dev, "%s\n", __func__); diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index f0be803cc2274ca2199ed7661cf752b0a91434b6..5248676b0036a7e8f2142bd2f099c36efb529471 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -841,7 +841,6 @@ static const struct hdmi_codec_ops sii902x_audio_codec_ops = { .mute_stream = sii902x_audio_mute, .get_eld = sii902x_audio_get_eld, .get_dai_id = sii902x_audio_get_dai_id, - .no_capture_mute = 1, }; static int sii902x_audio_codec_init(struct sii902x *sii902x, @@ -864,6 +863,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x, .i2s = 1, /* Only i2s support for now. */ .spdif = 0, .max_i2s_channels = 0, + .no_capture_mute = 1, }; u8 lanes[4]; int num_lanes, i; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index c9d4b9146df95bb46cb6bea4849c331616c2b463..2a74396ac846dc34d87fadea700c387d597ba307 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1658,7 +1658,6 @@ static const struct hdmi_codec_ops audio_codec_ops = { .audio_shutdown = hdmi_audio_shutdown, .mute_stream = hdmi_audio_mute, .get_eld = hdmi_audio_get_eld, - .no_capture_mute = 1, }; static int hdmi_register_audio_device(struct hdmi_context *hdata) @@ -1667,6 +1666,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata) .ops = &audio_codec_ops, .max_i2s_channels = 6, .i2s = 1, + .no_capture_mute = 1, }; hdata->audio.pdev = platform_device_register_data( diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 2160f05bbd16d2346e27365e5549b75ad26fdcb9..10a4195d667ff577183788f8fc7ca806660e2b9c 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1165,7 +1165,6 @@ static const struct hdmi_codec_ops audio_codec_ops = { .audio_shutdown = tda998x_audio_shutdown, .mute_stream = tda998x_audio_mute_stream, .get_eld = tda998x_audio_get_eld, - .no_capture_mute = 1, }; static int tda998x_audio_codec_init(struct tda998x_priv *priv, @@ -1176,6 +1175,7 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv, .max_i2s_channels = 2, .no_i2s_capture = 1, .no_spdif_capture = 1, + .no_capture_mute = 1, }; if (priv->audio_port_enable[AUDIO_ROUTE_I2S]) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index f0f6f402994a7be7e3faee68d66bdb25888ab768..b401246b8f884b9885ece7aaac23a4de2826fb0a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2532,7 +2532,6 @@ static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = { .audio_shutdown = mtk_dp_audio_shutdown, .get_eld = mtk_dp_audio_get_eld, .hook_plugged_cb = mtk_dp_audio_hook_plugged_cb, - .no_capture_mute = 1, }; static int mtk_dp_register_audio_driver(struct device *dev) @@ -2543,6 +
[PATCH RFC v2 1/7] ASoC: hdmi-codec: pass data to get_dai_id too
The upcoming DRM connector HDMI codec implementation is going to use codec-specific data in the .get_dai_id to get drm_connector. Pass data to the callback, as it is done with other hdmi_codec_ops callbacks. Acked-by: Mark Brown Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 3 ++- drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++- drivers/gpu/drm/bridge/lontium-lt9611.c | 3 ++- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 ++- drivers/gpu/drm/bridge/sii902x.c| 3 ++- drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++- include/sound/hdmi-codec.h | 3 ++- sound/soc/codecs/hdmi-codec.c | 2 +- 8 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c index 61f4a38e7d2bf6905683cbc9e762b28ecc999d05..51fb9a574b4e28450b2598a92e2930ace5128b71 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c @@ -204,7 +204,8 @@ static void audio_shutdown(struct device *dev, void *data) } static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, - struct device_node *endpoint) + struct device_node *endpoint, + void *data) { struct of_endpoint of_ep; int ret; diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index a2675b121fe44b96945f34215fd900f35bfde43a..926437346b6c9a651d495faf25162cac7407d30d 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1952,7 +1952,8 @@ static void anx7625_audio_shutdown(struct device *dev, void *data) } static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component, - struct device_node *endpoint) + struct device_node *endpoint, + void *data) { struct of_endpoint of_ep; int ret; diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 1b31fdebe164063e6f3972fdf8a5801ef4c35c4e..4fa0dfc5539a5786278221f7c13b6473ab320a9a 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -1059,7 +1059,8 @@ static void lt9611_audio_shutdown(struct device *dev, void *data) } static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component, - struct device_node *endpoint) + struct device_node *endpoint, + void *data) { struct of_endpoint of_ep; int ret; diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 4d1d40e1f1b4d144f4aa9de7b83bedf13dfa4436..fd26aa36b15b8c0d3859f7ef488a87573eea8507 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -522,7 +522,8 @@ static void lt9611uxc_audio_shutdown(struct device *dev, void *data) } static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component, -struct device_node *endpoint) +struct device_node *endpoint, +void *data) { struct of_endpoint of_ep; int ret; diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index 9be9cc5b902594ebe6e1ac29ab8684623e336796..f0be803cc2274ca2199ed7661cf752b0a91434b6 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -815,7 +815,8 @@ static int sii902x_audio_get_eld(struct device *dev, void *data, } static int sii902x_audio_get_dai_id(struct snd_soc_component *component, - struct device_node *endpoint) + struct device_node *endpoint, + void *data) { struct of_endpoint of_ep; int ret; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index 26c187d20d973dc65801a3baa59ecf57d20072eb..86c412e9cbc80bb82bad5db3aa0263a7acd9c2d7 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -148,7 +148,8 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf, } static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component, - struct device_node *endpoint) + struct device_node *endpoint, + void *data
[PATCH RFC v2 5/7] drm/bridge: lt9611: switch to using the DRM HDMI codec framework
Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec framework. This enables programming of Audio InfoFrames using the HDMI Connector interface and also enables support for the missing features, including the ELD retrieval and better hotplug support. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/lontium-lt9611.c | 171 +--- 1 file changed, 69 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 4fa0dfc5539a5786278221f7c13b6473ab320a9a..9d8b1c8d533c79bd91ae956aa4cb74f3bab6de78 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -45,7 +45,6 @@ struct lt9611 { struct device_node *dsi1_node; struct mipi_dsi_device *dsi0; struct mipi_dsi_device *dsi1; - struct platform_device *audio_pdev; bool ac_mode; @@ -866,6 +865,10 @@ static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge, unsigned int mask; switch (type) { + case HDMI_INFOFRAME_TYPE_AUDIO: + mask = LT9611_INFOFRAME_AUDIO; + break; + case HDMI_INFOFRAME_TYPE_AVI: mask = LT9611_INFOFRAME_AVI; break; @@ -899,6 +902,11 @@ static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge, int i; switch (type) { + case HDMI_INFOFRAME_TYPE_AUDIO: + mask = LT9611_INFOFRAME_AUDIO; + addr = 0x84b2; + break; + case HDMI_INFOFRAME_TYPE_AVI: mask = LT9611_INFOFRAME_AVI; addr = 0x8440; @@ -942,6 +950,55 @@ lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, return MODE_OK; } +static int lt9611_hdmi_codec_audio_startup(struct drm_connector *connector, + struct drm_bridge *bridge) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + + regmap_write(lt9611->regmap, 0x82d6, 0x8c); + regmap_write(lt9611->regmap, 0x82d7, 0x04); + + regmap_write(lt9611->regmap, 0x8406, 0x08); + regmap_write(lt9611->regmap, 0x8407, 0x10); + + regmap_write(lt9611->regmap, 0x8434, 0xd5); + + return 0; +} + +static int lt9611_hdmi_codec_prepare(struct drm_connector *connector, +struct drm_bridge *bridge, +struct hdmi_codec_daifmt *fmt, +struct hdmi_codec_params *hparms) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + + if (hparms->sample_rate == 48000) + regmap_write(lt9611->regmap, 0x840f, 0x2b); + else if (hparms->sample_rate == 96000) + regmap_write(lt9611->regmap, 0x840f, 0xab); + else + return -EINVAL; + + regmap_write(lt9611->regmap, 0x8435, 0x00); + regmap_write(lt9611->regmap, 0x8436, 0x18); + regmap_write(lt9611->regmap, 0x8437, 0x00); + + return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, + &hparms->cea); +} + +static void lt9611_hdmi_codec_audio_shutdown(struct drm_connector *connector, +struct drm_bridge *bridge) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + + drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector); + + regmap_write(lt9611->regmap, 0x8406, 0x00); + regmap_write(lt9611->regmap, 0x8407, 0x00); +} + static const struct drm_bridge_funcs lt9611_bridge_funcs = { .attach = lt9611_bridge_attach, .mode_valid = lt9611_bridge_mode_valid, @@ -962,6 +1019,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = { .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, + + .hdmi_codec_audio_startup = lt9611_hdmi_codec_audio_startup, + .hdmi_codec_prepare = lt9611_hdmi_codec_prepare, + .hdmi_codec_audio_shutdown = lt9611_hdmi_codec_audio_shutdown, }; static int lt9611_parse_dt(struct device *dev, @@ -1015,102 +1076,6 @@ static int lt9611_read_device_rev(struct lt9611 *lt9611) return ret; } -static int lt9611_hdmi_hw_params(struct device *dev, void *data, -struct hdmi_codec_daifmt *fmt, -struct hdmi_codec_params *hparms) -{ - struct lt9611 *lt9611 = data; - - if (hparms->sample_rate == 48000) - regmap_write(lt9611->regmap, 0x840f, 0x2b); - else if (hparms->sample_rate == 96000) - regmap_write(lt9611->regmap, 0x840f, 0xab); - else - return -EINVAL; - - regmap_wri
[PATCH v2 1/6] drm/display: hdmi: add generic mode_valid helper
Add drm_hdmi_connector_mode_valid(), generic helper for HDMI connectors. It can be either used directly or as a part of the .mode_valid callback. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_helper.c | 45 ++ drivers/gpu/drm/display/drm_hdmi_helper_internal.h | 11 ++ drivers/gpu/drm/display/drm_hdmi_state_helper.c| 26 +--- drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 168 - include/drm/display/drm_hdmi_helper.h | 4 + 5 files changed, 229 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_helper.c b/drivers/gpu/drm/display/drm_hdmi_helper.c index 74dd4d01dd9bb2c9e69ec1c60b0056bd69417e8a..560c5d4365ca54d3f669395349cedfd6f75fa033 100644 --- a/drivers/gpu/drm/display/drm_hdmi_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_helper.c @@ -9,6 +9,8 @@ #include #include +#include "drm_hdmi_helper_internal.h" + static inline bool is_eotf_supported(u8 output_eotf, u8 sink_eotf) { return sink_eotf & BIT(output_eotf); @@ -256,3 +258,46 @@ drm_hdmi_compute_mode_clock(const struct drm_display_mode *mode, return DIV_ROUND_CLOSEST_ULL(clock * bpc, 8); } EXPORT_SYMBOL(drm_hdmi_compute_mode_clock); + +enum drm_mode_status +__drm_hdmi_connector_clock_valid(const struct drm_connector *connector, +const struct drm_display_mode *mode, +unsigned long long clock) +{ + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + const struct drm_display_info *info = &connector->display_info; + + if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) + return MODE_CLOCK_HIGH; + + if (funcs && funcs->tmds_char_rate_valid) { + enum drm_mode_status status; + + status = funcs->tmds_char_rate_valid(connector, mode, clock); + if (status != MODE_OK) + return status; + } + + return MODE_OK; +} + +/** + * drm_hdmi_connector_mode_valid() - Check if mode is valid for HDMI connector + * @connector: DRM connector to validate the mode + * @mode: Display mode to validate + * + * Generic .mode_valid implementation for HDMI connectors. + */ +enum drm_mode_status +drm_hdmi_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + unsigned long long clock; + + clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + if (!clock) + return MODE_ERROR; + + return __drm_hdmi_connector_clock_valid(connector, mode, clock); +} +EXPORT_SYMBOL(drm_hdmi_connector_mode_valid); diff --git a/drivers/gpu/drm/display/drm_hdmi_helper_internal.h b/drivers/gpu/drm/display/drm_hdmi_helper_internal.h new file mode 100644 index ..ee74435c04f62cf71b9857bdc427c46442b85697 --- /dev/null +++ b/drivers/gpu/drm/display/drm_hdmi_helper_internal.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_DP_HELPER_INTERNAL_H +#define DRM_DP_HELPER_INTERNAL_H + +enum drm_mode_status +__drm_hdmi_connector_clock_valid(const struct drm_connector *connector, +const struct drm_display_mode *mode, +unsigned long long clock); + +#endif diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index feb7a3a759811aed70c679be8704072093e2a79b..29c2cb2c3171366a2a68fc6ad48f8ad8a4dc7e30 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -8,6 +8,8 @@ #include #include +#include "drm_hdmi_helper_internal.h" + /** * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources * @connector: DRM connector @@ -198,28 +200,6 @@ sink_supports_format_bpc(const struct drm_connector *connector, return false; } -static enum drm_mode_status -hdmi_clock_valid(const struct drm_connector *connector, -const struct drm_display_mode *mode, -unsigned long long clock) -{ - const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; - const struct drm_display_info *info = &connector->display_info; - - if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) - return MODE_CLOCK_HIGH; - - if (funcs && funcs->tmds_char_rate_valid) { - enum drm_mode_status status; - - status = funcs->tmds_char_rate_valid(connector, mode, clock); - if (status != MODE_OK) - return status; - } - - return MODE_OK; -} - static int hdmi_compute_clock(const struct drm_connector *connector, struct drm_connector_s
[PATCH v2 5/6] drm/bridge: lontium-lt9611: drop TMDS char rate check in mode_valid
Drop manual check of the TMDS char rate in the mode_valid callback. This check is now being performed by the core. Reviewed-by: Chen-Yu Tsai Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/lontium-lt9611.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 1b31fdebe164063e6f3972fdf8a5801ef4c35c4e..b8ccffdf515ade6e3bf863edbedc41e6f2030f29 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -757,7 +757,6 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - unsigned long long rate; if (mode->hdisplay > 3840) return MODE_BAD_HVALUE; @@ -765,8 +764,7 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, if (mode->hdisplay > 2000 && !lt9611->dsi1_node) return MODE_PANEL; - rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); - return bridge->funcs->hdmi_tmds_char_rate_valid(bridge, mode, rate); + return MODE_OK; } static int lt9611_bridge_atomic_check(struct drm_bridge *bridge, -- 2.39.5
[PATCH v2 0/6] drm/display: hdmi: add drm_hdmi_connector_mode_valid()
Several HDMI drivers have common code pice in the .mode_valid function that validates RGB / 8bpc rate using the TMDS char rate callbacks. Move this code piece to the common helper and remove the need to perform this check manually. In case of DRM_BRIDGE_OP_HDMI bridges, they can skip the check in favour of performing it in drm_bridge_connector. Signed-off-by: Dmitry Baryshkov --- Changes in v2: - Switched drm_hdmi_connector_mode_valid() to use common helper (ex-hdmi_clock_valid()) (Maxime) - Added simple unit tests for drm_hdmi_connector_mode_valid(). - Link to v1: https://lore.kernel.org/r/20241018-hdmi-mode-valid-v1-0-6e49ae480...@linaro.org --- Dmitry Baryshkov (6): drm/display: hdmi: add generic mode_valid helper drm/sun4i: use drm_hdmi_connector_mode_valid() drm/vc4: use drm_hdmi_connector_mode_valid() drm/display: bridge_connector: use drm_bridge_connector_mode_valid() drm/bridge: lontium-lt9611: drop TMDS char rate check in mode_valid drm/bridge: dw-hdmi-qp: replace mode_valid with tmds_char_rate drivers/gpu/drm/bridge/lontium-lt9611.c| 4 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 12 +- drivers/gpu/drm/display/drm_bridge_connector.c | 16 +- drivers/gpu/drm/display/drm_hdmi_helper.c | 45 ++ drivers/gpu/drm/display/drm_hdmi_helper_internal.h | 11 ++ drivers/gpu/drm/display/drm_hdmi_state_helper.c| 26 +--- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 12 +- drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 168 - drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +- include/drm/display/drm_hdmi_helper.h | 4 + 10 files changed, 252 insertions(+), 50 deletions(-) --- base-commit: 623b1e4d2eace0958996995f9f88cb659a6f69dd change-id: 20241018-hdmi-mode-valid-aaec4428501c Best regards, -- Dmitry Baryshkov
[PATCH v2 2/6] drm/sun4i: use drm_hdmi_connector_mode_valid()
Use new drm_hdmi_connector_mode_valid() helper instead of a module-specific copy. Reviewed-by: Chen-Yu Tsai Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 12 +--- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index b3649449de3026784ae2f3466906403a0b6e3b47..54b72fe220afacc208b3fd48d5160031127ea14a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -205,16 +205,6 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector, return 0; } -static enum drm_mode_status -sun4i_hdmi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - unsigned long long rate = drm_hdmi_compute_mode_clock(mode, 8, - HDMI_COLORSPACE_RGB); - - return sun4i_hdmi_connector_clock_valid(connector, mode, rate); -} - static int sun4i_hdmi_get_modes(struct drm_connector *connector) { struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); @@ -269,7 +259,7 @@ static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = { static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { .atomic_check = sun4i_hdmi_connector_atomic_check, - .mode_valid = sun4i_hdmi_connector_mode_valid, + .mode_valid = drm_hdmi_connector_mode_valid, .get_modes = sun4i_hdmi_get_modes, }; -- 2.39.5
[PATCH v2 6/6] drm/bridge: dw-hdmi-qp: replace mode_valid with tmds_char_rate
Replace .mode_valid() callback with .hdmi_tmds_char_rate_valid(). It is more generic and is used in other mode validation paths. The rate validation for .mode_valid() will be performed by the drm_bridge_connector code. Reviewed-by: Chen-Yu Tsai Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 181c5164b23192f0b557624d73c6223032b90ec6..c686671e4850a1af75b82995185ffc3cbb22a447 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -442,16 +442,14 @@ dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge, } static enum drm_mode_status -dw_hdmi_qp_bridge_mode_valid(struct drm_bridge *bridge, -const struct drm_display_info *info, -const struct drm_display_mode *mode) +dw_hdmi_qp_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge, + const struct drm_display_mode *mode, + unsigned long long rate) { struct dw_hdmi_qp *hdmi = bridge->driver_private; - unsigned long long rate; - rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); if (rate > HDMI14_MAX_TMDSCLK) { - dev_dbg(hdmi->dev, "Unsupported mode clock: %d\n", mode->clock); + dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate); return MODE_CLOCK_HIGH; } @@ -510,7 +508,7 @@ static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = { .atomic_disable = dw_hdmi_qp_bridge_atomic_disable, .detect = dw_hdmi_qp_bridge_detect, .edid_read = dw_hdmi_qp_bridge_edid_read, - .mode_valid = dw_hdmi_qp_bridge_mode_valid, + .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid, .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, }; -- 2.39.5
[PATCH v2 4/6] drm/display: bridge_connector: use drm_bridge_connector_mode_valid()
Use new drm_bridge_connector_mode_valid() helper if there is a HDMI bridge in the bridge chain. This removes the need to perform TMDS char rate check manually in the bridge driver. Reviewed-by: Chen-Yu Tsai Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 320c297008aaa8b6ef5b1f4c71928849b202e8ac..512ced87ea18c74e182a558a686ddd83de891814 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /** @@ -299,9 +300,22 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector) return 0; } +static enum drm_mode_status +drm_bridge_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + + if (bridge_connector->bridge_hdmi) + return drm_hdmi_connector_mode_valid(connector, mode); + + return MODE_OK; +} + static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = { .get_modes = drm_bridge_connector_get_modes, - /* No need for .mode_valid(), the bridges are checked by the core. */ + .mode_valid = drm_bridge_connector_mode_valid, .enable_hpd = drm_bridge_connector_enable_hpd, .disable_hpd = drm_bridge_connector_disable_hpd, }; -- 2.39.5
[PATCH v2 3/6] drm/vc4: use drm_hdmi_connector_mode_valid()
Use new drm_hdmi_connector_mode_valid() helper instead of a module-specific copy. Reviewed-by: Chen-Yu Tsai Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 62b82b1eeb3694d1685969c49b2760cbbddc840e..486e513b898d7f761e8615f2afc193ca44b23200 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1752,7 +1752,6 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, const struct drm_display_mode *mode) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long long rate; if (vc4_hdmi->variant->unsupported_odd_h_timings && !(mode->flags & DRM_MODE_FLAG_DBLCLK) && @@ -1760,8 +1759,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, (mode->hsync_end % 2) || (mode->htotal % 2))) return MODE_H_ILLEGAL; - rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); - return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate); + return drm_hdmi_connector_mode_valid(&vc4_hdmi->connector, mode); } static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { -- 2.39.5
Re: [PATCH v2] drm/msm/dpu: cast crtc_clk calculation to u64 in _dpu_core_perf_calc_clk()
On Tue, 29 Oct 2024 14:42:10 -0500, Gax-c wrote: > There may be a potential integer overflow issue in > _dpu_core_perf_calc_clk(). crtc_clk is defined as u64, while > mode->vtotal, mode->hdisplay, and drm_mode_vrefresh(mode) are defined as > a smaller data type. The result of the calculation will be limited to > "int" in this case without correct casting. In screen with high > resolution and high refresh rate, integer overflow may happen. > So, we recommend adding an extra cast to prevent potential > integer overflow. > > [...] Applied, thanks! [1/1] drm/msm/dpu: cast crtc_clk calculation to u64 in _dpu_core_perf_calc_clk() https://gitlab.freedesktop.org/lumag/msm/-/commit/20c7b42d9dbd Best regards, -- Dmitry Baryshkov
Re: [PATCH v2 0/3] drm/msm/dp: mass-rename symbols
On Tue, 29 Oct 2024 22:28:23 +0200, Dmitry Baryshkov wrote: > The LKP reported [1] a symbol clash between the drm/msm/dp and the HIMBC > driver being sumbitted, because both of them use a generic dp_ prefix > for a lot of symbols. It's a hight time we made msm/dp driver use > something less generic, like msm_dp. > > [1] https://lore.kernel.org/oe-kbuild-all/202410250305.uhkdhtxy-...@intel.com/ > > [...] Applied, thanks! [1/3] drm/msm/dp: prefix all symbols with msm_dp_ https://gitlab.freedesktop.org/lumag/msm/-/commit/fb7d509b1710 [2/3] drm/msm/dp: rename edp_ bridge functions and struct https://gitlab.freedesktop.org/lumag/msm/-/commit/f47e87b07935 [3/3] drm/msm/dp: tidy up platform data names https://gitlab.freedesktop.org/lumag/msm/-/commit/c36a410780a3 Best regards, -- Dmitry Baryshkov
Re: [PATCH 0/3] drm/msm: minor msm_drv.h cleanup
On Thu, 31 Oct 2024 23:44:05 +0200, Dmitry Baryshkov wrote: > As I stumbled upon msm_display_topology define, perform minor cleanup of > msm_drv.h incldue file. > > Applied, thanks! [1/3] drm/msm: move msm_display_topology to the DPU driver https://gitlab.freedesktop.org/lumag/msm/-/commit/f8706bff68cb [2/3] drm/msm: move MAX_H_TILES_PER_DISPLAY to the DPU driver https://gitlab.freedesktop.org/lumag/msm/-/commit/858b64e21217 [3/3] drm/msm: drop MAX_BRIDGES define https://gitlab.freedesktop.org/lumag/msm/-/commit/26d841fd1c15 Best regards, -- Dmitry Baryshkov
Re: [PATCH] drm/bridge: ti-sn65dsi86: Fix multiple instances
On Wed, Oct 30, 2024 at 12:28:46PM +0200, Laurent Pinchart wrote: > On Wed, Oct 30, 2024 at 11:25:40AM +0100, Geert Uytterhoeven wrote: > > On Mon, Oct 28, 2024 at 2:34 PM Dmitry Baryshkov wrote: > > > On Tue, Oct 22, 2024 at 07:37:01AM -0700, Doug Anderson wrote: > > > > On Tue, Oct 22, 2024 at 12:12 AM Geert Uytterhoeven wrote: > > > > > > > > > > However, using i2c_client->adapter->nr instead of > > > > > > > > > > ida_alloc() > > > > > > > > > > in the TI driver does sound like a good idea to me... > > > > > > > > > > > > > > > > > > Great! > > > > > > > > > > > > > > > With the I2C adapter numbers, that becomes: > > > > > > > > > > > > > > > > /sys/bus/auxiliary/devices > > > > > > > > ├── ti_sn65dsi86.gpio.1 > > > > > > > > ├── ti_sn65dsi86.pwm.1 > > > > > > > > ├── ti_sn65dsi86.aux.1 > > > > > > > > ├── ti_sn65dsi86.bridge.1 > > > > > > > > ├── ti_sn65dsi86.gpio.4 > > > > > > > > ├── ti_sn65dsi86.pwm.4 > > > > > > > > ├── ti_sn65dsi86.aux.4 > > > > > > > > └── ti_sn65dsi86.bridge.4 > > > > > > > > > > > > > > > > > adapter->nr instead like other aux subsystems already do. > > > > > > > > > > > > > > Unfortunately the devil is in the details, as usual: there can be > > > > > > > multiple instances of the sn65dsi86 bridge on a single I2C bus, > > > > > > > so adapter->nr is not guaranteed to generate a unique name. > > > > > > > > > > > > In the case of sn65dsi86 I think we'd actually be OK. The TI bridge > > > > > > chip is always at bus address 0x2d so you can't have more than one > > > > > > on > > > > > > the same bus. Unless you added something funky atop it (like a mux > > > > > > of > > > > > > some sort) you might be OK. > > > > > > > > > > It's 0x2c on mine ;-) > > > > > > > > > > 8.5.1 Local I2C Interface Overview > > > > > The 7-bit device address for SN65DSI86 is factory preset to > > > > > 010110X > > > > > with the least significant bit being determined by the ADDR > > > > > control > > > > > input. > > > > > > > > Doh! I missed that in my search of the doc. I guess because they > > > > decided to specify the address in binary in that part so my searching > > > > for both the 7-bit and 8-bit I2C address didn't trigger. Oh well. > > > > > > > > > > > Changing the auxiliary bus to use the parent's name instead of the > > > > > > > module name, as suggested by Laurent, would fix that. > > > > > > > > > > > > Right. On my system dev_name() of the sn65dsi86 device is "2-002d". > > > > > > If > > > > > > we had a second on i2c bus 4, we'd have: > > > > > > > > > > > > /sys/bus/auxiliary/devices > > > > > > ├── 2-002d.gpio.0 > > > > > > ├── 2-002d.pwm.0 > > > > > > ├── 2-002d.aux.0 > > > > > > ├── 2-002d.bridge.0 > > > > > > ├── 4-002d.gpio.0 > > > > > > ├── 4-002d.pwm.0 > > > > > > ├── 4-002d.aux.0 > > > > > > └── 4-002d.bridge.0 > > > > > > > > > > > > ...and I think that's guaranteed to be unique because all the i2c > > > > > > devices are flat in "/sys/bus/i2c/devices". > > > > > > > > > > Correct. > > > > > > > > So given everything, using the dev_name() of the "parent" sounds > > > > pretty good and seems like it addresses everyone's concerns. Was there > > > > a part of the conversation where someone pointed out problems with it > > > > that I missed? Is the next step to post a patch implementing that? > > > > It'll change sysfs paths and dev names for everyone using AUX bus, but > > > > presumably that's OK? > > > > > > It also requires changing in the way the auxiliary_match_id() works. > > > Currently matching is done using modname + ID. > > > > Right, so just using the parent's name instead of modname won't work, > > as the former is not a fixed string. > > > > > So, maybe using MODNAME.NAME.parent-name.ID is better (e.g. > > > ti_sn65dsi86.gpio.2-002d.1). It will still require changes to the > > > match_id function, but they won't be that intrusive (one just has to > > > skip two parts of the name instead of skipping just one). > > > > IMHO this is becoming too complex. What if the parent's name contains > > a period? > > > > So just using ida_alloc() in the caller seems like the most > > straight-forward solution. > > Why would we duplicate that in every user, when it should really be the > responsibility of the bus ? We need a better solution. Make AUX bus keep a hashtable of parent -> ID relationship and get from the table / allocate via IDA the ID each time somebody adds new AUX device? -- With best wishes Dmitry
Re: [PATCH v4 15/18] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode
On Thu, Oct 31, 2024 at 02:45:29PM -0700, Stephen Boyd wrote: > Quoting Dmitry Baryshkov (2024-10-31 11:42:36) > > On Tue, Oct 29, 2024 at 01:15:51PM -0700, Stephen Boyd wrote: > > > At this point we need to tell the DP bridge, like IT6505, that it's one > > > or the other output endpoints that it should use, but we haven't > > > directly connected the usb-c-connector to the output ports of IT6505 > > > because drm_of_find_panel_or_bridge() can't find the parent of the > > > usb-c-connector if we connect the DP bridge to the usb-c-connector > > > graphs. We'll need a way for the bridge to know which output port is > > > connected to a usb-c-connector fwnode. Some sort of API like > > > > I think that the final bridge should be the IT6505. It can save you from > > some troubles, like the inter-bridge lane negotiation. Please remember > > that using lanes 2-3 as primary lanes doesn't seem to fall into the > > standard DisplayPort usage. It is documented by USB-C and only because > > of the orientation switching. > > If the final bridge is IT6505 then drm_of_find_panel_or_bridge() isn't > called and I think we're OK. But then we have to traverse the > remote-endpoint of the usb-c-connector to IT6505 in displayport.c in the > Corsola case while knowing to look at the parent of the usb-c-connector > node and traversing the remote-endpoint to the QMP phy in the Trogdor > case. The logic in dp_altmode_probe() is like > > if (port@1/endpoint@1 exists in usb-c-connector) > connector_fwnode = port@1/endpoint@1/remote-endpoint > else if (cros-ec-typec/port exists) > connector_fwnode = cros-ec-typec/port@0/endpoint/remote-endpoint > else > original stuff I'd say, definitely ugh. Maybe we can add the swnode with the "displayport" property pointing back to the DP bridge / endpoint. But... read below. > If we have the crazy three usb-c-connector design it can still work > because we'd have something like > > cros-ec-typec { > port { > dp_endpoint: endpoint { > remote-endpoint = <&dp_ml0_ml1>; > }; > }; > > usb-c-connector@0 { > port@1 { > endpoint { > remote-endpoint = <&hub_ss0>; >}; >// Implicitly dp_ml0_ml1 > }; > }; > usb-c-connector@1 { > port@1 { > endpoint@0 { > remote-endpoint = <&hub_ss1>; > }; > endpoint@1 { > remote-endpoint = <&dp_ml2_ml3>; > }; > }; > }; > usb-c-connector@2 { > port@1 { > endpoint { > remote-endpoint = <&hub_ss2>; > }; >// Implicitly dp_ml0_ml1 > }; > }; > }; > > (I like thinking about this 3 connector case because it combines both > Trogdor and Corsola designs so I can talk about both cases at the same > time) > > I don't know what happens when we have 4 connectors though, with 2 going > to one pair of lanes and 2 going to the other 2 lanes. Maybe it's better > to always have a DP input port in cros-ec-typec to avoid this problem > and map back to the endpoint explicitly. > > cros-ec-typec { > port { > dp_endpoint0: endpoint@0 { > remote-endpoint = <&dp_ml0_ml1>; > }; > dp_endpoint1: endpoint@1 { > remote-endpoint = <&dp_ml2_ml3>; > }; > }; > > usb-c-connector@0 { > port@1 { > endpoint@0 { > remote-endpoint = <&hub_ss0>; >}; >endpoint@1 { > remote-endpoint = <&dp_endpoint0>; >}; > }; > }; > usb-c-connector@1 { > port@1 { > endpoint@0 { > remote-endpoint = <&hub_ss1>; > }; > endpoint@1 { > remote-endpoint = <&dp_endpoint1>; > }; > }; > }; > usb-c-connector@2 { > port@1 { > endpoint@0 { > remote-endpoint = <&hub_ss2>; > }; > endpoint@1 { > remote-endpoint = <&dp_endpoint1>; > }; > }; > }; > }; > > Or use a displayport property that goes to connector node itself so that > we don't extend the graph binding of the usb-c-connector. > > cros-ec-typec { > usb-c-connector@0 { > altmodes { > displayport { > connector = <&dp_ml0_ml1>; I think this has been frowned upon. Not exactly this, but adding the displaypor
[PATCH 3/3] drm/msm: drop MAX_BRIDGES define
The const MAX_BRIDGES is unused after the commit 4d1a1e4686bd ("drm/msm: remove msm_drm_private::bridges field"), drop it now. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 1dc161d9bf51..d8c9a1b19263 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -52,7 +52,6 @@ struct msm_gem_vma; struct msm_disp_state; #define MAX_CRTCS 8 -#define MAX_BRIDGES8 #define FRAC_16_16(mult, div)(((mult) << 16) / (div)) -- 2.39.5
Re: [PATCH 1/2] drm/i2c/ch7006: Add a check to prevent NULL pointer dereference
On Fri, Oct 25, 2024 at 03:34:07PM +0800, Zhang Zekun wrote: > drm_mode_duplicate() could return NULL due to lack of memory, > which will then call NULL pointer dereference. Add a check to > prevent it. > > Fixes: 6ee738610f41 ("drm/nouveau: Add DRM driver for NVIDIA GPUs") > Signed-off-by: Zhang Zekun > --- > drivers/gpu/drm/i2c/ch7006_drv.c | 8 ++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v2 3/3] Revert "drm/client: Add drm_client_modeset_check()"
On Tue, Oct 29, 2024 at 11:47:05PM +, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > drm_client_modeset_check() was explicitly added in 2020 by > commit 64593f2a6fc9 ("drm/client: Add drm_client_modeset_check()") > but has never been used. > > This reverts commit 64593f2a6fc933bb9a410bc3f8c261f3e57a9601. Nit: Usually this comes before the commit message. No need for repost though. Reviewed-by: Dmitry Baryshkov > > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_client_modeset.c | 35 > include/drm/drm_client.h | 1 - > 2 files changed, 4 insertions(+), 32 deletions(-) > > diff --git a/drivers/gpu/drm/drm_client_modeset.c > b/drivers/gpu/drm/drm_client_modeset.c > index cee5eafbfb81..39201c11eaac 100644 > --- a/drivers/gpu/drm/drm_client_modeset.c > +++ b/drivers/gpu/drm/drm_client_modeset.c > @@ -995,7 +995,7 @@ bool drm_client_rotation(struct drm_mode_set *modeset, > unsigned int *rotation) > } > EXPORT_SYMBOL(drm_client_rotation); > > -static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, > bool active, bool check) > +static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, > bool active) > { > struct drm_device *dev = client->dev; > struct drm_plane *plane; > @@ -1062,10 +1062,7 @@ static int drm_client_modeset_commit_atomic(struct > drm_client_dev *client, bool > } > } > > - if (check) > - ret = drm_atomic_check_only(state); > - else > - ret = drm_atomic_commit(state); > + ret = drm_atomic_commit(state); > > out_state: > if (ret == -EDEADLK) > @@ -1126,30 +1123,6 @@ static int drm_client_modeset_commit_legacy(struct > drm_client_dev *client) > return ret; > } > > -/** > - * drm_client_modeset_check() - Check modeset configuration > - * @client: DRM client > - * > - * Check modeset configuration. > - * > - * Returns: > - * Zero on success or negative error code on failure. > - */ > -int drm_client_modeset_check(struct drm_client_dev *client) > -{ > - int ret; > - > - if (!drm_drv_uses_atomic_modeset(client->dev)) > - return 0; > - > - mutex_lock(&client->modeset_mutex); > - ret = drm_client_modeset_commit_atomic(client, true, true); > - mutex_unlock(&client->modeset_mutex); > - > - return ret; > -} > -EXPORT_SYMBOL(drm_client_modeset_check); > - > /** > * drm_client_modeset_commit_locked() - Force commit CRTC configuration > * @client: DRM client > @@ -1168,7 +1141,7 @@ int drm_client_modeset_commit_locked(struct > drm_client_dev *client) > > mutex_lock(&client->modeset_mutex); > if (drm_drv_uses_atomic_modeset(dev)) > - ret = drm_client_modeset_commit_atomic(client, true, false); > + ret = drm_client_modeset_commit_atomic(client, true); > else > ret = drm_client_modeset_commit_legacy(client); > mutex_unlock(&client->modeset_mutex); > @@ -1246,7 +1219,7 @@ int drm_client_modeset_dpms(struct drm_client_dev > *client, int mode) > > mutex_lock(&client->modeset_mutex); > if (drm_drv_uses_atomic_modeset(dev)) > - ret = drm_client_modeset_commit_atomic(client, mode == > DRM_MODE_DPMS_ON, false); > + ret = drm_client_modeset_commit_atomic(client, mode == > DRM_MODE_DPMS_ON); > else > drm_client_modeset_dpms_legacy(client, mode); > mutex_unlock(&client->modeset_mutex); > diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h > index bc0e66f9c425..ead3c3526ee3 100644 > --- a/include/drm/drm_client.h > +++ b/include/drm/drm_client.h > @@ -177,7 +177,6 @@ int drm_client_modeset_create(struct drm_client_dev > *client); > void drm_client_modeset_free(struct drm_client_dev *client); > int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int > width, unsigned int height); > bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int > *rotation); > -int drm_client_modeset_check(struct drm_client_dev *client); > int drm_client_modeset_commit_locked(struct drm_client_dev *client); > int drm_client_modeset_commit(struct drm_client_dev *client); > int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); > -- > 2.47.0 > -- With best wishes Dmitry
[PATCH 2/3] drm/msm: move MAX_H_TILES_PER_DISPLAY to the DPU driver
The MAX_H_TILES_PER_DISPLAY const is only used by the DPU driver, move it to the corresponding header. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 ++ drivers/gpu/drm/msm/msm_drv.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index f7465a1774aa..6c4f3d7dfbb1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -19,6 +19,8 @@ #define IDLE_TIMEOUT (66 - 16/2) +#define MAX_H_TILES_PER_DISPLAY 2 + /** * struct msm_display_info - defines display properties * @intf_type: INTF_ type diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index ae3adb0f68a8..1dc161d9bf51 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -71,7 +71,6 @@ enum msm_dsi_controller { }; #define MSM_GPU_MAX_RINGS 4 -#define MAX_H_TILES_PER_DISPLAY 2 /* Commit/Event thread specific structure */ struct msm_drm_thread { -- 2.39.5
[PATCH 1/3] drm/msm: move msm_display_topology to the DPU driver
The struct msm_display_topology is only used by the DPU driver. Remove it from the global header and move it to DPU-specific header. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 16 drivers/gpu/drm/msm/msm_drv.h | 16 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index e63db8ace6b9..14220ba04a78 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -37,6 +37,22 @@ struct dpu_rm { struct dpu_hw_blk *cdm_blk; }; +/** + * struct msm_display_topology - defines a display topology pipeline + * @num_lm: number of layer mixers used + * @num_intf: number of interfaces the panel is mounted on + * @num_dspp: number of dspp blocks used + * @num_dsc: number of Display Stream Compression (DSC) blocks used + * @needs_cdm:indicates whether cdm block is needed for this display topology + */ +struct msm_display_topology { + u32 num_lm; + u32 num_intf; + u32 num_dspp; + u32 num_dsc; + bool needs_cdm; +}; + /** * dpu_rm_init - Read hardware catalog and create reservation tracking objects * for all HW blocks. diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 133e47bea7d5..ae3adb0f68a8 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -73,22 +73,6 @@ enum msm_dsi_controller { #define MSM_GPU_MAX_RINGS 4 #define MAX_H_TILES_PER_DISPLAY 2 -/** - * struct msm_display_topology - defines a display topology pipeline - * @num_lm: number of layer mixers used - * @num_intf: number of interfaces the panel is mounted on - * @num_dspp: number of dspp blocks used - * @num_dsc: number of Display Stream Compression (DSC) blocks used - * @needs_cdm:indicates whether cdm block is needed for this display topology - */ -struct msm_display_topology { - u32 num_lm; - u32 num_intf; - u32 num_dspp; - u32 num_dsc; - bool needs_cdm; -}; - /* Commit/Event thread specific structure */ struct msm_drm_thread { struct drm_device *dev; -- 2.39.5
[PATCH 0/3] drm/msm: minor msm_drv.h cleanup
As I stumbled upon msm_display_topology define, perform minor cleanup of msm_drv.h incldue file. Signed-off-by: Dmitry Baryshkov --- Dmitry Baryshkov (3): drm/msm: move msm_display_topology to the DPU driver drm/msm: move MAX_H_TILES_PER_DISPLAY to the DPU driver drm/msm: drop MAX_BRIDGES define drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 16 drivers/gpu/drm/msm/msm_drv.h | 18 -- 3 files changed, 18 insertions(+), 18 deletions(-) --- base-commit: 4a6fd06643afa99989a0e6b848e125099674227b change-id: 20241031-dpu-move-topology-f5c4489830bd Best regards, -- Dmitry Baryshkov
Re: [PATCH v3 03/23] drm/msm/dpu: get rid of struct dpu_rm_requirements
On Wed, Oct 16, 2024 at 06:21:09PM -0700, Jessica Zhang wrote: > From: Dmitry Baryshkov > > The struct dpu_rm_requirements was used to wrap display topology and > hw resources, which meant INTF indices. As of commit ef58e0ad3436 > ("drm/msm/dpu: get INTF blocks directly rather than through RM") the hw > resources struct was removed, leaving struct dpu_rm_requirements > containing a single field (topology). Remove the useless wrapper. > > Signed-off-by: Dmitry Baryshkov > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 71 > ++--- > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 +- > 3 files changed, 25 insertions(+), 50 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index > 3b171bf227d16f301545eefeac1e2bf61085b218..6293e716a1c3ae8ba07c0ee76f61766fdaab0710 > 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -691,7 +691,7 @@ static int dpu_encoder_virt_atomic_check( > > if (!crtc_state->active_changed || crtc_state->enable) > ret = dpu_rm_reserve(&dpu_kms->rm, global_state, > - drm_enc, crtc_state, topology); > + drm_enc, crtc_state, &topology); > } > > trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > index > 44938ba7a2b7e618735447e0af51e91f9fa3242a..8193c3d579dfc86b0fb8395ba60b7b1f5137413f > 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > @@ -4,6 +4,7 @@ > * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. > */ > > +#include "msm_drv.h" pr_fmt should be defined before all the includes. And anyway, we should probably move msm_display_topology to the DPU-specific header. > #define pr_fmt(fmt) "[drm:%s] " fmt, __func__ > #include "dpu_kms.h" > #include "dpu_hw_lm.h" > @@ -26,14 +27,6 @@ static inline bool reserved_by_other(uint32_t *res_map, > int idx, > return res_map[idx] && res_map[idx] != enc_id; > } > > -/** > - * struct dpu_rm_requirements - Reservation requirements parameter bundle > - * @topology: selected topology for the display > - */ > -struct dpu_rm_requirements { > - struct msm_display_topology topology; > -}; > - > int dpu_rm_init(struct drm_device *dev, > struct dpu_rm *rm, > const struct dpu_mdss_cfg *cat, > @@ -231,14 +224,13 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int > primary_idx) > * mixer in rm->pingpong_blks[]. > * @dspp_idx: output parameter, index of dspp block attached to the layer > * mixer in rm->dspp_blks[]. > - * @reqs: input parameter, rm requirements for HW blocks needed in the > - * datapath. > + * @topology: selected topology for the display > * Return: true if lm matches all requirements, false otherwise > */ > static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, > struct dpu_global_state *global_state, > uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx, > - struct dpu_rm_requirements *reqs) > + struct msm_display_topology *topology) > { > const struct dpu_lm_cfg *lm_cfg; > int idx; > @@ -263,7 +255,7 @@ static bool > _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, > } > *pp_idx = idx; > > - if (!reqs->topology.num_dspp) > + if (!topology->num_dspp) > return true; > > idx = lm_cfg->dspp - DSPP_0; > @@ -285,7 +277,7 @@ static bool > _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, > static int _dpu_rm_reserve_lms(struct dpu_rm *rm, > struct dpu_global_state *global_state, > uint32_t enc_id, > -struct dpu_rm_requirements *reqs) > +struct msm_display_topology *topology) > > { > int lm_idx[MAX_BLOCKS]; > @@ -293,14 +285,14 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, > int dspp_idx[MAX_BLOCKS] = {0}; > int i, lm_count = 0; > > - if (!reqs->topology.num_lm) { > - DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm); > + if (!topology->num_
Re: [PATCH v18 6/8] phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
On Tue, Oct 29, 2024 at 02:02:14PM +0800, Sandor Yu wrote: > Add Cadence HDP-TX DisplayPort and HDMI PHY driver for i.MX8MQ. > > Cadence HDP-TX PHY could be put in either DP mode or > HDMI mode base on the configuration chosen. > DisplayPort or HDMI PHY mode is configured in the driver. > > Signed-off-by: Sandor Yu > Signed-off-by: Alexander Stein > --- > v17->v18: > - fix build error as code rebase to latest kernel version. > > drivers/phy/freescale/Kconfig| 10 + > drivers/phy/freescale/Makefile |1 + > drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1337 ++ > 3 files changed, 1348 insertions(+) > create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c > > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig > index dcd9acff6d01a..2b1210367b31c 100644 > --- a/drivers/phy/freescale/Kconfig > +++ b/drivers/phy/freescale/Kconfig > @@ -35,6 +35,16 @@ config PHY_FSL_IMX8M_PCIE > Enable this to add support for the PCIE PHY as found on > i.MX8M family of SOCs. > > +config PHY_FSL_IMX8MQ_HDPTX > + tristate "Freescale i.MX8MQ DP/HDMI PHY support" > + depends on OF && HAS_IOMEM > + depends on COMMON_CLK > + select GENERIC_PHY > + select CDNS_MHDP_HELPER This can have problems with being satisfied on randconfig builds, because CDNS_MHDP_HELPER is deep inside the DRM tree. > + help > + Enable this to support the Cadence HDPTX DP/HDMI PHY driver > + on i.MX8MQ SOC. > + > config PHY_FSL_IMX8QM_HSIO > tristate "Freescale i.MX8QM HSIO PHY" > depends on OF && HAS_IOMEM > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile > index 658eac7d0a622..a946b87905498 100644 > --- a/drivers/phy/freescale/Makefile > +++ b/drivers/phy/freescale/Makefile > @@ -1,4 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > +obj-$(CONFIG_PHY_FSL_IMX8MQ_HDPTX) += phy-fsl-imx8mq-hdptx.o > obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o > obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o > obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)+= phy-fsl-imx8-mipi-dphy.o > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c > b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c > new file mode 100644 > index 0..7aac39df0ab02 > --- /dev/null > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c > @@ -0,0 +1,1337 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Cadence DP/HDMI PHY driver > + * > + * Copyright (C) 2022-2024 NXP Semiconductor, Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define ADDR_PHY_AFE 0x8 > + > +/* PHY registers */ > +#define CMN_SSM_BIAS_TMR 0x0022 > +#define CMN_PLLSM0_PLLEN_TMR 0x0029 > +#define CMN_PLLSM0_PLLPRE_TMR0x002a > +#define CMN_PLLSM0_PLLVREF_TMR 0x002b > +#define CMN_PLLSM0_PLLLOCK_TMR 0x002c > +#define CMN_PLLSM0_USER_DEF_CTRL 0x002f > +#define CMN_PSM_CLK_CTRL 0x0061 > +#define CMN_CDIAG_REFCLK_CTRL0x0062 > +#define CMN_PLL0_VCOCAL_START0x0081 > +#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084 > +#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085 > +#define CMN_PLL0_INTDIV 0x0094 > +#define CMN_PLL0_FRACDIV 0x0095 > +#define CMN_PLL0_HIGH_THR0x0096 > +#define CMN_PLL0_DSM_DIAG0x0097 > +#define CMN_PLL0_SS_CTRL20x0099 > +#define CMN_ICAL_INIT_TMR0x00c4 > +#define CMN_ICAL_ITER_TMR0x00c5 > +#define CMN_RXCAL_INIT_TMR 0x00d4 > +#define CMN_RXCAL_ITER_TMR 0x00d5 > +#define CMN_TXPUCAL_CTRL 0x00e0 > +#define CMN_TXPUCAL_INIT_TMR 0x00e4 > +#define CMN_TXPUCAL_ITER_TMR 0x00e5 > +#define CMN_TXPDCAL_CTRL 0x00f0 > +#define CMN_TXPDCAL_INIT_TMR 0x00f4 > +#define CMN_TXPDCAL_ITER_TMR 0x00f5 > +#define CMN_ICAL_ADJ_INIT_TMR0x0102 > +#define CMN_ICAL_ADJ_ITER_TMR0x0103 > +#define CMN_RX_ADJ_INIT_TMR 0x0106 > +#define CMN_RX_ADJ_ITER_TMR 0x0107 > +#define CMN_TXPU_ADJ_CTRL0x0108 > +#define CMN_TXPU_ADJ_INIT_TMR0x010a > +#define CMN_TXPU_ADJ_ITER_TMR0x010b > +#define CMN_TXPD_ADJ_CTRL0x010c > +#define CMN_TXPD_ADJ_INIT_TMR0x010e > +#define CMN_TXPD_ADJ_ITER_TMR0x010f > +#define CMN_DIAG_PLL0_FBH_OVRD 0x01c0 > +#define CMN_DIAG_PLL0_FBL_OVRD 0x01c1 > +#define CMN_DIAG_PLL0_OVRD 0x01c2 > +#define
Re: [PATCH v3 05/23] drm/msm/dpu: move resource allocation to CRTC
On Thu, Oct 31, 2024 at 12:37:03PM -0700, Abhinav Kumar wrote: > > > On 10/16/2024 6:21 PM, Jessica Zhang wrote: > > From: Dmitry Baryshkov > > > > All resource allocation is centered around the LMs. Then other blocks > > (except DSCs) are allocated basing on the LMs that was selected, and LM > > powers up the CRTC rather than the encoder. > > > > Moreover if at some point the driver supports encoder cloning, > > allocating resources from the encoder will be incorrect, as all clones > > will have different encoder IDs, while LMs are to be shared by these > > encoders. > > > > Signed-off-by: Dmitry Baryshkov > > [quic_abhin...@quicinc.com: Refactored resource allocation for CDM] > > Signed-off-by: Abhinav Kumar > > [quic_jessz...@quicinc.com: Changed to grabbing exising global state] > > Signed-off-by: Jessica Zhang > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 86 > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 > > +++- > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++ > > 3 files changed, 183 insertions(+), 123 deletions(-) > > > > > > > - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */ > > + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */ > > if (dpu_enc->dsc) > > - num_dsc = 2; > > + topology->num_dsc += 2; > > - return (num_dsc > 0) && (num_dsc > intf_count); > > -} > > I dont recall the context of replacing num_dsc = 2 with num_dsc += 2 > and its not documented. > > > > > + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */ > > + if (dpu_enc->dsc) > > + num_dsc += 2; > > - return topology; > > + return (num_dsc > 0) && (num_dsc > num_intf); > > } > > Same here > > This should not break anything with current code. We could land it the way > it is as this was the version which was last tested and post a follow up if > this was not right. Something to be documented though, hope this note serves > that purpose. Rest of the change LGTM, As this is supposed to be a refactor, I'll land it as num_dsc = 2 and let Jessica fix it in the followup patches. I think it's better this way. > > Reviewed-by: Abhinav Kumar -- With best wishes Dmitry
Re: [PATCH v6 7/9] drm/msm/dpu: add support for virtual planes
On Thu, Oct 31, 2024 at 01:06:34PM -0700, Abhinav Kumar wrote: > > > On 10/31/2024 8:11 AM, Dmitry Baryshkov wrote: > > Hi Abhinav, > > > > On Wed, 30 Oct 2024 at 21:26, Abhinav Kumar > > wrote: > > > > > > > > > > > > On 10/30/2024 3:48 AM, Dmitry Baryshkov wrote: > > > > On Tue, Oct 29, 2024 at 02:30:12PM -0700, Abhinav Kumar wrote: > > > > > > > > > > > > > > > On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > > > > > Only several SSPP blocks support such features as YUV output or > > > > > > scaling, > > > > > > thus different DRM planes have different features. Properly > > > > > > utilizing > > > > > > all planes requires the attention of the compositor, who should > > > > > > prefer simpler planes to YUV-supporting ones. Otherwise it is very > > > > > > easy > > > > > > to end up in a situation when all featureful planes are already > > > > > > allocated for simple windows, leaving no spare plane for YUV > > > > > > playback. > > > > > > > > > > > > To solve this problem make all planes virtual. Each plane is > > > > > > registered > > > > > > as if it supports all possible features, but then at the runtime > > > > > > during > > > > > > the atomic_check phase the driver selects backing SSPP block for > > > > > > each > > > > > > plane. > > > > > > > > > > > > As the planes are attached to the CRTC and not the encoder, the SSPP > > > > > > blocks are also allocated per CRTC ID (all other resources are > > > > > > currently > > > > > > allocated per encoder ID). This also matches the hardware > > > > > > requirement, > > > > > > where both rectangles of a single SSPP can only be used with the LM > > > > > > pair. > > > > > > > > > > > > Note, this does not provide support for using two different SSPP > > > > > > blocks > > > > > > for a single plane or using two rectangles of an SSPP to drive two > > > > > > planes. Each plane still gets its own SSPP and can utilize either a > > > > > > solo > > > > > > rectangle or both multirect rectangles depending on the resolution. > > > > > > > > > > > > Note #2: By default support for virtual planes is turned off and the > > > > > > driver still uses old code path with preallocated SSPP block for > > > > > > each > > > > > > plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1' > > > > > > kernel parameter. > > > > > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > > > --- > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 237 > > > > > > ++ > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 16 ++ > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 68 + > > > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 27 > > > > > > 7 files changed, 383 insertions(+), 29 deletions(-) > > > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > > > > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > > > > > index 58595dcc3889..a7eea094aa14 100644 > > > > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > > > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > > > > > @@ -1166,6 +1166,49 @@ static bool dpu_crtc_needs_dirtyfb(struct > > > > > > drm_crtc_state *cstate) > > > > > > return false; > > > > > > } > > > > > > +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct > > > > > > drm_crtc_state *crtc_state) > > > > > > +{ > > > > > > + int total_planes = crtc->dev->mode_config.num_total_pl
Re: [PATCH v18 3/8] dt-bindings: display: bridge: Add Cadence MHDP8501
On Thu, Oct 31, 2024 at 09:55:45PM +0200, Dmitry Baryshkov wrote: > On Tue, Oct 29, 2024 at 02:02:11PM +0800, Sandor Yu wrote: > > Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge. > > > > Signed-off-by: Sandor Yu > > --- > > v17->v18: > > - remove lane-mapping and replace it with data-lanes > > - remove r-b tag as property changed. > > > > v16->v17: > > - Add lane-mapping property > > > > v9->v16: > > *No change > > > > .../display/bridge/cdns,mhdp8501.yaml | 112 ++ > > 1 file changed, 112 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > > b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > > new file mode 100644 > > index 0..e4b900ecf1ac9 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > > @@ -0,0 +1,112 @@ > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Cadence MHDP8501 DP/HDMI bridge > > + > > +maintainers: > > + - Sandor Yu > > + > > +description: > > + Cadence MHDP8501 DisplayPort/HDMI interface. > > + > > +properties: > > + compatible: > > +enum: > > + - fsl,imx8mq-mhdp8501 > > + > > + reg: > > +maxItems: 1 > > + > > + clocks: > > +maxItems: 1 > > +description: MHDP8501 DP/HDMI APB clock. > > + > > + phys: > > +maxItems: 1 > > +description: > > + phandle to the DP/HDMI PHY > > + > > + interrupts: > > +items: > > + - description: Hotplug cable plugin. > > + - description: Hotplug cable plugout. > > + > > + interrupt-names: > > +items: > > + - const: plug_in > > + - const: plug_out > > + > > + data-lanes: > > +$ref: /schemas/media/video-interfaces.yaml#/properties/data-lanes > > +minItems: 4 > > +maxItems: 4 > > +description: Lane reordering for HDMI or DisplayPort interface. > > So, HDMI or DP port? I don't think the format is actually the same, so > it is either-or. Please ignore this, I've misread the text. -- With best wishes Dmitry
Re: [PATCH v3 05/23] drm/msm/dpu: move resource allocation to CRTC
On Wed, Oct 16, 2024 at 06:21:11PM -0700, Jessica Zhang wrote: > From: Dmitry Baryshkov > > All resource allocation is centered around the LMs. Then other blocks > (except DSCs) are allocated basing on the LMs that was selected, and LM > powers up the CRTC rather than the encoder. > > Moreover if at some point the driver supports encoder cloning, > allocating resources from the encoder will be incorrect, as all clones > will have different encoder IDs, while LMs are to be shared by these > encoders. > > Signed-off-by: Dmitry Baryshkov > [quic_abhin...@quicinc.com: Refactored resource allocation for CDM] > Signed-off-by: Abhinav Kumar > [quic_jessz...@quicinc.com: Changed to grabbing exising global state] > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 86 > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 > +++- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++ > 3 files changed, 183 insertions(+), 123 deletions(-) > I tried applying the seamingly ready part of the series (patches 3-12), but this one fails with too many rejects because of the 3ae133b0192b ("drm/msm/dpu: move CRTC resource assignment to dpu_encoder_virt_atomic_check"), which we picked through msm-fixes. Unfortunately I can not pick those without a preliminary rebase and cross-check of this patch and the next one. -- With best wishes Dmitry
Re: [PATCH 1/1] dt-bindings: display: nwl-dsi: Allow 'data-lanes' property for port@1
On Thu, Oct 31, 2024 at 04:20:10PM -0400, Frank Li wrote: > On Thu, Oct 31, 2024 at 09:59:26PM +0200, Dmitry Baryshkov wrote: > > On Thu, Oct 31, 2024 at 03:47:14PM -0400, Frank Li wrote: > > > Change $ref of port@1 from 'port' to 'port-base' and add 'endpoint' > > > property referencing video-interfaces.yaml. Allow 'data-lanes' values > > > 1, 2, 3, and 4 for port@1. > > > > > > Fix below CHECK_DTB warnings: > > > arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtb: > > > dsi@30a0: ports:port@1:endpoint: Unevaluated properties are not > > > allowed ('data-lanes' was unexpected) > > > > > > Signed-off-by: Frank Li > > > --- > > > .../bindings/display/bridge/nwl-dsi.yaml | 18 +- > > > 1 file changed, 17 insertions(+), 1 deletion(-) > > > > > > diff --git > > > a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > > > b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > > > index 350fb8f400f02..5952e6448ed47 100644 > > > --- a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > > > +++ b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > > > @@ -111,11 +111,27 @@ properties: > > > unevaluatedProperties: false > > > > > >port@1: > > > -$ref: /schemas/graph.yaml#/properties/port > > > +$ref: /schemas/graph.yaml#/$defs/port-base > > > +unevaluatedProperties: false > > > description: > > >DSI output port node to the panel or the next bridge > > >in the chain > > > > > > +properties: > > > + endpoint: > > > +$ref: /schemas/media/video-interfaces.yaml# > > > +unevaluatedProperties: false > > > + > > > +properties: > > > + data-lanes: > > > +description: array of physical DSI data lane indexes. > > > +minItems: 1 > > > +items: > > > + - const: 1 > > > + - const: 2 > > > + - const: 3 > > > + - const: 4 > > > > Why are they indexed starting from 1? > > Not sure, git grep -r data-lanes Documentation/devicetree/bindings/ > Most start from 1. Not sure latest DT team's intention. They usually start from 1, because just before the property comes 'clock-lanes = <0>'. Otherwise in most of the cases the lanes are indexed from 0. > > Frank > > > > > > + > > > required: > > >- port@0 > > >- port@1 > > > -- > > > 2.34.1 > > > > > > > -- > > With best wishes > > Dmitry -- With best wishes Dmitry
Re: [PATCH v18 3/8] dt-bindings: display: bridge: Add Cadence MHDP8501
On Tue, Oct 29, 2024 at 02:02:11PM +0800, Sandor Yu wrote: > Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge. > > Signed-off-by: Sandor Yu > --- > v17->v18: > - remove lane-mapping and replace it with data-lanes > - remove r-b tag as property changed. > > v16->v17: > - Add lane-mapping property > > v9->v16: > *No change > > .../display/bridge/cdns,mhdp8501.yaml | 112 ++ > 1 file changed, 112 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > > diff --git > a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > new file mode 100644 > index 0..e4b900ecf1ac9 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml > @@ -0,0 +1,112 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Cadence MHDP8501 DP/HDMI bridge > + > +maintainers: > + - Sandor Yu > + > +description: > + Cadence MHDP8501 DisplayPort/HDMI interface. > + > +properties: > + compatible: > +enum: > + - fsl,imx8mq-mhdp8501 > + > + reg: > +maxItems: 1 > + > + clocks: > +maxItems: 1 > +description: MHDP8501 DP/HDMI APB clock. > + > + phys: > +maxItems: 1 > +description: > + phandle to the DP/HDMI PHY > + > + interrupts: > +items: > + - description: Hotplug cable plugin. > + - description: Hotplug cable plugout. > + > + interrupt-names: > +items: > + - const: plug_in > + - const: plug_out > + > + data-lanes: > +$ref: /schemas/media/video-interfaces.yaml#/properties/data-lanes > +minItems: 4 > +maxItems: 4 > +description: Lane reordering for HDMI or DisplayPort interface. So, HDMI or DP port? I don't think the format is actually the same, so it is either-or. > + > + ports: > +$ref: /schemas/graph.yaml#/properties/ports > + > +properties: > + port@0: > +$ref: /schemas/graph.yaml#/properties/port > +description: > + Input port from display controller output. > + port@1: > +$ref: /schemas/graph.yaml#/properties/port > +description: > + Output port to DisplayPort or HDMI connector. > + > +required: > + - port@0 > + - port@1 > + > +required: > + - compatible > + - reg > + - clocks > + - interrupts > + - interrupt-names > + - phys > + - data-lanes > + - ports > + > +additionalProperties: false > + > +examples: > + - | > +#include > +#include > + > +mhdp: display-bridge@32c0 { > +compatible = "fsl,imx8mq-mhdp8501"; > +reg = <0x32c0 0x10>; > +interrupts = , > + ; > +interrupt-names = "plug_in", "plug_out"; > +clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>; > +phys = <&mdhp_phy>; > +data-lanes = <1 2 3 4>; 0 1 2 3 > + > +ports { > +#address-cells = <1>; > +#size-cells = <0>; > + > +port@0 { > +reg = <0>; > + > +mhdp_in: endpoint { > +remote-endpoint = <&dcss_out>; > +}; > +}; > + > +port@1 { > +reg = <1>; > + > +mhdp_out: endpoint { > +remote-endpoint = <&dp_connector>; > +}; > +}; > +}; > +}; > -- > 2.34.1 > -- With best wishes Dmitry
Re: [PATCH 1/1] dt-bindings: display: nwl-dsi: Allow 'data-lanes' property for port@1
On Thu, Oct 31, 2024 at 03:47:14PM -0400, Frank Li wrote: > Change $ref of port@1 from 'port' to 'port-base' and add 'endpoint' > property referencing video-interfaces.yaml. Allow 'data-lanes' values > 1, 2, 3, and 4 for port@1. > > Fix below CHECK_DTB warnings: > arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtb: > dsi@30a0: ports:port@1:endpoint: Unevaluated properties are not allowed > ('data-lanes' was unexpected) > > Signed-off-by: Frank Li > --- > .../bindings/display/bridge/nwl-dsi.yaml | 18 +- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > index 350fb8f400f02..5952e6448ed47 100644 > --- a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > +++ b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml > @@ -111,11 +111,27 @@ properties: > unevaluatedProperties: false > >port@1: > -$ref: /schemas/graph.yaml#/properties/port > +$ref: /schemas/graph.yaml#/$defs/port-base > +unevaluatedProperties: false > description: >DSI output port node to the panel or the next bridge >in the chain > > +properties: > + endpoint: > +$ref: /schemas/media/video-interfaces.yaml# > +unevaluatedProperties: false > + > +properties: > + data-lanes: > +description: array of physical DSI data lane indexes. > +minItems: 1 > +items: > + - const: 1 > + - const: 2 > + - const: 3 > + - const: 4 Why are they indexed starting from 1? > + > required: >- port@0 >- port@1 > -- > 2.34.1 > -- With best wishes Dmitry
Re: [PATCH v18 1/8] drm: bridge: Cadence: Create MHDP helper driver
On Tue, Oct 29, 2024 at 02:02:09PM +0800, Sandor Yu wrote: > Mailbox access functions in MHDP8546 will be share to other MHDP driver > and Cadence HDP-TX HDMI/DP PHY drivers. > > Create a new MHDP helper driver and move all mailbox access functions into. > According the mailbox access sequence and type of security. > Six mailbox access API functions are introduced. > Three APIs for non-secure mailbox access: > - cdns_mhdp_mailbox_send() > - cdns_mhdp_mailbox_send_recv() > - cdns_mhdp_mailbox_send_recv_multi() > The other three APIs for secure mailbox access: > - cdns_mhdp_secure_mailbox_send() > - cdns_mhdp_secure_mailbox_send_recv() > - cdns_mhdp_secure_mailbox_send_recv_multi() > > All MHDP commands that need to be passed through the mailbox > have been rewritten using those new API functions. > > The register read/write and DP DPCD read/write command functions > are also included in this new helper driver. > > Function cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(), > because it use the DPTX command ID DPTX_WRITE_REGISTER. > New cdns_mhdp_reg_write() is added with the general command ID > GENERAL_REGISTER_WRITE. > > Signed-off-by: Sandor Yu > --- > v17->v18: > - Create three ordinary mailbox access APIs > cdns_mhdp_mailbox_send > cdns_mhdp_mailbox_send_recv > cdns_mhdp_mailbox_send_recv_multi > - Create three secure mailbox access APIs > cdns_mhdp_secure_mailbox_send > cdns_mhdp_secure_mailbox_send_recv > cdns_mhdp_secure_mailbox_send_recv_multi > - MHDP8546 DP and HDCP commands that need access mailbox are rewrited > with above 6 API functions. > > v16->v17: > - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex > > v12->v16: > *No change. > > drivers/gpu/drm/bridge/cadence/Kconfig| 4 + > drivers/gpu/drm/bridge/cadence/Makefile | 1 + > .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 414 +++ > .../drm/bridge/cadence/cdns-mhdp8546-core.c | 487 +++--- > .../drm/bridge/cadence/cdns-mhdp8546-core.h | 47 +- > .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c | 236 + > .../drm/bridge/cadence/cdns-mhdp8546-hdcp.h | 18 +- > include/drm/bridge/cdns-mhdp-helper.h | 130 + > 8 files changed, 658 insertions(+), 679 deletions(-) > create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c > create mode 100644 include/drm/bridge/cdns-mhdp-helper.h > > diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig > b/drivers/gpu/drm/bridge/cadence/Kconfig > index cced81633ddcd..e0973339e9e33 100644 > --- a/drivers/gpu/drm/bridge/cadence/Kconfig > +++ b/drivers/gpu/drm/bridge/cadence/Kconfig > @@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E > the routing of the DSS DPI signal to the Cadence DSI. > endif > > +config CDNS_MHDP_HELPER > + tristate > + I'm not sure if the placement for the helper is suitable. Especially if you want to reuse the helper by some other subsystem. As far as I don't like it, maybe drivers/soc is a better option. > config DRM_CDNS_MHDP8546 > tristate "Cadence DPI/DP bridge" > select DRM_DISPLAY_DP_HELPER > @@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546 > select DRM_DISPLAY_HELPER > select DRM_KMS_HELPER > select DRM_PANEL_BRIDGE > + select CDNS_MHDP_HELPER > depends on OF > help > Support Cadence DPI to DP bridge. This is an internal > diff --git a/drivers/gpu/drm/bridge/cadence/Makefile > b/drivers/gpu/drm/bridge/cadence/Makefile > index c95fd5b81d137..087dc074820d7 100644 > --- a/drivers/gpu/drm/bridge/cadence/Makefile > +++ b/drivers/gpu/drm/bridge/cadence/Makefile > @@ -2,6 +2,7 @@ > obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o > cdns-dsi-y := cdns-dsi-core.o > cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o > +obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o > obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o > cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o > cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c > new file mode 100644 > index 0..f39228a78c7cb > --- /dev/null > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c > @@ -0,0 +1,414 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc. > + * > + */ > +#include > +#include > +#include > + > +/* Protects mailbox communications with the firmware */ > +static DEFINE_MUTEX(mhdp_mailbox_mutex); > + > +/* Mailbox helper functions */ > +static int mhdp_mailbox_read(void __iomem *regs) > +{ > + int ret, empty; > + > + WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex)); > + > + ret = readx_poll_timeout(readl, regs + CDNS_MAILBOX_EMPTY, > + empty, !empty, MAILBOX_RETRY_US, > + MAILBOX_TIMEOUT_US); > + if (ret < 0)
Re: [PATCH] drm/bridge: it6505: Fix inverted reset polarity
On Tue, Oct 29, 2024 at 05:54:10PM +0800, Chen-Yu Tsai wrote: > The IT6505 bridge chip has a active low reset line. Since it is a > "reset" and not an "enable" line, the GPIO should be asserted to > put it in reset and deasserted to bring it out of reset during > the power on sequence. > > The polarity was inverted when the driver was first introduced, likely > because the device family that was targeted had an inverting level > shifter on the reset line. > > The MT8186 Corsola devices already have the IT6505 in their device tree, > but the whole display pipeline is actually disabled and won't be enabled > until some remaining issues are sorted out. The other known user is > the MT8183 Kukui / Jacuzzi family; their device trees currently do not > have the IT6505 included. > > Fix the polarity in the driver while there are no actual users. > > Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") > Cc: > Signed-off-by: Chen-Yu Tsai > --- > drivers/gpu/drm/bridge/ite-it6505.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) The datasheet describes the pin as Active LOW, so the change seems to be correct. Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH libdrm] modetest: Make modetest availble to vendor on Android
On Tue, Oct 29, 2024 at 02:43:05PM +, Rob Barnes wrote: > Make modetest available to vendors on Android. libdrm_util and > libdrm_test_headers is also made available to vendors since these are > depenencies of modetest. This results in the module target > modetest.vendor being availble to vendor modules. > > Signed-off-by: Rob Barnes > --- > tests/Android.bp | 1 + > tests/modetest/Android.bp | 1 + > tests/util/Android.bp | 1 + > 3 files changed, 3 insertions(+) > Acked-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [RFC PATCH] i2c: skip of_i2c_register_device() for invalid child nodes
On Thu, Oct 31, 2024 at 11:45:53AM -0700, Abhinav Kumar wrote: > > > On 10/31/2024 11:23 AM, Dmitry Baryshkov wrote: > > On Wed, 30 Oct 2024 at 03:07, Abhinav Kumar > > wrote: > > > > > > of_i2c_register_devices() adds all child nodes of a given i2c bus > > > however in certain device trees of_alias_from_compatible() and > > > of_property_read_u32() can fail as the child nodes of the device > > > might not be valid i2c client devices. One such example is the > > > i2c aux device for the DRM MST toplogy manager which uses the > > > display controller device node to add the i2c adaptor [1] leading > > > to an error spam like below > > > > > > i2c i2c-20: of_i2c: register > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > > > i2c i2c-20: of_i2c: modalias failure on > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > > > i2c i2c-20: Failed to create I2C device for > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > > > i2c i2c-20: of_i2c: register > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > > > i2c i2c-20: of_i2c: invalid reg on > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > > > i2c i2c-20: Failed to create I2C device for > > > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > > > > > > Add protection against invalid child nodes before trying to register > > > i2c devices for all child nodes. > > > > > > [1] : > > > https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/display/drm_dp_mst_topology.c#L5985 > > > > > > Signed-off-by: Abhinav Kumar > > > --- > > > drivers/i2c/i2c-core-of.c | 6 ++ > > > 1 file changed, 6 insertions(+) > > > > > > diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c > > > index a6c407d36800..62a2603c3092 100644 > > > --- a/drivers/i2c/i2c-core-of.c > > > +++ b/drivers/i2c/i2c-core-of.c > > > @@ -86,6 +86,8 @@ void of_i2c_register_devices(struct i2c_adapter *adap) > > > { > > > struct device_node *bus, *node; > > > struct i2c_client *client; > > > + u32 addr; > > > + char temp[16]; > > > > > > /* Only register child devices if the adapter has a node pointer > > > set */ > > > if (!adap->dev.of_node) > > > @@ -101,6 +103,10 @@ void of_i2c_register_devices(struct i2c_adapter > > > *adap) > > > if (of_node_test_and_set_flag(node, OF_POPULATED)) > > > continue; > > > > > > + if (of_property_read_u32(node, "reg", &addr) || > > > + of_alias_from_compatible(node, temp, sizeof(temp))) > > > + continue; > > > > I think just of_property_read_u32() should be enough to skip > > non-I2C-device children. If of_alias_from_compatible() fails, it is a > > legit error. > > > > Thanks for the review. > > of_alias_from_compatible() looks for a compatible string but all child nodes > such as ports will not have the compatible. Hence below error will still be > seen: > > i2c i2c-20: of_i2c: modalias failure on > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports But ports node don't have a reg property too, so it should be skipped based on that. > > > > + > > > client = of_i2c_register_device(adap, node); > > > if (IS_ERR(client)) { > > > dev_err(&adap->dev, > > > -- > > > 2.34.1 > > > > > > > -- With best wishes Dmitry
Re: [PATCH v4 15/18] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode
On Tue, Oct 29, 2024 at 01:15:51PM -0700, Stephen Boyd wrote: > Quoting Dmitry Baryshkov (2024-10-25 03:49:36) > > On Tue, Oct 22, 2024 at 06:15:47PM -0700, Stephen Boyd wrote: > > > Quoting Dmitry Baryshkov (2024-09-20 02:38:53) > > > > On Sat, Aug 31, 2024 at 09:06:53PM GMT, Stephen Boyd wrote: > > > > > > > > Either way the problem seems to be that I need to associate one > > > drm_bridge with two displayport altmode drivers and pass some fwnode > > > handle to drm_connector_oob_hotplug_event() in a way that we can map > > > that back to the right output endpoint in the DP bridge graph. That > > > seems to imply that we need to pass the fwnode for the usb-c-connector > > > in addition to the fwnode for the drm_bridge, so that the drm_bridge > > > code can look at its DT graph and find the remote node connected. > > > Basically something like this: > > > > > > void drm_connector_oob_hotplug_event(struct fwnode_handle > > > *connector_fwnode, > > >struct fwnode_handle > > > *usb_connector_fwnode, > > >enum drm_connector_status status) > > > > > > (We might as well also pass the number of lanes here) > > > > I think this is a bit of an overkill. > > > > The drm_connector_oob_hotplug_event() is fine as it is, it gets > > "fwnode_handle to report the event on". > > Ok. I understand that drm_*() shouldn't know about USB or type-c in > general. > > > > > What needs to be changed (in my humble opinion) is the > > drm_connector_find_by_fwnode() function (or likely a new function is to > > be added): if it can not find drm_connector for the passed fwnode, it > > should look it up on the parent, then on parent's parent, etc, until we > > actually find the drm_connector (good) or we reach the root (sad). > > > > And finally after getting the drm_connector, the oob_hotplug_event() > > callback should also receive the fwnode argument. This way the connector > > (or the bridge) can identify the fwnode (aka usb-c-connector in our > > case) that caused the event. > > > > WDYT? > > Ok I think I'm following along. The dp->connector_fwnode in > displayport.c will always be the usb-c-connector node in your example? > And that will search for the connector or bridge associated with that > usb-c-connector node. Then when it comes time to call > drm_connector_oob_hotplug_event() it will take the usb-c-connector > fwnode as 'connector_fwnode' and in that function we'll make > drm_connector_find_by_fwnode() implement the parent walk? The > cros-ec-typec compatible node will register a drm_bridge in all cases, > and that is the parent of the usb-c-connector node, so the walk will end > there. > > Then you want to pass the usb-c-connector fwnode to > connector->funcs->oob_hotplug_event()? So > drm_bridge_connector_oob_hotplug_event() changes to also get the > usb-c-connector fwnode. This plan should work. Yes, that was my proposal. This way we know the origin device (bridge / connector) and let it take care of any details on its own. > At this point we need to tell the DP bridge, like IT6505, that it's one > or the other output endpoints that it should use, but we haven't > directly connected the usb-c-connector to the output ports of IT6505 > because drm_of_find_panel_or_bridge() can't find the parent of the > usb-c-connector if we connect the DP bridge to the usb-c-connector > graphs. We'll need a way for the bridge to know which output port is > connected to a usb-c-connector fwnode. Some sort of API like I think that the final bridge should be the IT6505. It can save you from some troubles, like the inter-bridge lane negotiation. Please remember that using lanes 2-3 as primary lanes doesn't seem to fall into the standard DisplayPort usage. It is documented by USB-C and only because of the orientation switching. Maybe that's just it? Register DP_bridge (or QMP PHY) as orientation-switch? Then you don't need any extra API for the lane mapping? The cross-ec-typec can provide orientation information and the USB-C-aware controller will follow the lane mapping. > > fwnode_graph_get_endpoint_connected_to_fwnode(bridge_fwnode, usb_c_fwnode) > > that takes the bridge fwnode and traverses the graph to find the > endpoint in that's connected to 'usb_c_fwnode'. That traversal API will > need help from the intermediate node, cros-ec-typec, so maybe it is > better as a drm_bridge API that uses some new drm_bridge_funcs callbac
Re: [RFC PATCH] i2c: skip of_i2c_register_device() for invalid child nodes
On Wed, 30 Oct 2024 at 03:07, Abhinav Kumar wrote: > > of_i2c_register_devices() adds all child nodes of a given i2c bus > however in certain device trees of_alias_from_compatible() and > of_property_read_u32() can fail as the child nodes of the device > might not be valid i2c client devices. One such example is the > i2c aux device for the DRM MST toplogy manager which uses the > display controller device node to add the i2c adaptor [1] leading > to an error spam like below > > i2c i2c-20: of_i2c: register > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > i2c i2c-20: of_i2c: modalias failure on > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > i2c i2c-20: Failed to create I2C device for > /soc@0/display-subsystem@ae0/display-controller@ae01000/ports > i2c i2c-20: of_i2c: register > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > i2c i2c-20: of_i2c: invalid reg on > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > i2c i2c-20: Failed to create I2C device for > /soc@0/display-subsystem@ae0/display-controller@ae01000/opp-table > > Add protection against invalid child nodes before trying to register > i2c devices for all child nodes. > > [1] : > https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/display/drm_dp_mst_topology.c#L5985 > > Signed-off-by: Abhinav Kumar > --- > drivers/i2c/i2c-core-of.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c > index a6c407d36800..62a2603c3092 100644 > --- a/drivers/i2c/i2c-core-of.c > +++ b/drivers/i2c/i2c-core-of.c > @@ -86,6 +86,8 @@ void of_i2c_register_devices(struct i2c_adapter *adap) > { > struct device_node *bus, *node; > struct i2c_client *client; > + u32 addr; > + char temp[16]; > > /* Only register child devices if the adapter has a node pointer set > */ > if (!adap->dev.of_node) > @@ -101,6 +103,10 @@ void of_i2c_register_devices(struct i2c_adapter *adap) > if (of_node_test_and_set_flag(node, OF_POPULATED)) > continue; > > + if (of_property_read_u32(node, "reg", &addr) || > + of_alias_from_compatible(node, temp, sizeof(temp))) > + continue; I think just of_property_read_u32() should be enough to skip non-I2C-device children. If of_alias_from_compatible() fails, it is a legit error. > + > client = of_i2c_register_device(adap, node); > if (IS_ERR(client)) { > dev_err(&adap->dev, > -- > 2.34.1 > -- With best wishes Dmitry
Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support
On Wed, 30 Oct 2024 at 11:02, Biju Das wrote: > > Hi Dmitry Baryshkov, > > > -Original Message- > > From: Dmitry Baryshkov > > Sent: 30 October 2024 03:17 > > Subject: Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support > > > > On Tue, 29 Oct 2024 at 04:41, Liu Ying wrote: > > > > > > On 10/28/2024, Dmitry Baryshkov wrote: > > > > On Mon, Oct 28, 2024 at 11:12:00AM +, Biju Das wrote: > > > >> Hi Dmitry, Liu, > > > >> > > > >>> -Original Message- > > > >>> From: Dmitry Baryshkov > > > >>> Sent: 28 October 2024 10:20 > > > >>> Subject: Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI > > > >>> converter support > > > >>> > > > >>> Hi, > > > >>> > > > >>> On Mon, 28 Oct 2024 at 04:37, Liu Ying wrote: > > > >>>> > > > >>>> Hi, > > > >>>> > > > >>>> This patch series aims to add ITE IT6263 LVDS to HDMI converter > > > >>>> on i.MX8MP EVK. Combined with LVDS receiver and HDMI 1.4a > > > >>>> transmitter, the IT6263 supports LVDS input and HDMI 1.4 output > > > >>>> by conversion function. IT6263 product link can be found at [1]. > > > >>>> > > > >>>> Patch 1 is a preparation patch to allow display mode of an > > > >>>> existing panel to pass the added mode validation logic in patch 3. > > > >>>> > > > >>>> Patch 2 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to > > > >>>> find the next non-panel bridge, that is the IT6263 in this case. > > > >>>> > > > >>>> Patch 3 adds mode validation logic to i.MX8MP LDB bridge driver > > > >>>> against "ldb" clock so that it can filter out unsupported display > > > >>>> modes read from EDID. > > > >>>> > > > >>>> Patch 4 adds MEDIA_BUS_FMT_RGB101010_1X7X5_{SPWG,JEIDA} support, > > > >>>> as they are supported by IT6263(with LVDS data bit reversed order). > > > >>>> > > > >>>> Patch 5 makes drm_of.c use > > > >>>> MEDIA_BUS_FMT_RGB101010_1X7X5_{JEIDA,SPWG}. > > > >>>> > > > >>>> Patch 6 supports getting dual-link LVDS pixel order for the sink > > > >>>> side as needed by IT6263 driver. > > > >>>> > > > >>>> Patch 7 documents jeida-30 and vesa-30 data mappings in > > > >>>> lvds-data-mapping.yaml, as needed by IT6263 DT binding. > > > >>>> > > > >>>> Patch 8 extracts common dual-link LVDS display properties into > > > >>>> new lvds-dual-ports.yaml so that IT6263 DT binding can reference it. > > > >>>> > > > >>>> Patch 9 adds DT binding for IT6263. > > > >>>> > > > >>>> Patch 10 adds IT6263 bridge driver. Only video output is supported. > > > >>>> > > > >>>> Patch 11 adds DT overlays to support NXP adapter cards[2][3] with > > > >>>> IT6263 populated. > > > >>>> > > > >>>> Patch 12 enables the IT6263 bridge driver in defconfig. > > > >>>> > > > >>>> Patch 13 updates MAINTAINERS to add maintainer for IT6263 driver. > > > >>> > > > >>> This has pretty complicated structure from the merging point of view. > > > >>> > > > >>> I propose we take patches 6, 8, 9 (without 30-bit formats, they > > > >>> can be dropped while applying), 11, 12 > > > >>> (?) and 13 through drm-misc in one batch (once DT maintainers > > > >>> review the binding parts). This looks like a minimal set, having no > > > >>> extra dependencies. > > > >> > > > >>> > > > >>> The second set might be 4, 5 + new patch, re-adding 30-bit formats > > > >>> to > > > >>> IT6263 binding (no driver changes are necessary). This can go in > > > >>> separately, after an Ack from media maintainers. > > > >>> > > > >>> Of course both sets can go together if linux-media maintainers > > > >>> reacts quickly and ack merging media- formats patch through drm-misc > > > >>> tree. > > > > > > I'm fine with merging the two sets through drm-misc tree as long as > > > linux-media and dri-devel maintainers accept this. Up to them. > > > > > > >>> > > > >>> The rest of the patches don't have such strong dependencies and go in > > > >>> once ready / reviewed. > > > >>> > > > >>> WDYT? > > > >> > > > >> I guess, 6,8,9(without 30-bit formats), 10, 12 and 13. > > > >> > > > >> 11 may have dependency on 1, 2 and 3 as it is SoC specific. > > > > > > > > Yes, of course, 10, not 11. > > > > > > > >> Then 4, 5 + new patch, re-adding 30-bit formats to IT6263 binding. > > > > > > I think it would be good to directly support 30-bit formats in > > > IT6263 DT binding, not re-add them to it. This way, we'll have one > > > version of the binding, not two. So, a better first set would contain > > > patch 6, 7(one existing A-b from Krzysztof), 8, 9, 10, 12 and 13. > > > > I'm not sure that 7 can go without an ack from linux-media maintainers. > > You mean in describing jeida-30 and vesa-30 format in > patch#7, is valid only if patch#4 is ok with media people > or they provide an ack for patch#7 to take it through drm tree? The former one. I'd prefer an ack from linux-media maintainers to accept bindings based on those names. -- With best wishes Dmitry
Re: [PATCH RFC 2/4] drm/nouveau/dp: Use the generic helper to control LTTPR transparent mode
On Thu, Oct 31, 2024 at 05:12:46PM +0200, Abel Vesa wrote: > LTTPRs operating modes are defined by the DisplayPort standard and the > generic framework now provides a helper to switch between them. > So use the drm generic helper instead as it makes the code a bit cleaner. > > Signed-off-by: Abel Vesa > --- > drivers/gpu/drm/nouveau/nouveau_dp.c | 9 +++-- > 1 file changed, 3 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c > b/drivers/gpu/drm/nouveau/nouveau_dp.c > index > bcda0105160f1450df855281e0d932606a5095dd..80264e6186246903fa037861fe37493646de0c6e > 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_dp.c > +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c > @@ -80,15 +80,12 @@ nouveau_dp_probe_dpcd(struct nouveau_connector > *nv_connector, > int nr = drm_dp_lttpr_count(outp->dp.lttpr.caps); > > if (nr) { > - drm_dp_dpcd_writeb(aux, DP_PHY_REPEATER_MODE, > - > DP_PHY_REPEATER_MODE_TRANSPARENT); > + drm_dp_lttpr_set_transparent_mode(aux, true); > > if (nr > 0) { > - ret = drm_dp_dpcd_writeb(aux, > DP_PHY_REPEATER_MODE, > - > DP_PHY_REPEATER_MODE_NON_TRANSPARENT); > + ret = drm_dp_lttpr_set_transparent_mode(aux, > false); > if (ret != 1) { > - drm_dp_dpcd_writeb(aux, > DP_PHY_REPEATER_MODE, > - > DP_PHY_REPEATER_MODE_TRANSPARENT); > + drm_dp_lttpr_set_transparent_mode(aux, > true); > } else { > outp->dp.lttpr.nr = nr; > } Could you please extract this true-false-true dance to a new helper too? This way Intel driver can use the simple helper, the rest of the drivers can benefit having the common code. > > -- > 2.34.1 > -- With best wishes Dmitry
Re: [PATCH v6 7/9] drm/msm/dpu: add support for virtual planes
On Thu, 31 Oct 2024 at 17:11, Dmitry Baryshkov wrote: > > Hi Abhinav, > > On Wed, 30 Oct 2024 at 21:26, Abhinav Kumar wrote: > > On 10/30/2024 3:48 AM, Dmitry Baryshkov wrote: > > > On Tue, Oct 29, 2024 at 02:30:12PM -0700, Abhinav Kumar wrote: > > >> On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > >>> + if (reqs->yuv && !hw_sspp->cap->sblk->csc_blk.len) > > >>> + continue; > > >> > > >> same here > > >>> + > > >>> + if (reqs->rot90 && !(hw_sspp->cap->features & > > >>> DPU_SSPP_INLINE_ROTATION)) > > >>> + continue; > > >>> + > > >>> + global_state->sspp_to_crtc_id[i] = crtc_id; > > >>> + > > >>> + return rm->hw_sspp[i]; > > >>> + } > > >>> + > > >>> + return NULL; > > >>> +} > > >>> +struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, > > >>> + struct dpu_global_state > > >>> *global_state, > > >>> + struct drm_crtc *crtc, > > >>> + struct dpu_rm_sspp_requirements > > >>> *reqs) > > >>> +{ > > >>> + struct dpu_hw_sspp *hw_sspp = NULL; > > >>> + > > >>> + if (!reqs->scale && !reqs->yuv) > > >>> + hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, > > >>> SSPP_TYPE_DMA); > > >>> + if (!hw_sspp && reqs->scale) > > >>> + hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, > > >>> SSPP_TYPE_RGB); > > >> > > >> I dont recollect whether RGB SSPPs supported scaling, if you have any > > >> source > > >> or link for this, that would help me for sure. > > > > > > I have to dig further into the old fbdev driver. It looks like > > > mdss_mdp_qseed2_setup() is getting called for all plane types on the > > > corresponding hardware, but then it rejects scaling only for DMA and > > > CURSOR planes, which means that RGB planes should get the scaler setup. > > > > > > For now this is from the SDE driver from 4.4: > > > > > > * @SDE_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes > > > > > >> But even otherwise, I dont see any chipset in the catalog setting this > > >> SSPP > > >> type, so do we need to add this case? > > > > > > Yes, we do. MSM8996 / MSM8937 / MSM8917 / MSM8953 use RGB planes. > > > > > > > Yes those chipsets do have RGB SSPP. My question was whether they have > > migrated to dpu and thats why I wanted to know whether we want to > > include RGB SSPP handling. > > > > I do not even see them in msm_mdp5_dpu_migration. > > Ugh, it's a bug then, I'll push a fix. Ok, this is very surprising: static const char *const msm_mdp5_dpu_migration[] = { "qcom,msm8917-mdp5", "qcom,msm8937-mdp5", "qcom,msm8953-mdp5", "qcom,msm8996-mdp5", "qcom,sdm630-mdp5", "qcom,sdm660-mdp5", NULL, }; -- With best wishes Dmitry
Re: [PATCH RFC 4/4] drm/msm/dp: Add support for LTTPR handling
On Thu, Oct 31, 2024 at 05:12:48PM +0200, Abel Vesa wrote: > Link Training Tunable PHY Repeaters (LTTPRs) are defined in DisplayPort > 1.4a specification. As the name suggests, these PHY repeaters are > capable of adjusting their output for link training purposes. > > The msm DP driver is currently lacking any handling of LTTPRs. > This means that if at least one LTTPR is found between DPTX and DPRX, > the link training would fail if that LTTPR was not already configured > in transparent mode. It might be nice to mention what is the transparent mode, especially for those who do not have the standard at hand. > The section 3.6.6.1 from the DisplayPort v2.0 specification mandates > that before link training with the LTTPR is started, the DPTX may place > the LTTPR in non-transparent mode by first switching to transparent mode > and then to non-transparent mode. This operation seems to be needed only > on first link training and doesn't need to be done again until device is > unplugged. > > It has been observed on a few X Elite-based platforms which have > such LTTPRs in their board design that the DPTX needs to follow the > procedure described above in order for the link training to be successful. > > So add support for reading the LTTPR DPCD caps to figure out the number > of such LTTPRs first. Then, for platforms (or Type-C dongles) that have > at least one such an LTTPR, set its operation mode to transparent mode > first and then to non-transparent, just like the mentioned section of > the specification mandates. > > Signed-off-by: Abel Vesa > --- > drivers/gpu/drm/msm/dp/dp_display.c | 25 + > 1 file changed, 25 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c > b/drivers/gpu/drm/msm/dp/dp_display.c > index > f01980b0888a40b719d3958cb96c6341feada077..5d3d318d7b87ce3bf567d8b7435931d8e087f713 > 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -107,6 +107,8 @@ struct dp_display_private { > struct dp_event event_list[DP_EVENT_Q_MAX]; > spinlock_t event_lock; > > + u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE]; > + > bool wide_bus_supported; > > struct dp_audio *audio; > @@ -367,12 +369,35 @@ static int dp_display_send_hpd_notification(struct > dp_display_private *dp, > return 0; > } > > +static void dp_display_lttpr_init(struct dp_display_private *dp) > +{ > + int lttpr_count; > + > + if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, > + dp->lttpr_caps)) > + return; > + > + lttpr_count = drm_dp_lttpr_count(dp->lttpr_caps); > + > + if (lttpr_count) { > + drm_dp_lttpr_set_transparent_mode(dp->aux, true); > + > + if (lttpr_count > 0) { > + if (drm_dp_lttpr_set_transparent_mode(dp->aux, false) > != 1) > + drm_dp_lttpr_set_transparent_mode(dp->aux, > true); > + } > + } > +} > + > static int dp_display_process_hpd_high(struct dp_display_private *dp) > { > struct drm_connector *connector = dp->dp_display.connector; > const struct drm_display_info *info = &connector->display_info; > int rc = 0; > > + if (!dp->dp_display.is_edp) > + dp_display_lttpr_init(dp); Why is it limited to non-eDP cases only. > + > rc = dp_panel_read_sink_caps(dp->panel, connector); > if (rc) > goto end; > > -- > 2.34.1 > -- With best wishes Dmitry
Re: [PATCH v2] drm/bridge: Fix assignment of the of_node of the parent to aux bridge
On Mon, 21 Oct 2024 at 10:23, Johan Hovold wrote: > > On Fri, Oct 18, 2024 at 03:49:34PM +0300, Abel Vesa wrote: > > The assignment of the of_node to the aux bridge needs to mark the > > of_node as reused as well, otherwise resource providers like pinctrl will > > report a gpio as already requested by a different device when both pinconf > > and gpios property are present. > > I don't think you need a gpio property for that to happen, right? And > this causes probe to fail IIRC? No, just having a pinctrl property in the bridge device is enough. Without this fix when the aux subdevice is being bound to the driver, the pinctrl_bind_pins() will attempt to bind pins, which are already in use by the actual bridge device. > > > Fix that by using the device_set_of_node_from_dev() helper instead. > > > > Fixes: 6914968a0b52 ("drm/bridge: properly refcount DT nodes in aux bridge > > drivers") > > This is not the commit that introduced the issue. > > > Cc: sta...@vger.kernel.org # 6.8 > > I assume there are no existing devicetrees that need this since then we > would have heard about it sooner. Do we still need to backport it? > > When exactly are you hitting this? > > > Cc: Dmitry Baryshkov > > Signed-off-by: Abel Vesa > > --- > > Changes in v2: > > - Re-worded commit to be more explicit of what it fixes, as Johan suggested > > - Used device_set_of_node_from_dev() helper, as per Johan's suggestion > > - Added Fixes tag and cc'ed stable > > - Link to v1: > > https://lore.kernel.org/r/20241017-drm-aux-bridge-mark-of-node-reused-v1-1-7cd5702bb...@linaro.org > > Patch itself looks good now. > > Johan -- With best wishes Dmitry
Re: [PATCH v6 7/9] drm/msm/dpu: add support for virtual planes
Hi Abhinav, On Wed, 30 Oct 2024 at 21:26, Abhinav Kumar wrote: > > > > On 10/30/2024 3:48 AM, Dmitry Baryshkov wrote: > > On Tue, Oct 29, 2024 at 02:30:12PM -0700, Abhinav Kumar wrote: > >> > >> > >> On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > >>> Only several SSPP blocks support such features as YUV output or scaling, > >>> thus different DRM planes have different features. Properly utilizing > >>> all planes requires the attention of the compositor, who should > >>> prefer simpler planes to YUV-supporting ones. Otherwise it is very easy > >>> to end up in a situation when all featureful planes are already > >>> allocated for simple windows, leaving no spare plane for YUV playback. > >>> > >>> To solve this problem make all planes virtual. Each plane is registered > >>> as if it supports all possible features, but then at the runtime during > >>> the atomic_check phase the driver selects backing SSPP block for each > >>> plane. > >>> > >>> As the planes are attached to the CRTC and not the encoder, the SSPP > >>> blocks are also allocated per CRTC ID (all other resources are currently > >>> allocated per encoder ID). This also matches the hardware requirement, > >>> where both rectangles of a single SSPP can only be used with the LM > >>> pair. > >>> > >>> Note, this does not provide support for using two different SSPP blocks > >>> for a single plane or using two rectangles of an SSPP to drive two > >>> planes. Each plane still gets its own SSPP and can utilize either a solo > >>> rectangle or both multirect rectangles depending on the resolution. > >>> > >>> Note #2: By default support for virtual planes is turned off and the > >>> driver still uses old code path with preallocated SSPP block for each > >>> plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1' > >>> kernel parameter. > >>> > >>> Signed-off-by: Dmitry Baryshkov > >>> --- > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 237 > >>> ++ > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 16 ++ > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 68 + > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 27 > >>>7 files changed, 383 insertions(+), 29 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > >>> index 58595dcc3889..a7eea094aa14 100644 > >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > >>> @@ -1166,6 +1166,49 @@ static bool dpu_crtc_needs_dirtyfb(struct > >>> drm_crtc_state *cstate) > >>> return false; > >>>} > >>> +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct > >>> drm_crtc_state *crtc_state) > >>> +{ > >>> + int total_planes = crtc->dev->mode_config.num_total_plane; > >>> + struct drm_atomic_state *state = crtc_state->state; > >>> + struct dpu_global_state *global_state; > >>> + struct drm_plane_state **states; > >>> + struct drm_plane *plane; > >>> + int ret; > >>> + > >>> + global_state = dpu_kms_get_global_state(crtc_state->state); > >>> + if (IS_ERR(global_state)) > >>> + return PTR_ERR(global_state); > >>> + > >>> + dpu_rm_release_all_sspp(global_state, crtc); > >>> + > >>> + if (!crtc_state->enable) > >>> + return 0; > >>> + > >>> + states = kcalloc(total_planes, sizeof(*states), GFP_KERNEL); > >>> + if (!states) > >>> + return -ENOMEM; > >>> + > >>> + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { > >>> + struct drm_plane_state *plane_state = > >>> + drm_atomic_get_plane_state(state, plane); > >>> + > >>> + if (IS_ERR(plane_state)) { > >>> + ret = PTR_ERR(plane_state); > >>> +
Re: [PATCH v6 7/9] drm/msm/dpu: add support for virtual planes
On Tue, Oct 29, 2024 at 02:30:12PM -0700, Abhinav Kumar wrote: > > > On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > Only several SSPP blocks support such features as YUV output or scaling, > > thus different DRM planes have different features. Properly utilizing > > all planes requires the attention of the compositor, who should > > prefer simpler planes to YUV-supporting ones. Otherwise it is very easy > > to end up in a situation when all featureful planes are already > > allocated for simple windows, leaving no spare plane for YUV playback. > > > > To solve this problem make all planes virtual. Each plane is registered > > as if it supports all possible features, but then at the runtime during > > the atomic_check phase the driver selects backing SSPP block for each > > plane. > > > > As the planes are attached to the CRTC and not the encoder, the SSPP > > blocks are also allocated per CRTC ID (all other resources are currently > > allocated per encoder ID). This also matches the hardware requirement, > > where both rectangles of a single SSPP can only be used with the LM > > pair. > > > > Note, this does not provide support for using two different SSPP blocks > > for a single plane or using two rectangles of an SSPP to drive two > > planes. Each plane still gets its own SSPP and can utilize either a solo > > rectangle or both multirect rectangles depending on the resolution. > > > > Note #2: By default support for virtual planes is turned off and the > > driver still uses old code path with preallocated SSPP block for each > > plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1' > > kernel parameter. > > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 237 > > ++ > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 16 ++ > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 68 + > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 27 > > 7 files changed, 383 insertions(+), 29 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > index 58595dcc3889..a7eea094aa14 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > > @@ -1166,6 +1166,49 @@ static bool dpu_crtc_needs_dirtyfb(struct > > drm_crtc_state *cstate) > > return false; > > } > > +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct > > drm_crtc_state *crtc_state) > > +{ > > + int total_planes = crtc->dev->mode_config.num_total_plane; > > + struct drm_atomic_state *state = crtc_state->state; > > + struct dpu_global_state *global_state; > > + struct drm_plane_state **states; > > + struct drm_plane *plane; > > + int ret; > > + > > + global_state = dpu_kms_get_global_state(crtc_state->state); > > + if (IS_ERR(global_state)) > > + return PTR_ERR(global_state); > > + > > + dpu_rm_release_all_sspp(global_state, crtc); > > + > > + if (!crtc_state->enable) > > + return 0; > > + > > + states = kcalloc(total_planes, sizeof(*states), GFP_KERNEL); > > + if (!states) > > + return -ENOMEM; > > + > > + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { > > + struct drm_plane_state *plane_state = > > + drm_atomic_get_plane_state(state, plane); > > + > > + if (IS_ERR(plane_state)) { > > + ret = PTR_ERR(plane_state); > > + goto done; > > + } > > + > > + states[plane_state->normalized_zpos] = plane_state; > > + } > > + > > + ret = dpu_assign_plane_resources(global_state, state, crtc, states, > > total_planes); > > + > > +done: > > + kfree(states); > > + return ret; > > + > > + return 0; > > +} > > + > > static int dpu_crtc_atomic_check(struct drm_crtc *crtc, > > struct drm_atomic_state *state) > > { > > @@ -1181,6 +1224,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc > > *crtc, > > bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); > > + if (dpu_use_virtual_planes && > > + (crtc_state
Re: [PATCH v6 8/9] drm/msm/dpu: allow using two SSPP blocks for a single plane
On Tue, Oct 29, 2024 at 03:07:30PM -0700, Abhinav Kumar wrote: > > > On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > Virtual wide planes give high amount of flexibility, but it is not > > always enough: > > > > In parallel multirect case only the half of the usual width is supported > > for tiled formats. Thus the whole width of two tiled multirect > > rectangles can not be greater than max_linewidth, which is not enough > > for some platforms/compositors. > > > > Another example is as simple as wide YUV plane. YUV planes can not use > > multirect, so currently they are limited to max_linewidth too. > > > > Now that the planes are fully virtualized, add support for allocating > > two SSPP blocks to drive a single DRM plane. This fixes both mentioned > > cases and allows all planes to go up to 2*max_linewidth (at the cost of > > making some of the planes unavailable to the user). > > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 163 > > ++ > > 1 file changed, 119 insertions(+), 44 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > index 125db3803cf5..ad6cc469f475 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > @@ -20,7 +20,6 @@ > > #include "msm_drv.h" > > #include "msm_mdss.h" > > #include "dpu_kms.h" > > -#include "dpu_formats.h" > > #include "dpu_hw_sspp.h" > > #include "dpu_hw_util.h" > > #include "dpu_trace.h" > > @@ -888,6 +887,28 @@ static int dpu_plane_atomic_check_nosspp(struct > > drm_plane *plane, > > return 0; > > } > > +static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe > > *pipe, > > + struct dpu_sw_pipe_cfg > > *pipe_cfg, > > + const struct msm_format *fmt, > > + uint32_t max_linewidth) > > +{ > > + if (drm_rect_width(&pipe_cfg->src_rect) != > > drm_rect_width(&pipe_cfg->dst_rect) || > > + drm_rect_height(&pipe_cfg->src_rect) != > > drm_rect_height(&pipe_cfg->dst_rect)) > > + return false; > > + > > + if (pipe_cfg->rotation & DRM_MODE_ROTATE_90) > > + return false; > > + > > + if (MSM_FORMAT_IS_YUV(fmt)) > > + return false; > > + > > + if (MSM_FORMAT_IS_UBWC(fmt) && > > + drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) > > + return false; > > + > > + return true; > > +} > > Dont we also need to check for > > if (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) && >!test_bit(DPU_SSPP_SMART_DMA_V2, > &pipe->sspp->cap->features))? > return false; In the patch I was checking that after a call to this function, but maybe you are right. Especially since I was checking only the pipe, not the r_pipe. > > > + > > static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, > >struct drm_atomic_state *state, > >const struct drm_crtc_state *crtc_state) > > @@ -901,7 +922,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane > > *plane, > > const struct msm_format *fmt; > > struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; > > struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; > > - uint32_t max_linewidth; > > uint32_t supported_rotations; > > const struct dpu_sspp_cfg *pipe_hw_caps; > > const struct dpu_sspp_sub_blks *sblk; > > @@ -923,8 +943,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane > > *plane, > > fmt = msm_framebuffer_format(new_plane_state->fb); > > - max_linewidth = pdpu->catalog->caps->max_linewidth; > > - > > supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; > > if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) > > @@ -940,41 +958,6 @@ static int dpu_plane_atomic_check_sspp(struct > > drm_plane *plane, > > return ret; > > if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { > > - /* > > -
Re: [PATCH V2 drm-dp 2/4] drm/hisilicon/hibmc: add dp link moduel in hibmc
On Tue, 29 Oct 2024 at 16:15, Yongbang Shi wrote: > > > On Tue, Oct 22, 2024 at 08:41:46PM +0800, Yongbang Shi wrote: > >> From: baihan li > >> > >> Add link training process functions in this moduel. > > We should probably have a bounty for a developer who finally writes a > > generic DP link training helpers. > > > >> Signed-off-by: baihan li > > Missing SoB > > > >> --- > >> ChangeLog: > >> v1 -> v2: > >>- using drm_dp_* functions implement dp link training process, > >> suggested by Jani Nikula. > >>- fix build errors reported by kernel test robot > >> Closes: > >> https://lore.kernel.org/oe-kbuild-all/202410031735.8irzzr6t-...@intel.com/ > >> > >> v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > >> --- > >> drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > >> drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 344 +++ > >> drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h | 25 ++ > >> 3 files changed, 370 insertions(+), 1 deletion(-) > >> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > >> create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h > >> > >> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > >> b/drivers/gpu/drm/hisilicon/hibmc/Makefile > >> index 8770ec6dfffd..94d77da88bbf 100644 > >> --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > >> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > >> @@ -1,5 +1,5 @@ > >> # SPDX-License-Identifier: GPL-2.0-only > >> hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > >> hibmc_drm_i2c.o \ > >> - dp/dp_aux.o > >> + dp/dp_aux.o dp/dp_link.o > >> > >> obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > >> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > >> b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > >> new file mode 100644 > >> index ..b02a536e0689 > >> --- /dev/null > >> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > >> @@ -0,0 +1,344 @@ > >> +// SPDX-License-Identifier: GPL-2.0-or-later > >> +// Copyright (c) 2024 Hisilicon Limited. > >> + > >> +#include > >> +#include > >> +#include > >> +#include "dp_comm.h" > >> +#include "dp_reg.h" > >> +#include "dp_link.h" > >> +#include "dp_aux.h" > >> + > >> +const u8 link_rate_map[] = {DP_LINK_BW_1_62, DP_LINK_BW_2_7, > >> +DP_LINK_BW_5_4, DP_LINK_BW_8_1}; > >> + > >> +static int dp_link_training_configure(struct dp_dev *dp) > >> +{ > >> +u8 buf[2]; > >> +int ret; > >> + > >> +/* DP 2 lane */ > >> +dp_write_bits(dp->base + DP_PHYIF_CTRL0, DP_CFG_LANE_DATA_EN, > >> + dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x3 : 0x1); > >> +dp_write_bits(dp->base + DP_DPTX_GCTL0, DP_CFG_PHY_LANE_NUM, > >> + dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x1 : 0); > >> + > >> +/* enhanced frame */ > >> +dp_write_bits(dp->base + DP_VIDEO_CTRL, DP_CFG_STREAM_FRAME_MODE, > >> 0x1); > >> + > >> +/* set rate and lane count */ > >> +buf[0] = dp_get_link_rate(dp->link.cap.link_rate); > >> +buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes; > >> +ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); > >> +if (ret != sizeof(buf)) { > >> +drm_err(dp->dev, "dp aux write link rate and lanes failed, > >> ret: %d\n", ret); > >> +return ret; > >> +} > >> + > >> +/* set 8b/10b and downspread */ > >> +buf[0] = 0x10; > >> +buf[1] = 0x1; > >> +ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, > >> sizeof(buf)); > >> +if (ret != sizeof(buf)) > >> +drm_err(dp->dev, "dp aux write 8b/10b and downspread failed, > >> ret: %d\n", ret); > >> + > >> +ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd); > >> +if (ret) > >> +drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); > >> + > >> +return ret; > >> +} > >> + > >> +static int dp_link_pattern2dpcd(struct dp_dev *dp, enum dp_pattern_e > >> pattern) > >> +{ > >> +switch (pattern) { > >> +case DP_PATTERN_NO: > >> +return DP_TRAINING_PATTERN_DISABLE; > >> +case DP_PATTERN_TPS1: > >> +return DP_TRAINING_PATTERN_1; > >> +case DP_PATTERN_TPS2: > >> +return DP_TRAINING_PATTERN_2; > >> +case DP_PATTERN_TPS3: > >> +return DP_TRAINING_PATTERN_3; > >> +case DP_PATTERN_TPS4: > >> +return DP_TRAINING_PATTERN_4; > >> +default: > >> +drm_err(dp->dev, "dp link unknown pattern %d\n", pattern); > >> +return -EINVAL; > > Why do you need the extra defines / wrappers? Can you use > > DP_TRAINING_PATTERN_foo directly? > > Hi Dmitry, > Thanks for your all of these good advices and questions. I will resply as > soon as possible. > For this point, I also need this enum dp_pattern_e value to write in my dp > reg at TPS stage, so I made this map here. I'd suggest to do it other way around: use standard defines and when
Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support
On Tue, 29 Oct 2024 at 04:41, Liu Ying wrote: > > On 10/28/2024, Dmitry Baryshkov wrote: > > On Mon, Oct 28, 2024 at 11:12:00AM +, Biju Das wrote: > >> Hi Dmitry, Liu, > >> > >>> -----Original Message- > >>> From: Dmitry Baryshkov > >>> Sent: 28 October 2024 10:20 > >>> Subject: Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter > >>> support > >>> > >>> Hi, > >>> > >>> On Mon, 28 Oct 2024 at 04:37, Liu Ying wrote: > >>>> > >>>> Hi, > >>>> > >>>> This patch series aims to add ITE IT6263 LVDS to HDMI converter on > >>>> i.MX8MP EVK. Combined with LVDS receiver and HDMI 1.4a transmitter, > >>>> the IT6263 supports LVDS input and HDMI 1.4 output by conversion > >>>> function. IT6263 product link can be found at [1]. > >>>> > >>>> Patch 1 is a preparation patch to allow display mode of an existing > >>>> panel to pass the added mode validation logic in patch 3. > >>>> > >>>> Patch 2 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to find > >>>> the next non-panel bridge, that is the IT6263 in this case. > >>>> > >>>> Patch 3 adds mode validation logic to i.MX8MP LDB bridge driver > >>>> against "ldb" clock so that it can filter out unsupported display > >>>> modes read from EDID. > >>>> > >>>> Patch 4 adds MEDIA_BUS_FMT_RGB101010_1X7X5_{SPWG,JEIDA} support, as > >>>> they are supported by IT6263(with LVDS data bit reversed order). > >>>> > >>>> Patch 5 makes drm_of.c use MEDIA_BUS_FMT_RGB101010_1X7X5_{JEIDA,SPWG}. > >>>> > >>>> Patch 6 supports getting dual-link LVDS pixel order for the sink side > >>>> as needed by IT6263 driver. > >>>> > >>>> Patch 7 documents jeida-30 and vesa-30 data mappings in > >>>> lvds-data-mapping.yaml, as needed by IT6263 DT binding. > >>>> > >>>> Patch 8 extracts common dual-link LVDS display properties into new > >>>> lvds-dual-ports.yaml so that IT6263 DT binding can reference it. > >>>> > >>>> Patch 9 adds DT binding for IT6263. > >>>> > >>>> Patch 10 adds IT6263 bridge driver. Only video output is supported. > >>>> > >>>> Patch 11 adds DT overlays to support NXP adapter cards[2][3] with > >>>> IT6263 populated. > >>>> > >>>> Patch 12 enables the IT6263 bridge driver in defconfig. > >>>> > >>>> Patch 13 updates MAINTAINERS to add maintainer for IT6263 driver. > >>> > >>> This has pretty complicated structure from the merging point of view. > >>> > >>> I propose we take patches 6, 8, 9 (without 30-bit formats, they can be > >>> dropped while applying), 11, 12 > >>> (?) and 13 through drm-misc in one batch (once DT maintainers review the > >>> binding parts). This looks > >>> like a minimal set, having no extra dependencies. > >> > >>> > >>> The second set might be 4, 5 + new patch, re-adding 30-bit formats to > >>> IT6263 binding (no driver changes are necessary). This can go in > >>> separately, after an Ack from media > >>> maintainers. > >>> > >>> Of course both sets can go together if linux-media maintainers reacts > >>> quickly and ack merging media- > >>> formats patch through drm-misc tree. > > I'm fine with merging the two sets through drm-misc tree as long > as linux-media and dri-devel maintainers accept this. Up to them. > > >>> > >>> The rest of the patches don't have such strong dependencies and go in > >>> once ready / reviewed. > >>> > >>> WDYT? > >> > >> I guess, 6,8,9(without 30-bit formats), 10, 12 and 13. > >> > >> 11 may have dependency on 1, 2 and 3 as it is SoC specific. > > > > Yes, of course, 10, not 11. > > > >> Then 4, 5 + new patch, re-adding 30-bit formats to IT6263 binding. > > I think it would be good to directly support 30-bit formats in > IT6263 DT binding, not re-add them to it. This way, we'll have one > version of the binding, not two. So, a better first set would > contain patch 6, 7(one existing A-b from Krzysztof), 8, 9, 10, 12 > and 13. I'm not sure that 7 can go without an ack from linux-media maintainers. -- With best wishes Dmitry
Re: [PATCH V2 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc
On Tue, 29 Oct 2024 at 16:15, Yongbang Shi wrote: > > > On Tue, Oct 22, 2024 at 08:41:45PM +0800, Yongbang Shi wrote: > >> From: baihan li > >> +} > >> + > >> +enum dpcd_revision { > >> +DPCD_REVISION_10 = 0x10, > >> +DPCD_REVISION_11, > >> +DPCD_REVISION_12, > >> +DPCD_REVISION_13, > >> +DPCD_REVISION_14, > > Any reason for ignoring defines in drm_dp.h? > > Hi Dmitry, > I tried it but still can't find it, if you know, can you tell me which macro > I can use? # define DP_DPCD_REV_10 0x10 # define DP_DPCD_REV_11 0x11 etc > Thanks, > Baihan -- With best wishes Dmitry
[PATCH v2 3/3] drm/msm/dp: tidy up platform data names
Follow the established symbol name pattern and rename platform data structures. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 38 ++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 5cc349f672c0..aba925aab7ad 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -118,7 +118,7 @@ struct msm_dp_desc { bool wide_bus_supported; }; -static const struct msm_dp_desc sa8775p_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sa8775p[] = { { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0af5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -126,25 +126,25 @@ static const struct msm_dp_desc sa8775p_dp_descs[] = { {} }; -static const struct msm_dp_desc sc7180_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc7180[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc7280_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc7280[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0aea, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc8180x_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc8180x[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc8280xp_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc8280xp[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -156,12 +156,12 @@ static const struct msm_dp_desc sc8280xp_dp_descs[] = { {} }; -static const struct msm_dp_desc sm8650_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sm8650[] = { { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc x1e80100_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_x1e80100[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -170,18 +170,18 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = { }; static const struct of_device_id msm_dp_dt_match[] = { - { .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs }, - { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, - { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs }, - { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs }, - { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs }, - { .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs }, - { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_dp_descs }, - { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sm8350-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, - { .compatible = "qcom,x1e80100-dp", .data = &x1e80100_dp_descs }, + { .compatible = "qcom,sa8775p-dp", .data = &msm_dp_desc_sa8775p }, + { .compatible = "qcom,sc7180-dp", .data = &msm_dp_desc_sc7180 }, + { .compatible = "qcom,sc7280-dp", .data = &msm_dp_desc_sc7280 }, + { .compatible = "qcom,sc7280-edp", .data = &msm_dp_desc_sc7280 }, + { .compatible = "qcom,sc8180x-dp", .data = &msm_dp_desc_sc8180x }, + { .compatible = "qcom,sc8180x-edp", .data = &msm_dp_desc_sc8180x }, + { .compatible = "qcom,sc8280xp-dp", .data = &msm_dp_desc_sc8280xp }, + { .compatible = "qcom,sc8280xp-edp", .data = &msm_dp_desc_sc8280xp }, + { .c
[PATCH v2 0/3] drm/msm/dp: mass-rename symbols
The LKP reported [1] a symbol clash between the drm/msm/dp and the HIMBC driver being sumbitted, because both of them use a generic dp_ prefix for a lot of symbols. It's a hight time we made msm/dp driver use something less generic, like msm_dp. [1] https://lore.kernel.org/oe-kbuild-all/202410250305.uhkdhtxy-...@intel.com/ Signed-off-by: Dmitry Baryshkov --- Changes in v2: - Switched eDP symbols from msm_dp_foo_edp to msm_edp_foo (Abhinav) - Link to v1: https://lore.kernel.org/r/20241028-msm-dp-rename-v1-0-a2564e945...@linaro.org --- Dmitry Baryshkov (3): drm/msm/dp: prefix all symbols with msm_dp_ drm/msm/dp: rename edp_ bridge functions and struct drm/msm/dp: tidy up platform data names drivers/gpu/drm/msm/dp/dp_audio.c | 294 ++-- drivers/gpu/drm/msm/dp/dp_audio.h | 38 +- drivers/gpu/drm/msm/dp/dp_aux.c | 148 +++--- drivers/gpu/drm/msm/dp/dp_aux.h | 18 +- drivers/gpu/drm/msm/dp/dp_catalog.c | 734 ++--- drivers/gpu/drm/msm/dp/dp_catalog.h | 118 ++--- drivers/gpu/drm/msm/dp/dp_ctrl.c| 482 +-- drivers/gpu/drm/msm/dp/dp_ctrl.h| 40 +- drivers/gpu/drm/msm/dp/dp_debug.c | 68 +-- drivers/gpu/drm/msm/dp/dp_debug.h | 10 +- drivers/gpu/drm/msm/dp/dp_display.c | 904 ++-- drivers/gpu/drm/msm/dp/dp_display.h | 18 +- drivers/gpu/drm/msm/dp/dp_drm.c | 142 +++--- drivers/gpu/drm/msm/dp/dp_drm.h | 22 +- drivers/gpu/drm/msm/dp/dp_link.c| 432 - drivers/gpu/drm/msm/dp/dp_link.h| 44 +- drivers/gpu/drm/msm/dp/dp_panel.c | 254 +- drivers/gpu/drm/msm/dp/dp_panel.h | 42 +- drivers/gpu/drm/msm/dp/dp_utils.c | 20 +- drivers/gpu/drm/msm/dp/dp_utils.h | 8 +- 20 files changed, 1918 insertions(+), 1918 deletions(-) --- base-commit: dec9255a128e19c5fcc3bdb18175d78094cc624d change-id: 20241028-msm-dp-rename-f0eed848e231 Best regards, -- Dmitry Baryshkov
[PATCH v2 2/3] drm/msm/dp: rename edp_ bridge functions and struct
Follow the estalished prefix and rename eDP bridge symbols to use msm_edp_ prefix, moving the edp to the end of the symbol name. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_drm.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 6a0840266c0f..d3e241ea6941 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -115,7 +115,7 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = { .debugfs_init = msm_dp_bridge_debugfs_init, }; -static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, +static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -136,7 +136,7 @@ static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, return 0; } -static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, +static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -147,7 +147,7 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, /* * Check the old state of the crtc to determine if the panel -* was put into psr state previously by the edp_bridge_atomic_disable. +* was put into psr state previously by the msm_edp_bridge_atomic_disable. * If the panel is in psr, just exit psr state and skip the full * bridge enable sequence. */ @@ -166,7 +166,7 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, msm_dp_bridge_atomic_enable(drm_bridge, old_bridge_state); } -static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, +static void msm_edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -194,7 +194,7 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, * If old crtc state is active, then this is a display disable * call while the sink is in psr state. So, exit psr here. * The eDP controller will be disabled in the -* edp_bridge_atomic_post_disable function. +* msm_edp_bridge_atomic_post_disable function. * * We observed sink is stuck in self refresh if psr exit is skipped * when display disable occurs while the sink is in psr state. @@ -211,7 +211,7 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, msm_dp_bridge_atomic_disable(drm_bridge, old_bridge_state); } -static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, +static void msm_edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -228,7 +228,7 @@ static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, return; /* -* Self refresh mode is already set in edp_bridge_atomic_disable. +* Self refresh mode is already set in msm_edp_bridge_atomic_disable. */ if (new_crtc_state->self_refresh_active) return; @@ -237,13 +237,13 @@ static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, } /** - * edp_bridge_mode_valid - callback to determine if specified mode is valid + * msm_edp_bridge_mode_valid - callback to determine if specified mode is valid * @bridge: Pointer to drm bridge structure * @info: display info * @mode: Pointer to drm mode structure * Returns: Validity status for specified mode */ -static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, +static enum drm_mode_status msm_edp_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, const struct drm_display_mode *mode) { @@ -268,24 +268,24 @@ static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) +static void msm_edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) { struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display; msm_dp_display_debugfs_init(dp, root, true); } -static const struct drm_bridge_funcs edp_bridge_ops = { - .atomic_enable = edp_bridg
Re: [PATCH 2/3] drm/msm/dp: rename edp_ bridge functions and struct
On Tue, 29 Oct 2024 at 20:08, Abhinav Kumar wrote: > > > > On 10/28/2024 4:49 AM, Dmitry Baryshkov wrote: > > Follow the estalished prefix and rename eDP bridge symbols to use > > msm_dp_ prefix, moving the edp to the end of the symbol name. > > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/msm/dp/dp_drm.c | 36 ++-- > > 1 file changed, 18 insertions(+), 18 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c > > b/drivers/gpu/drm/msm/dp/dp_drm.c > > index 6a0840266c0f..ff9ce9b15234 100644 > > --- a/drivers/gpu/drm/msm/dp/dp_drm.c > > +++ b/drivers/gpu/drm/msm/dp/dp_drm.c > > @@ -115,7 +115,7 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops > > = { > > .debugfs_init = msm_dp_bridge_debugfs_init, > > }; > > > > -static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, > > +static int msm_dp_bridge_atomic_check_edp(struct drm_bridge *drm_bridge, > > struct drm_bridge_state *bridge_state, > > struct drm_crtc_state *crtc_state, > > struct drm_connector_state *conn_state) > > msm_dp_bridge_atomic_check_edp looks a bit odd. > > What about just msm_edp_bridge_atomic_check? > > Likewise for other edp names. Yeah, I was torn between these two options. I'll switch to the second one. -- With best wishes Dmitry
Re: [PATCH 3/5] drm/vblank: Remove unused drm_crtc_vblank_count_and_time
On Wed, Oct 23, 2024 at 12:29:32AM +0100, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > drm_crtc_vblank_count_and_time() was explicitly added by > commit cf6483050e9b ("drm/irq: Add drm_crtc_vblank_count_and_time()") > in 2015, but never used. > > Remove it, and rework comments that reference it. Not having the deep knowledge of the drm_vblank code, dropping the function unused since 2015 should be fine. Acked-by: Dmitry Baryshkov > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_vblank.c | 44 +++- > include/drm/drm_vblank.h | 10 > 2 files changed, 12 insertions(+), 42 deletions(-) -- With best wishes Dmitry
Re: [PATCH] drm: encoder_slave: Remove unused encoder functions
On Fri, Oct 25, 2024 at 09:39:20PM +0100, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > drm_i2c_encoder_commit(), drm_i2c_encoder_mode_set() and > drm_i2c_encoder_prepare() have been unused since 2016's > commit 7bc61cc5df80 ("drm/arcpgu: Accommodate adv7511 switch to DRM > bridge"). > > Remove them. > That change makes drm_i2c_encoder_dpms() unused. > Remove it. > > Remove the comments about those functions wrapping a couple of > pointers in drm_encoder_slave_funcs. I can see sil164, ch7006, and nv17 > set those fields, and I can see some nouveau code that calls them > directly; so i don't think we can remove the fields. > (Although it's not clear to me if the sil164 or ch7006 code > can ever get called). > > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_encoder_slave.c | 26 -- > include/drm/drm_encoder_slave.h | 11 ++- > 2 files changed, 2 insertions(+), 35 deletions(-) > > diff --git a/drivers/gpu/drm/drm_encoder_slave.c > b/drivers/gpu/drm/drm_encoder_slave.c > index e464429d32df..0c994a4ef9ae 100644 > --- a/drivers/gpu/drm/drm_encoder_slave.c > +++ b/drivers/gpu/drm/drm_encoder_slave.c > @@ -125,12 +125,6 @@ get_slave_funcs(struct drm_encoder *enc) > return to_encoder_slave(enc)->slave_funcs; > } > > -void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode) > -{ > - get_slave_funcs(encoder)->dpms(encoder, mode); > -} > -EXPORT_SYMBOL(drm_i2c_encoder_dpms); I think it might be better to convert nouveau to use these functions instead of open-coding them. Another option might be to make nouveau use normal drm_bridge interface to talk to i2c encoders and drop the custom interface. Ben, WDYT? > - > bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder, > const struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode) > @@ -142,26 +136,6 @@ bool drm_i2c_encoder_mode_fixup(struct drm_encoder > *encoder, > } > EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup); > > -void drm_i2c_encoder_prepare(struct drm_encoder *encoder) > -{ > - drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > -} > -EXPORT_SYMBOL(drm_i2c_encoder_prepare); > - > -void drm_i2c_encoder_commit(struct drm_encoder *encoder) > -{ > - drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > -} > -EXPORT_SYMBOL(drm_i2c_encoder_commit); > - > -void drm_i2c_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > -{ > - get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode); > -} > -EXPORT_SYMBOL(drm_i2c_encoder_mode_set); > - > enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder, > struct drm_connector *connector) > { > diff --git a/include/drm/drm_encoder_slave.h b/include/drm/drm_encoder_slave.h > index 49172166a164..3089db10b6fd 100644 > --- a/include/drm/drm_encoder_slave.h > +++ b/include/drm/drm_encoder_slave.h > @@ -58,8 +58,7 @@ struct drm_encoder_slave_funcs { > void (*destroy)(struct drm_encoder *encoder); > > /** > - * @dpms: Analogous to &drm_encoder_helper_funcs @dpms callback. Wrapped > - * by drm_i2c_encoder_dpms(). > + * @dpms: Analogous to &drm_encoder_helper_funcs @dpms callback. >*/ > void (*dpms)(struct drm_encoder *encoder, int mode); > > @@ -88,7 +87,7 @@ struct drm_encoder_slave_funcs { > struct drm_display_mode *mode); > /** >* @mode_set: Analogous to &drm_encoder_helper_funcs @mode_set > - * callback. Wrapped by drm_i2c_encoder_mode_set(). > + * callback. >*/ > void (*mode_set)(struct drm_encoder *encoder, >struct drm_display_mode *mode, > @@ -223,15 +222,9 @@ void drm_i2c_encoder_destroy(struct drm_encoder > *encoder); > * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs: > */ > > -void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode); > bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder, > const struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode); > -void drm_i2c_encoder_prepare(struct drm_encoder *encoder); > -void drm_i2c_encoder_commit(struct drm_encoder *encoder); > -void drm_i2c_encoder_mode_set(struct drm_encoder *encoder, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode); > enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder, > struct drm_connector *connector); > void drm_i2c_encoder_save(struct drm_encoder *encoder); > -- > 2.47.0 > -- With best wishes Dmitry
Re: [PATCH] drm/bridge: ti-sn65dsi86: Fix multiple instances
On Tue, Oct 22, 2024 at 07:37:01AM -0700, Doug Anderson wrote: > Hi, > > On Tue, Oct 22, 2024 at 12:12 AM Geert Uytterhoeven > wrote: > > > > > > > > > However, using i2c_client->adapter->nr instead of ida_alloc() > > > > > > > in the TI driver does sound like a good idea to me... > > > > > > > > > > > > Great! > > > > > > > > > With the I2C adapter numbers, that becomes: > > > > > > > > > > /sys/bus/auxiliary/devices > > > > > ├── ti_sn65dsi86.gpio.1 > > > > > ├── ti_sn65dsi86.pwm.1 > > > > > ├── ti_sn65dsi86.aux.1 > > > > > ├── ti_sn65dsi86.bridge.1 > > > > > ├── ti_sn65dsi86.gpio.4 > > > > > ├── ti_sn65dsi86.pwm.4 > > > > > ├── ti_sn65dsi86.aux.4 > > > > > └── ti_sn65dsi86.bridge.4 > > > > > > > > > > > adapter->nr instead like other aux subsystems already do. > > > > > > > > Unfortunately the devil is in the details, as usual: there can be > > > > multiple instances of the sn65dsi86 bridge on a single I2C bus, > > > > so adapter->nr is not guaranteed to generate a unique name. > > > > > > In the case of sn65dsi86 I think we'd actually be OK. The TI bridge > > > chip is always at bus address 0x2d so you can't have more than one on > > > the same bus. Unless you added something funky atop it (like a mux of > > > some sort) you might be OK. > > > > It's 0x2c on mine ;-) > > > > 8.5.1 Local I2C Interface Overview > > The 7-bit device address for SN65DSI86 is factory preset to 010110X > > with the least significant bit being determined by the ADDR control > > input. > > Doh! I missed that in my search of the doc. I guess because they > decided to specify the address in binary in that part so my searching > for both the 7-bit and 8-bit I2C address didn't trigger. Oh well. > > > > > > Changing the auxiliary bus to use the parent's name instead of the > > > > module name, as suggested by Laurent, would fix that. > > > > > > Right. On my system dev_name() of the sn65dsi86 device is "2-002d". If > > > we had a second on i2c bus 4, we'd have: > > > > > > /sys/bus/auxiliary/devices > > > ├── 2-002d.gpio.0 > > > ├── 2-002d.pwm.0 > > > ├── 2-002d.aux.0 > > > ├── 2-002d.bridge.0 > > > ├── 4-002d.gpio.0 > > > ├── 4-002d.pwm.0 > > > ├── 4-002d.aux.0 > > > └── 4-002d.bridge.0 > > > > > > ...and I think that's guaranteed to be unique because all the i2c > > > devices are flat in "/sys/bus/i2c/devices". > > > > Correct. > > So given everything, using the dev_name() of the "parent" sounds > pretty good and seems like it addresses everyone's concerns. Was there > a part of the conversation where someone pointed out problems with it > that I missed? Is the next step to post a patch implementing that? > It'll change sysfs paths and dev names for everyone using AUX bus, but > presumably that's OK? It also requires changing in the way the auxiliary_match_id() works. Currently matching is done using modname + ID. So, maybe using MODNAME.NAME.parent-name.ID is better (e.g. ti_sn65dsi86.gpio.2-002d.1). It will still require changes to the match_id function, but they won't be that intrusive (one just has to skip two parts of the name instead of skipping just one). -- With best wishes Dmitry
Re: [PATCH 5/5] drm/client: Remove unused drm_client_modeset_check
On Wed, Oct 23, 2024 at 12:29:34AM +0100, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > drm_client_modeset_check() was explicitly added in 2020 by > commit 64593f2a6fc9 ("drm/client: Add drm_client_modeset_check()") > but has never been used. > > Remove it. If you are removing it, it makes more sense to revert the mentioned commit completely, dropping the third argument of drm_client_modeset_commit_atomic(). > > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_client_modeset.c | 24 > include/drm/drm_client.h | 1 - > 2 files changed, 25 deletions(-) > > diff --git a/drivers/gpu/drm/drm_client_modeset.c > b/drivers/gpu/drm/drm_client_modeset.c > index cee5eafbfb81..69e1ce4d18cd 100644 > --- a/drivers/gpu/drm/drm_client_modeset.c > +++ b/drivers/gpu/drm/drm_client_modeset.c > @@ -1126,30 +1126,6 @@ static int drm_client_modeset_commit_legacy(struct > drm_client_dev *client) > return ret; > } > > -/** > - * drm_client_modeset_check() - Check modeset configuration > - * @client: DRM client > - * > - * Check modeset configuration. > - * > - * Returns: > - * Zero on success or negative error code on failure. > - */ > -int drm_client_modeset_check(struct drm_client_dev *client) > -{ > - int ret; > - > - if (!drm_drv_uses_atomic_modeset(client->dev)) > - return 0; > - > - mutex_lock(&client->modeset_mutex); > - ret = drm_client_modeset_commit_atomic(client, true, true); > - mutex_unlock(&client->modeset_mutex); > - > - return ret; > -} > -EXPORT_SYMBOL(drm_client_modeset_check); > - > /** > * drm_client_modeset_commit_locked() - Force commit CRTC configuration > * @client: DRM client > diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h > index 560aae47e06d..e1fd32adb3e9 100644 > --- a/include/drm/drm_client.h > +++ b/include/drm/drm_client.h > @@ -176,7 +176,6 @@ int drm_client_modeset_create(struct drm_client_dev > *client); > void drm_client_modeset_free(struct drm_client_dev *client); > int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int > width, unsigned int height); > bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int > *rotation); > -int drm_client_modeset_check(struct drm_client_dev *client); > int drm_client_modeset_commit_locked(struct drm_client_dev *client); > int drm_client_modeset_commit(struct drm_client_dev *client); > int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); > -- > 2.47.0 > -- With best wishes Dmitry
Re: [PATCH 2/5] drm/sysfs: Remove unused drm_class_device_(un)register
On Wed, Oct 23, 2024 at 12:29:31AM +0100, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > drm_class_device_register() and drm_class_device_unregister() have been > unused since > commit ed89fff97382 ("drm/ttm: drop sysfs directory") > > Remove them. > > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_sysfs.c | 32 > include/drm/drm_sysfs.h | 4 ---- > 2 files changed, 36 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH 1/5] drm: Remove unused drm_atomic_helper_commit_planes_on_crtc
On Wed, Oct 23, 2024 at 12:29:30AM +0100, li...@treblig.org wrote: > From: "Dr. David Alan Gilbert" > > The last use of drm_atomic_helper_commit_planes_on_crtc() was removed > in 2018 by > commit 6c246b81f938 ("drm/i915: Replace call to commit_planes_on_crtc with > internal update, v2.") > > Remove it. > > Signed-off-by: Dr. David Alan Gilbert > --- > drivers/gpu/drm/drm_atomic_helper.c | 72 - > include/drm/drm_atomic_helper.h | 1 - > 2 files changed, 73 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support
On Mon, Oct 28, 2024 at 11:12:00AM +, Biju Das wrote: > Hi Dmitry, Liu, > > > -Original Message- > > From: Dmitry Baryshkov > > Sent: 28 October 2024 10:20 > > Subject: Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support > > > > Hi, > > > > On Mon, 28 Oct 2024 at 04:37, Liu Ying wrote: > > > > > > Hi, > > > > > > This patch series aims to add ITE IT6263 LVDS to HDMI converter on > > > i.MX8MP EVK. Combined with LVDS receiver and HDMI 1.4a transmitter, > > > the IT6263 supports LVDS input and HDMI 1.4 output by conversion > > > function. IT6263 product link can be found at [1]. > > > > > > Patch 1 is a preparation patch to allow display mode of an existing > > > panel to pass the added mode validation logic in patch 3. > > > > > > Patch 2 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to find > > > the next non-panel bridge, that is the IT6263 in this case. > > > > > > Patch 3 adds mode validation logic to i.MX8MP LDB bridge driver > > > against "ldb" clock so that it can filter out unsupported display > > > modes read from EDID. > > > > > > Patch 4 adds MEDIA_BUS_FMT_RGB101010_1X7X5_{SPWG,JEIDA} support, as > > > they are supported by IT6263(with LVDS data bit reversed order). > > > > > > Patch 5 makes drm_of.c use MEDIA_BUS_FMT_RGB101010_1X7X5_{JEIDA,SPWG}. > > > > > > Patch 6 supports getting dual-link LVDS pixel order for the sink side > > > as needed by IT6263 driver. > > > > > > Patch 7 documents jeida-30 and vesa-30 data mappings in > > > lvds-data-mapping.yaml, as needed by IT6263 DT binding. > > > > > > Patch 8 extracts common dual-link LVDS display properties into new > > > lvds-dual-ports.yaml so that IT6263 DT binding can reference it. > > > > > > Patch 9 adds DT binding for IT6263. > > > > > > Patch 10 adds IT6263 bridge driver. Only video output is supported. > > > > > > Patch 11 adds DT overlays to support NXP adapter cards[2][3] with > > > IT6263 populated. > > > > > > Patch 12 enables the IT6263 bridge driver in defconfig. > > > > > > Patch 13 updates MAINTAINERS to add maintainer for IT6263 driver. > > > > This has pretty complicated structure from the merging point of view. > > > > I propose we take patches 6, 8, 9 (without 30-bit formats, they can be > > dropped while applying), 11, 12 > > (?) and 13 through drm-misc in one batch (once DT maintainers review the > > binding parts). This looks > > like a minimal set, having no extra dependencies. > > > > > The second set might be 4, 5 + new patch, re-adding 30-bit formats to > > IT6263 binding (no driver changes are necessary). This can go in > > separately, after an Ack from media > > maintainers. > > > > Of course both sets can go together if linux-media maintainers reacts > > quickly and ack merging media- > > formats patch through drm-misc tree. > > > > The rest of the patches don't have such strong dependencies and go in once > > ready / reviewed. > > > > WDYT? > > I guess, 6,8,9(without 30-bit formats), 10, 12 and 13. > > 11 may have dependency on 1, 2 and 3 as it is SoC specific. Yes, of course, 10, not 11. > Then 4, 5 + new patch, re-adding 30-bit formats to IT6263 binding. -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Mon, Oct 28, 2024 at 12:31:50PM +0100, Konrad Dybcio wrote: > On 28.10.2024 11:52 AM, Dmitry Baryshkov wrote: > > On Mon, Oct 28, 2024 at 11:36:15AM +0100, Konrad Dybcio wrote: > >> On 28.10.2024 11:27 AM, Dmitry Baryshkov wrote: > >>> On Mon, 28 Oct 2024 at 12:08, Akhil P Oommen > >>> wrote: > >>>> > >>>> On 10/28/2024 1:56 PM, Dmitry Baryshkov wrote: > >>>>> On Sun, Oct 27, 2024 at 11:35:47PM +0530, Akhil P Oommen wrote: > >>>>>> Clang-19 and above sometimes end up with multiple copies of the large > >>>>>> a6xx_hfi_msg_bw_table structure on the stack. The problem is that > >>>>>> a6xx_hfi_send_bw_table() calls a number of device specific functions to > >>>>>> fill the structure, but these create another copy of the structure on > >>>>>> the stack which gets copied to the first. > >>>>>> > >>>>>> If the functions get inlined, that busts the warning limit: > >>>>>> > >>>>>> drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size > >>>>>> (1032) exceeds limit (1024) in 'a6xx_hfi_send_bw_table' > >>>>>> [-Werror,-Wframe-larger-than] > >>>>>> > >>>>>> Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > >>>>>> the stack. Also, use this opportunity to skip re-initializing this > >>>>>> table > >>>>>> to optimize gpu wake up latency. > >>>>>> > >>>>>> Cc: Arnd Bergmann > >>>>>> > >>>>>> Signed-off-by: Akhil P Oommen > >>>>>> --- > >>>>>> drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + > >>>>>> drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 > >>>>>> ++ > >>>>>> 2 files changed, 23 insertions(+), 12 deletions(-) > >>>>>> > >>>>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>>>> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>>>> index 94b6c5cab6f4..b4a79f88ccf4 100644 > >>>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>>>> @@ -99,6 +99,7 @@ struct a6xx_gmu { > >>>>>> struct completion pd_gate; > >>>>>> > >>>>>> struct qmp *qmp; > >>>>>> +struct a6xx_hfi_msg_bw_table *bw_table; > >>>>>> }; > >>>>>> > >>>>>> static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) > >>>>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>>>> b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>>>> index cdb3f6e74d3e..55e51c81be1f 100644 > >>>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>>>> @@ -630,32 +630,42 @@ static void a6xx_build_bw_table(struct > >>>>>> a6xx_hfi_msg_bw_table *msg) > >>>>>> > >>>>>> static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) > >>>>>> { > >>>>>> -struct a6xx_hfi_msg_bw_table msg = { 0 }; > >>>>>> +struct a6xx_hfi_msg_bw_table *msg; > >>>>>> struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, > >>>>>> gmu); > >>>>>> struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; > >>>>>> > >>>>>> +if (gmu->bw_table) > >>>>>> +goto send; > >>>>>> + > >>>>>> +msg = devm_kzalloc(gmu->dev, sizeof(*msg), GFP_KERNEL); > >>>>> > >>>>> Is it necessary after being sent? Isn't it better to just kzalloc() it > >>>>> and then kfree() it at the end of the function? > >>>> > >>>> Keeping it around will help to cut down unnecessary work during > >>>> subsequent gpu wake ups. > >>> > >>> Then, I'd say, it is better to make it a part of the a6xx_gpu struct. > >> > >> I think a6xx_gmu makes more logical sense here. > >> > >> FWIW, the driver allocates both _gmu and _gpu for all GPUs regardless > > > > Hmm, are we expected to handle / perform BW requests in case of GMU-less > > devices? > > opp-table does that for us > > In case of no gmu ("gmu wrapper"), Linux is the only entity that controls > things Ack -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Sun, Oct 27, 2024 at 11:35:47PM +0530, Akhil P Oommen wrote: > Clang-19 and above sometimes end up with multiple copies of the large > a6xx_hfi_msg_bw_table structure on the stack. The problem is that > a6xx_hfi_send_bw_table() calls a number of device specific functions to > fill the structure, but these create another copy of the structure on > the stack which gets copied to the first. > > If the functions get inlined, that busts the warning limit: > > drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size (1032) > exceeds limit (1024) in 'a6xx_hfi_send_bw_table' [-Werror,-Wframe-larger-than] > > Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > the stack. Also, use this opportunity to skip re-initializing this table > to optimize gpu wake up latency. > > Cc: Arnd Bergmann > Please no empty lines between tags. > Signed-off-by: Akhil P Oommen After all the discussions: Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + > drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 ++ > 2 files changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > index 94b6c5cab6f4..b4a79f88ccf4 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > @@ -99,6 +99,7 @@ struct a6xx_gmu { > struct completion pd_gate; > > struct qmp *qmp; > + struct a6xx_hfi_msg_bw_table *bw_table; > }; > > static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > index cdb3f6e74d3e..55e51c81be1f 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > @@ -630,32 +630,42 @@ static void a6xx_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > > static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) > { > - struct a6xx_hfi_msg_bw_table msg = { 0 }; > + struct a6xx_hfi_msg_bw_table *msg; > struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); > struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; > > + if (gmu->bw_table) > + goto send; > + > + msg = devm_kzalloc(gmu->dev, sizeof(*msg), GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > if (adreno_is_a618(adreno_gpu)) > - a618_build_bw_table(&msg); > + a618_build_bw_table(msg); > else if (adreno_is_a619(adreno_gpu)) > - a619_build_bw_table(&msg); > + a619_build_bw_table(msg); > else if (adreno_is_a640_family(adreno_gpu)) > - a640_build_bw_table(&msg); > + a640_build_bw_table(msg); > else if (adreno_is_a650(adreno_gpu)) > - a650_build_bw_table(&msg); > + a650_build_bw_table(msg); > else if (adreno_is_7c3(adreno_gpu)) > - adreno_7c3_build_bw_table(&msg); > + adreno_7c3_build_bw_table(msg); > else if (adreno_is_a660(adreno_gpu)) > - a660_build_bw_table(&msg); > + a660_build_bw_table(msg); > else if (adreno_is_a690(adreno_gpu)) > - a690_build_bw_table(&msg); > + a690_build_bw_table(msg); > else if (adreno_is_a730(adreno_gpu)) > - a730_build_bw_table(&msg); > + a730_build_bw_table(msg); > else if (adreno_is_a740_family(adreno_gpu)) > - a740_build_bw_table(&msg); > + a740_build_bw_table(msg); > else > - a6xx_build_bw_table(&msg); > + a6xx_build_bw_table(msg); Note for the future improvement: this begs to be migrated to the catalog data, adding device-specific callback instead of this if/else series. > + > + gmu->bw_table = msg; > > - return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, &msg, sizeof(msg), > +send: > + return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, gmu->bw_table, > sizeof(*(gmu->bw_table)), > NULL, 0); > } > > > --- > base-commit: 74c374648ed08efb2ef339656f2764c28c046956 > change-id: 20241024-stack-size-fix-28af7abd3fab > > Best regards, > -- > Akhil P Oommen > -- With best wishes Dmitry
Re: [PATCH V2 drm-dp 2/4] drm/hisilicon/hibmc: add dp link moduel in hibmc
On Tue, Oct 22, 2024 at 08:41:46PM +0800, Yongbang Shi wrote: > From: baihan li > > Add link training process functions in this moduel. We should probably have a bounty for a developer who finally writes a generic DP link training helpers. > Signed-off-by: baihan li Missing SoB > --- > ChangeLog: > v1 -> v2: > - using drm_dp_* functions implement dp link training process, suggested by > Jani Nikula. > - fix build errors reported by kernel test robot > Closes: > https://lore.kernel.org/oe-kbuild-all/202410031735.8irzzr6t-...@intel.com/ > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 344 +++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h | 25 ++ > 3 files changed, 370 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index 8770ec6dfffd..94d77da88bbf 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,5 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > -dp/dp_aux.o > +dp/dp_aux.o dp/dp_link.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > new file mode 100644 > index ..b02a536e0689 > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c > @@ -0,0 +1,344 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > +#include > +#include > +#include "dp_comm.h" > +#include "dp_reg.h" > +#include "dp_link.h" > +#include "dp_aux.h" > + > +const u8 link_rate_map[] = {DP_LINK_BW_1_62, DP_LINK_BW_2_7, > + DP_LINK_BW_5_4, DP_LINK_BW_8_1}; > + > +static int dp_link_training_configure(struct dp_dev *dp) > +{ > + u8 buf[2]; > + int ret; > + > + /* DP 2 lane */ > + dp_write_bits(dp->base + DP_PHYIF_CTRL0, DP_CFG_LANE_DATA_EN, > + dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x3 : 0x1); > + dp_write_bits(dp->base + DP_DPTX_GCTL0, DP_CFG_PHY_LANE_NUM, > + dp->link.cap.lanes == DP_LANE_NUM_2 ? 0x1 : 0); > + > + /* enhanced frame */ > + dp_write_bits(dp->base + DP_VIDEO_CTRL, DP_CFG_STREAM_FRAME_MODE, 0x1); > + > + /* set rate and lane count */ > + buf[0] = dp_get_link_rate(dp->link.cap.link_rate); > + buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes; > + ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); > + if (ret != sizeof(buf)) { > + drm_err(dp->dev, "dp aux write link rate and lanes failed, ret: > %d\n", ret); > + return ret; > + } > + > + /* set 8b/10b and downspread */ > + buf[0] = 0x10; > + buf[1] = 0x1; > + ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, sizeof(buf)); > + if (ret != sizeof(buf)) > + drm_err(dp->dev, "dp aux write 8b/10b and downspread failed, > ret: %d\n", ret); > + > + ret = drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd); > + if (ret) > + drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); > + > + return ret; > +} > + > +static int dp_link_pattern2dpcd(struct dp_dev *dp, enum dp_pattern_e pattern) > +{ > + switch (pattern) { > + case DP_PATTERN_NO: > + return DP_TRAINING_PATTERN_DISABLE; > + case DP_PATTERN_TPS1: > + return DP_TRAINING_PATTERN_1; > + case DP_PATTERN_TPS2: > + return DP_TRAINING_PATTERN_2; > + case DP_PATTERN_TPS3: > + return DP_TRAINING_PATTERN_3; > + case DP_PATTERN_TPS4: > + return DP_TRAINING_PATTERN_4; > + default: > + drm_err(dp->dev, "dp link unknown pattern %d\n", pattern); > + return -EINVAL; Why do you need the extra defines / wrappers? Can you use DP_TRAINING_PATTERN_foo directly? > + } > +} > + > +static int dp_link_set_pattern(struct dp_dev *dp, enum dp_pattern_e pattern) > +{ > + int ret; > + u8 buf; > + > + ret = dp_link_pattern2dpcd(dp, pattern); > + if (ret < 0) > + return ret; > + > + buf = (u8)ret; > + if (pattern != DP_TRAINING_PATTERN_DISABLE && pattern != > DP_TRAINING_PATTERN_4) { > + buf |= DP_LINK_SCRAMBLING_DISABLE; > + dp_write_bits(dp->base + DP_PHYIF_CTRL0, DP_CFG_SCRAMBLE_EN, > 0x1); > + } else { > + dp_write_bits(dp->base + DP_PHYIF_CTRL0, DP_CFG_SCRAMBLE_EN, 0); > + } > + > + dp_write_bits(dp->base + DP_PHYIF_CTRL0, DP_CFG_PAT_SEL, pattern); > + > + ret =
Re: [PATCH V2 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc
On Tue, Oct 22, 2024 at 08:41:45PM +0800, Yongbang Shi wrote: > From: baihan li > > Add dp aux read/write functions. They are basic functions > and will be used later. > > Signed-off-by: baihan li Generic comment: all patches miss your SoB. This is SoB of the author, so you as a submitted should add yours. -- With best wishes Dmitry
[PATCH 0/3] drm/msm/dp: mass-rename symbols
The LKP reported [1] a symbol clash between the drm/msm/dp and the HIMBC driver being sumbitted, because both of them use a generic dp_ prefix for a lot of symbols. It's a hight time we made msm/dp driver use something less generic, like msm_dp. [1] https://lore.kernel.org/oe-kbuild-all/202410250305.uhkdhtxy-...@intel.com/ Signed-off-by: Dmitry Baryshkov --- Dmitry Baryshkov (3): drm/msm/dp: prefix all symbols with msm_dp_ drm/msm/dp: rename edp_ bridge functions and struct drm/msm/dp: tidy up platform data names drivers/gpu/drm/msm/dp/dp_audio.c | 294 ++-- drivers/gpu/drm/msm/dp/dp_audio.h | 38 +- drivers/gpu/drm/msm/dp/dp_aux.c | 148 +++--- drivers/gpu/drm/msm/dp/dp_aux.h | 18 +- drivers/gpu/drm/msm/dp/dp_catalog.c | 734 ++--- drivers/gpu/drm/msm/dp/dp_catalog.h | 118 ++--- drivers/gpu/drm/msm/dp/dp_ctrl.c| 482 +-- drivers/gpu/drm/msm/dp/dp_ctrl.h| 40 +- drivers/gpu/drm/msm/dp/dp_debug.c | 68 +-- drivers/gpu/drm/msm/dp/dp_debug.h | 10 +- drivers/gpu/drm/msm/dp/dp_display.c | 904 ++-- drivers/gpu/drm/msm/dp/dp_display.h | 18 +- drivers/gpu/drm/msm/dp/dp_drm.c | 142 +++--- drivers/gpu/drm/msm/dp/dp_drm.h | 22 +- drivers/gpu/drm/msm/dp/dp_link.c| 432 - drivers/gpu/drm/msm/dp/dp_link.h| 44 +- drivers/gpu/drm/msm/dp/dp_panel.c | 254 +- drivers/gpu/drm/msm/dp/dp_panel.h | 42 +- drivers/gpu/drm/msm/dp/dp_utils.c | 20 +- drivers/gpu/drm/msm/dp/dp_utils.h | 8 +- 20 files changed, 1918 insertions(+), 1918 deletions(-) --- base-commit: dec9255a128e19c5fcc3bdb18175d78094cc624d change-id: 20241028-msm-dp-rename-f0eed848e231 Best regards, -- Dmitry Baryshkov
Re: [PATCH V2 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc
On Tue, Oct 22, 2024 at 08:41:45PM +0800, Yongbang Shi wrote: > From: baihan li > > Add dp aux read/write functions. They are basic functions > and will be used later. > > Signed-off-by: baihan li > --- > ChangeLog: > v1 -> v2: > - using drm_dp_aux frame implement dp aux read and write functions, > suggested by Jani Nikula. > - using drm dp header files' dp macros instead, suggested by Andy Yan. > > v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongb...@huawei.com/ > --- > drivers/gpu/drm/hisilicon/hibmc/Makefile | 3 +- > drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c | 162 +++ > drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.h | 31 > drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 74 + > drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 76 + > 5 files changed, 345 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h > create mode 100644 drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile > b/drivers/gpu/drm/hisilicon/hibmc/Makefile > index d25c75e60d3d..8770ec6dfffd 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile > +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile > @@ -1,4 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0-only > -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o > +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o > hibmc_drm_i2c.o \ > +dp/dp_aux.o > > obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o > diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > new file mode 100644 > index ..0078cafdf86d > --- /dev/null > +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > @@ -0,0 +1,162 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// Copyright (c) 2024 Hisilicon Limited. > + > +#include > +#include > +#include > +#include > +#include > +#include "dp_comm.h" > +#include "dp_reg.h" > +#include "dp_aux.h" > + > +#define DP_MIN_PULSE_NUM 0x9 > + > +static void dp_aux_reset(const struct dp_dev *dp) > +{ > + dp_write_bits(dp->base + DP_DPTX_RST_CTRL, DP_CFG_AUX_RST_N, 0x0); > + usleep_range(10, 15); > + dp_write_bits(dp->base + DP_DPTX_RST_CTRL, DP_CFG_AUX_RST_N, 0x1); > +} > + > +static void dp_aux_read_data(struct dp_dev *dp, u8 *buf, u8 size) > +{ > + u32 reg_num; > + u32 value; > + u32 num; > + u8 i, j; > + > + reg_num = round_up(size, AUX_4_BYTE) / AUX_4_BYTE; > + for (i = 0; i < reg_num; i++) { > + /* number of bytes read from a single register */ > + num = min(size - i * AUX_4_BYTE, AUX_4_BYTE); > + value = readl(dp->base + DP_AUX_RD_DATA0 + i * AUX_4_BYTE); > + /* convert the 32-bit value of the register to the buffer. */ > + for (j = 0; j < num; j++) > + buf[i * AUX_4_BYTE + j] = value >> (j * AUX_8_BIT); > + } > +} > + > +static void dp_aux_write_data(struct dp_dev *dp, u8 *buf, u8 size) > +{ > + u32 reg_num; > + u32 value; > + u8 i, j; > + u32 num; > + > + reg_num = round_up(size, AUX_4_BYTE) / AUX_4_BYTE; > + for (i = 0; i < reg_num; i++) { > + /* number of bytes written to a single register */ > + num = min_t(u8, size - i * AUX_4_BYTE, AUX_4_BYTE); > + value = 0; > + /* obtain the 32-bit value written to a single register. */ > + for (j = 0; j < num; j++) > + value |= buf[i * AUX_4_BYTE + j] << (j * AUX_8_BIT); > + /* writing data to a single register */ > + writel(value, dp->base + DP_AUX_WR_DATA0 + i * AUX_4_BYTE); > + } > +} > + > +static u32 dp_aux_build_cmd(const struct drm_dp_aux_msg *msg) > +{ > + u32 aux_cmd = msg->request; > + > + if (msg->size) > + aux_cmd |= (msg->size - 1) << AUX_CMD_REQ_LEN_S; > + else > + aux_cmd |= 1 << AUX_CMD_I2C_ADDR_ONLY_S; > + > + aux_cmd |= msg->address << AUX_CMD_ADDR_S; > + > + return aux_cmd; > +} > + > +/* ret >= 0 ,ret is size; ret < 0, ret is err code */ > +static int dp_aux_parse_xfer(struct dp_dev *dp, struct drm_dp_aux_msg *msg) > +{ > + u32 buf_data_cnt; > + u32 aux_status; > + int ret = 0; > + > + aux_status = readl(dp->base + DP_AUX_STATUS); > + msg->reply = FIELD_GET(DP_CFG_AUX_STATUS, aux_status); > + > + if (aux_status & DP_CFG_AUX_TIMEOUT) > + return -ETIMEDOUT; > + > + /* only address */ > + if (!msg->size) > + return 0; > + > + if (msg->reply != DP_AUX_NATIVE_REPLY_ACK) > + return 0; > + > + buf_data_cnt = FIELD_GET(DP_CFG_AUX_READY_DATA_BYTE, aux_status); > + > + switch (msg->request) { > + case DP_AUX_NATIVE_WRITE: > + re
[PATCH 3/3] drm/msm/dp: tidy up platform data names
Follow the established symbol name pattern and rename platform data structures. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 38 ++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 5cc349f672c0..aba925aab7ad 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -118,7 +118,7 @@ struct msm_dp_desc { bool wide_bus_supported; }; -static const struct msm_dp_desc sa8775p_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sa8775p[] = { { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0af5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -126,25 +126,25 @@ static const struct msm_dp_desc sa8775p_dp_descs[] = { {} }; -static const struct msm_dp_desc sc7180_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc7180[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc7280_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc7280[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0aea, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc8180x_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc8180x[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc sc8280xp_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sc8280xp[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -156,12 +156,12 @@ static const struct msm_dp_desc sc8280xp_dp_descs[] = { {} }; -static const struct msm_dp_desc sm8650_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_sm8650[] = { { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, {} }; -static const struct msm_dp_desc x1e80100_dp_descs[] = { +static const struct msm_dp_desc msm_dp_desc_x1e80100[] = { { .io_start = 0x0ae9, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true }, { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true }, { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true }, @@ -170,18 +170,18 @@ static const struct msm_dp_desc x1e80100_dp_descs[] = { }; static const struct of_device_id msm_dp_dt_match[] = { - { .compatible = "qcom,sa8775p-dp", .data = &sa8775p_dp_descs }, - { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, - { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs }, - { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs }, - { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs }, - { .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs }, - { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_dp_descs }, - { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sm8350-dp", .data = &sc7180_dp_descs }, - { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, - { .compatible = "qcom,x1e80100-dp", .data = &x1e80100_dp_descs }, + { .compatible = "qcom,sa8775p-dp", .data = &msm_dp_desc_sa8775p }, + { .compatible = "qcom,sc7180-dp", .data = &msm_dp_desc_sc7180 }, + { .compatible = "qcom,sc7280-dp", .data = &msm_dp_desc_sc7280 }, + { .compatible = "qcom,sc7280-edp", .data = &msm_dp_desc_sc7280 }, + { .compatible = "qcom,sc8180x-dp", .data = &msm_dp_desc_sc8180x }, + { .compatible = "qcom,sc8180x-edp", .data = &msm_dp_desc_sc8180x }, + { .compatible = "qcom,sc8280xp-dp", .data = &msm_dp_desc_sc8280xp }, + { .compatible = "qcom,sc8280xp-edp", .data = &msm_dp_desc_sc8280xp }, + { .c
[PATCH 2/3] drm/msm/dp: rename edp_ bridge functions and struct
Follow the estalished prefix and rename eDP bridge symbols to use msm_dp_ prefix, moving the edp to the end of the symbol name. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_drm.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 6a0840266c0f..ff9ce9b15234 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -115,7 +115,7 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = { .debugfs_init = msm_dp_bridge_debugfs_init, }; -static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, +static int msm_dp_bridge_atomic_check_edp(struct drm_bridge *drm_bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -136,7 +136,7 @@ static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, return 0; } -static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, +static void msm_dp_bridge_atomic_enable_edp(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -147,7 +147,7 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, /* * Check the old state of the crtc to determine if the panel -* was put into psr state previously by the edp_bridge_atomic_disable. +* was put into psr state previously by the msm_dp_bridge_atomic_disable_edp. * If the panel is in psr, just exit psr state and skip the full * bridge enable sequence. */ @@ -166,7 +166,7 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, msm_dp_bridge_atomic_enable(drm_bridge, old_bridge_state); } -static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, +static void msm_dp_bridge_atomic_disable_edp(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -194,7 +194,7 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, * If old crtc state is active, then this is a display disable * call while the sink is in psr state. So, exit psr here. * The eDP controller will be disabled in the -* edp_bridge_atomic_post_disable function. +* msm_dp_bridge_atomic_post_disable_edp function. * * We observed sink is stuck in self refresh if psr exit is skipped * when display disable occurs while the sink is in psr state. @@ -211,7 +211,7 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, msm_dp_bridge_atomic_disable(drm_bridge, old_bridge_state); } -static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, +static void msm_dp_bridge_atomic_post_disable_edp(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state) { struct drm_atomic_state *atomic_state = old_bridge_state->base.state; @@ -228,7 +228,7 @@ static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, return; /* -* Self refresh mode is already set in edp_bridge_atomic_disable. +* Self refresh mode is already set in msm_dp_bridge_atomic_disable_edp. */ if (new_crtc_state->self_refresh_active) return; @@ -237,13 +237,13 @@ static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, } /** - * edp_bridge_mode_valid - callback to determine if specified mode is valid + * msm_dp_bridge_mode_valid_edp - callback to determine if specified mode is valid * @bridge: Pointer to drm bridge structure * @info: display info * @mode: Pointer to drm mode structure * Returns: Validity status for specified mode */ -static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, +static enum drm_mode_status msm_dp_bridge_mode_valid_edp(struct drm_bridge *bridge, const struct drm_display_info *info, const struct drm_display_mode *mode) { @@ -268,24 +268,24 @@ static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) +static void msm_dp_bridge_debugfs_init_edp(struct drm_bridge *bridge, struct dentry *root) { struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display; msm_dp_display_debugfs_init(dp, root, true); } -static const struct drm_bridge_funcs
Re: [PATCH] video: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
On Sat, Oct 26, 2024 at 11:56:34AM +0800, Zhen Lei wrote: > When information such as info->screen_base is not ready, calling > sh7760fb_free_mem() does not release memory correctly. Call > dma_free_coherent() instead. > > Fixes: 4a25e41831ee ("video: sh7760fb: SH7760/SH7763 LCDC framebuffer driver") > Signed-off-by: Zhen Lei > --- > drivers/video/fbdev/sh7760fb.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Mon, Oct 28, 2024 at 11:36:15AM +0100, Konrad Dybcio wrote: > On 28.10.2024 11:27 AM, Dmitry Baryshkov wrote: > > On Mon, 28 Oct 2024 at 12:08, Akhil P Oommen > > wrote: > >> > >> On 10/28/2024 1:56 PM, Dmitry Baryshkov wrote: > >>> On Sun, Oct 27, 2024 at 11:35:47PM +0530, Akhil P Oommen wrote: > >>>> Clang-19 and above sometimes end up with multiple copies of the large > >>>> a6xx_hfi_msg_bw_table structure on the stack. The problem is that > >>>> a6xx_hfi_send_bw_table() calls a number of device specific functions to > >>>> fill the structure, but these create another copy of the structure on > >>>> the stack which gets copied to the first. > >>>> > >>>> If the functions get inlined, that busts the warning limit: > >>>> > >>>> drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size > >>>> (1032) exceeds limit (1024) in 'a6xx_hfi_send_bw_table' > >>>> [-Werror,-Wframe-larger-than] > >>>> > >>>> Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > >>>> the stack. Also, use this opportunity to skip re-initializing this table > >>>> to optimize gpu wake up latency. > >>>> > >>>> Cc: Arnd Bergmann > >>>> > >>>> Signed-off-by: Akhil P Oommen > >>>> --- > >>>> drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + > >>>> drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 > >>>> ++ > >>>> 2 files changed, 23 insertions(+), 12 deletions(-) > >>>> > >>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>> index 94b6c5cab6f4..b4a79f88ccf4 100644 > >>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>>> @@ -99,6 +99,7 @@ struct a6xx_gmu { > >>>> struct completion pd_gate; > >>>> > >>>> struct qmp *qmp; > >>>> +struct a6xx_hfi_msg_bw_table *bw_table; > >>>> }; > >>>> > >>>> static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) > >>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>> b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>> index cdb3f6e74d3e..55e51c81be1f 100644 > >>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >>>> @@ -630,32 +630,42 @@ static void a6xx_build_bw_table(struct > >>>> a6xx_hfi_msg_bw_table *msg) > >>>> > >>>> static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) > >>>> { > >>>> -struct a6xx_hfi_msg_bw_table msg = { 0 }; > >>>> +struct a6xx_hfi_msg_bw_table *msg; > >>>> struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); > >>>> struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; > >>>> > >>>> +if (gmu->bw_table) > >>>> +goto send; > >>>> + > >>>> +msg = devm_kzalloc(gmu->dev, sizeof(*msg), GFP_KERNEL); > >>> > >>> Is it necessary after being sent? Isn't it better to just kzalloc() it > >>> and then kfree() it at the end of the function? > >> > >> Keeping it around will help to cut down unnecessary work during > >> subsequent gpu wake ups. > > > > Then, I'd say, it is better to make it a part of the a6xx_gpu struct. > > I think a6xx_gmu makes more logical sense here. > > FWIW, the driver allocates both _gmu and _gpu for all GPUs regardless Hmm, are we expected to handle / perform BW requests in case of GMU-less devices? -- With best wishes Dmitry
Re: [PATCH V2 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc
On Fri, Oct 25, 2024 at 03:52:49AM +0800, kernel test robot wrote: > Hi Yongbang, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on drm-misc/drm-misc-next] > [also build test ERROR on linus/master v6.12-rc4 next-20241024] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: > https://github.com/intel-lab-lkp/linux/commits/Yongbang-Shi/drm-hisilicon-hibmc-add-dp-aux-in-hibmc/20241022-204925 > base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next > patch link: > https://lore.kernel.org/r/20241022124148.1952761-2-shiyongbang%40huawei.com > patch subject: [PATCH V2 drm-dp 1/4] drm/hisilicon/hibmc: add dp aux in hibmc > config: arm64-randconfig-004-20241024 > (https://download.01.org/0day-ci/archive/20241025/202410250305.uhkdhtxy-...@intel.com/config) > compiler: aarch64-linux-gcc (GCC) 14.1.0 > reproduce (this is a W=1 build): > (https://download.01.org/0day-ci/archive/20241025/202410250305.uhkdhtxy-...@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version > of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot > | Closes: > https://lore.kernel.org/oe-kbuild-all/202410250305.uhkdhtxy-...@intel.com/ > > All errors (new ones prefixed by >>): > >aarch64-linux-ld: drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.o: in function > `dp_aux_init': > >> drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c:154: multiple definition of > >> `dp_aux_init'; drivers/gpu/drm/msm/dp/dp_aux.o:dp_aux.c:(.text+0x8a0): > >> first defined here I think both of us should switch to a more generic names. I'll send a patchset for msm/dp, please use some less generic prefix for hibmc driver. > > > vim +154 drivers/gpu/drm/hisilicon/hibmc/dp/dp_aux.c > >152 >153void dp_aux_init(struct dp_dev *dp) > > 154{ > > -- > 0-DAY CI Kernel Test Service > https://github.com/intel/lkp-tests/wiki -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Mon, Oct 28, 2024 at 11:39:16AM +0100, Konrad Dybcio wrote: > On 28.10.2024 10:52 AM, Akhil P Oommen wrote: > > On 10/28/2024 12:13 AM, Arnd Bergmann wrote: > >> On Sun, Oct 27, 2024, at 18:05, Akhil P Oommen wrote: > >>> Clang-19 and above sometimes end up with multiple copies of the large > >>> a6xx_hfi_msg_bw_table structure on the stack. The problem is that > >>> a6xx_hfi_send_bw_table() calls a number of device specific functions to > >>> fill the structure, but these create another copy of the structure on > >>> the stack which gets copied to the first. > >>> > >>> If the functions get inlined, that busts the warning limit: > >>> > >>> drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size > >>> (1032) exceeds limit (1024) in 'a6xx_hfi_send_bw_table' > >>> [-Werror,-Wframe-larger-than] > >>> > >>> Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > >>> the stack. Also, use this opportunity to skip re-initializing this table > >>> to optimize gpu wake up latency. > >>> > >>> Cc: Arnd Bergmann > >> > >> Please change this to "Reported-by:" > > > > Sure. > > > >> > >> The patch looks correct to me, just one idea for improvement. > >> > >>> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>> index 94b6c5cab6f4..b4a79f88ccf4 100644 > >>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >>> @@ -99,6 +99,7 @@ struct a6xx_gmu { > >>> struct completion pd_gate; > >>> > >>> struct qmp *qmp; > >>> + struct a6xx_hfi_msg_bw_table *bw_table; > >>> }; > >> > >> I think the bw_table is better just embedded > >> in here rather than referenced as a pointer: > >> > > There are some low tier chipsets with relatively lower RAM size that > > doesn't require this table. So, dynamically allocating this here helps > > to save 640 bytes (minus the overhead of tracking). > > I'd second this, said chipsets often ship with 1-2 GiB of RAM (which > is still a lot in comparison, but you know.. every little bit counts) Okay from my side. Yeah, poor Gnome runnning on top of 1 GiB device is very sad. -- With best wishes Dmitry
Re: [PATCH v6 2/9] drm/msm/dpu: move pstate->pipe initialization to dpu_plane_atomic_check
On Fri, Oct 25, 2024 at 12:00:20PM -0700, Abhinav Kumar wrote: > > > On 10/24/2024 5:20 PM, Dmitry Baryshkov wrote: > > In preparation for virtualized planes support, move pstate->pipe > > initialization from dpu_plane_reset() to dpu_plane_atomic_check(). In > > case of virtual planes the plane's pipe will not be known up to the > > point of atomic_check() callback. > > > > I had R-bed this in v5. Did anything change in v6? No, nothing. I'm sorry for forgetting to run `b4 trailers -u`. > But one comment below. > > > Signed-off-by: Dmitry Baryshkov > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 25 +++-- > > 1 file changed, 11 insertions(+), 14 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > index 37faf5b238b0..725c9a5826fd 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > > @@ -797,13 +797,22 @@ static int dpu_plane_atomic_check(struct drm_plane > > *plane, > > uint32_t max_linewidth; > > unsigned int rotation; > > uint32_t supported_rotations; > > - const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap; > > - const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk; > > + const struct dpu_sspp_cfg *pipe_hw_caps; > > + const struct dpu_sspp_sub_blks *sblk; > > if (new_plane_state->crtc) > > crtc_state = drm_atomic_get_new_crtc_state(state, > > > > new_plane_state->crtc); > > + pipe->sspp = dpu_rm_get_sspp(&kms->rm, pdpu->pipe); > > + r_pipe->sspp = NULL; > > + > > + if (!pipe->sspp) > > + return -EINVAL; > > + > > + pipe_hw_caps = pipe->sspp->cap; > > + sblk = pipe->sspp->cap->sblk; > > + > > min_scale = FRAC_16_16(1, sblk->maxupscale); > > ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, > > min_scale, > > Do you think it will be better to move the get_sspp() call after the > drm_atomic_helper_check_plane_state()? I'd say, it makes no difference. I'll check your suggestion if I have to send another iteration. > > > @@ -820,7 +829,6 @@ static int dpu_plane_atomic_check(struct drm_plane > > *plane, > > pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; > > r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; > > r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; > > - r_pipe->sspp = NULL; > > pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos; > > if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) { > > @@ -1286,7 +1294,6 @@ static void dpu_plane_reset(struct drm_plane *plane) > > { > > struct dpu_plane *pdpu; > > struct dpu_plane_state *pstate; > > - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); > > if (!plane) { > > DPU_ERROR("invalid plane\n"); > > @@ -1308,16 +1315,6 @@ static void dpu_plane_reset(struct drm_plane *plane) > > return; > > } > > - /* > > -* Set the SSPP here until we have proper virtualized DPU planes. > > -* This is the place where the state is allocated, so fill it fully. > > -*/ > > - pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); > > - pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO; > > - pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE; > > - > > - pstate->r_pipe.sspp = NULL; > > - > > __drm_atomic_helper_plane_reset(plane, &pstate->base); > > } > > -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Mon, 28 Oct 2024 at 12:08, Akhil P Oommen wrote: > > On 10/28/2024 1:56 PM, Dmitry Baryshkov wrote: > > On Sun, Oct 27, 2024 at 11:35:47PM +0530, Akhil P Oommen wrote: > >> Clang-19 and above sometimes end up with multiple copies of the large > >> a6xx_hfi_msg_bw_table structure on the stack. The problem is that > >> a6xx_hfi_send_bw_table() calls a number of device specific functions to > >> fill the structure, but these create another copy of the structure on > >> the stack which gets copied to the first. > >> > >> If the functions get inlined, that busts the warning limit: > >> > >> drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size > >> (1032) exceeds limit (1024) in 'a6xx_hfi_send_bw_table' > >> [-Werror,-Wframe-larger-than] > >> > >> Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > >> the stack. Also, use this opportunity to skip re-initializing this table > >> to optimize gpu wake up latency. > >> > >> Cc: Arnd Bergmann > >> > >> Signed-off-by: Akhil P Oommen > >> --- > >> drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + > >> drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 > >> ++ > >> 2 files changed, 23 insertions(+), 12 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >> index 94b6c5cab6f4..b4a79f88ccf4 100644 > >> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > >> @@ -99,6 +99,7 @@ struct a6xx_gmu { > >> struct completion pd_gate; > >> > >> struct qmp *qmp; > >> +struct a6xx_hfi_msg_bw_table *bw_table; > >> }; > >> > >> static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) > >> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >> b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >> index cdb3f6e74d3e..55e51c81be1f 100644 > >> --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >> +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > >> @@ -630,32 +630,42 @@ static void a6xx_build_bw_table(struct > >> a6xx_hfi_msg_bw_table *msg) > >> > >> static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) > >> { > >> -struct a6xx_hfi_msg_bw_table msg = { 0 }; > >> +struct a6xx_hfi_msg_bw_table *msg; > >> struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); > >> struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; > >> > >> +if (gmu->bw_table) > >> +goto send; > >> + > >> +msg = devm_kzalloc(gmu->dev, sizeof(*msg), GFP_KERNEL); > > > > Is it necessary after being sent? Isn't it better to just kzalloc() it > > and then kfree() it at the end of the function? > > Keeping it around will help to cut down unnecessary work during > subsequent gpu wake ups. Then, I'd say, it is better to make it a part of the a6xx_gpu struct. -- With best wishes Dmitry
Re: [PATCH v4 00/13] Add ITE IT6263 LVDS to HDMI converter support
Hi, On Mon, 28 Oct 2024 at 04:37, Liu Ying wrote: > > Hi, > > This patch series aims to add ITE IT6263 LVDS to HDMI converter on > i.MX8MP EVK. Combined with LVDS receiver and HDMI 1.4a transmitter, > the IT6263 supports LVDS input and HDMI 1.4 output by conversion > function. IT6263 product link can be found at [1]. > > Patch 1 is a preparation patch to allow display mode of an existing > panel to pass the added mode validation logic in patch 3. > > Patch 2 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to find > the next non-panel bridge, that is the IT6263 in this case. > > Patch 3 adds mode validation logic to i.MX8MP LDB bridge driver against > "ldb" clock so that it can filter out unsupported display modes read > from EDID. > > Patch 4 adds MEDIA_BUS_FMT_RGB101010_1X7X5_{SPWG,JEIDA} support, as they > are supported by IT6263(with LVDS data bit reversed order). > > Patch 5 makes drm_of.c use MEDIA_BUS_FMT_RGB101010_1X7X5_{JEIDA,SPWG}. > > Patch 6 supports getting dual-link LVDS pixel order for the sink side as > needed by IT6263 driver. > > Patch 7 documents jeida-30 and vesa-30 data mappings in > lvds-data-mapping.yaml, > as needed by IT6263 DT binding. > > Patch 8 extracts common dual-link LVDS display properties into new > lvds-dual-ports.yaml so that IT6263 DT binding can reference it. > > Patch 9 adds DT binding for IT6263. > > Patch 10 adds IT6263 bridge driver. Only video output is supported. > > Patch 11 adds DT overlays to support NXP adapter cards[2][3] with IT6263 > populated. > > Patch 12 enables the IT6263 bridge driver in defconfig. > > Patch 13 updates MAINTAINERS to add maintainer for IT6263 driver. This has pretty complicated structure from the merging point of view. I propose we take patches 6, 8, 9 (without 30-bit formats, they can be dropped while applying), 11, 12 (?) and 13 through drm-misc in one batch (once DT maintainers review the binding parts). This looks like a minimal set, having no extra dependencies. The second set might be 4, 5 + new patch, re-adding 30-bit formats to IT6263 binding (no driver changes are necessary). This can go in separately, after an Ack from media maintainers. Of course both sets can go together if linux-media maintainers reacts quickly and ack merging media-formats patch through drm-misc tree. The rest of the patches don't have such strong dependencies and go in once ready / reviewed. WDYT? -- With best wishes Dmitry
Re: [PATCH v4 13/13] MAINTAINERS: Add maintainer for ITE IT6263 driver
On Mon, Oct 28, 2024 at 10:37:40AM +0800, Liu Ying wrote: > Add myself as the maintainer of ITE IT6263 LVDS TO HDMI BRIDGE DRIVER. > > Signed-off-by: Liu Ying > --- > v4: > * No change. > > v3: > * No change. > > v2: > * New patch. (Maxime) > > MAINTAINERS | 8 > 1 file changed, 8 insertions(+) Acked-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v4 10/13] drm/bridge: Add ITE IT6263 LVDS to HDMI converter
On Mon, Oct 28, 2024 at 10:37:37AM +0800, Liu Ying wrote: > Add basic HDMI video output support. Currently, only RGB888 output > pixel format is supported. At the LVDS input side, the driver > supports single LVDS link and dual LVDS links with "jeida-24" LVDS > mapping. > > Product link: > https://www.ite.com.tw/en/product/cate1/IT6263 > > Signed-off-by: Liu Ying > Reviewed-by: Biju Das > Acked-by: Maxime Ripard Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: Fix excessive stack usage
On Sun, Oct 27, 2024 at 11:35:47PM +0530, Akhil P Oommen wrote: > Clang-19 and above sometimes end up with multiple copies of the large > a6xx_hfi_msg_bw_table structure on the stack. The problem is that > a6xx_hfi_send_bw_table() calls a number of device specific functions to > fill the structure, but these create another copy of the structure on > the stack which gets copied to the first. > > If the functions get inlined, that busts the warning limit: > > drivers/gpu/drm/msm/adreno/a6xx_hfi.c:631:12: error: stack frame size (1032) > exceeds limit (1024) in 'a6xx_hfi_send_bw_table' [-Werror,-Wframe-larger-than] > > Fix this by kmalloc-ating struct a6xx_hfi_msg_bw_table instead of using > the stack. Also, use this opportunity to skip re-initializing this table > to optimize gpu wake up latency. > > Cc: Arnd Bergmann > > Signed-off-by: Akhil P Oommen > --- > drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + > drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 ++ > 2 files changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > index 94b6c5cab6f4..b4a79f88ccf4 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h > @@ -99,6 +99,7 @@ struct a6xx_gmu { > struct completion pd_gate; > > struct qmp *qmp; > + struct a6xx_hfi_msg_bw_table *bw_table; > }; > > static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > index cdb3f6e74d3e..55e51c81be1f 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c > @@ -630,32 +630,42 @@ static void a6xx_build_bw_table(struct > a6xx_hfi_msg_bw_table *msg) > > static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) > { > - struct a6xx_hfi_msg_bw_table msg = { 0 }; > + struct a6xx_hfi_msg_bw_table *msg; > struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); > struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; > > + if (gmu->bw_table) > + goto send; > + > + msg = devm_kzalloc(gmu->dev, sizeof(*msg), GFP_KERNEL); Is it necessary after being sent? Isn't it better to just kzalloc() it and then kfree() it at the end of the function? > + if (!msg) > + return -ENOMEM; > + > if (adreno_is_a618(adreno_gpu)) > - a618_build_bw_table(&msg); > + a618_build_bw_table(msg); > else if (adreno_is_a619(adreno_gpu)) > - a619_build_bw_table(&msg); > + a619_build_bw_table(msg); > else if (adreno_is_a640_family(adreno_gpu)) > - a640_build_bw_table(&msg); > + a640_build_bw_table(msg); > else if (adreno_is_a650(adreno_gpu)) > - a650_build_bw_table(&msg); > + a650_build_bw_table(msg); > else if (adreno_is_7c3(adreno_gpu)) > - adreno_7c3_build_bw_table(&msg); > + adreno_7c3_build_bw_table(msg); > else if (adreno_is_a660(adreno_gpu)) > - a660_build_bw_table(&msg); > + a660_build_bw_table(msg); > else if (adreno_is_a690(adreno_gpu)) > - a690_build_bw_table(&msg); > + a690_build_bw_table(msg); > else if (adreno_is_a730(adreno_gpu)) > - a730_build_bw_table(&msg); > + a730_build_bw_table(msg); > else if (adreno_is_a740_family(adreno_gpu)) > - a740_build_bw_table(&msg); > + a740_build_bw_table(msg); > else > - a6xx_build_bw_table(&msg); > + a6xx_build_bw_table(msg); > + > + gmu->bw_table = msg; > > - return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, &msg, sizeof(msg), > +send: > + return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, gmu->bw_table, > sizeof(*(gmu->bw_table)), > NULL, 0); > } > > > --- > base-commit: 74c374648ed08efb2ef339656f2764c28c046956 > change-id: 20241024-stack-size-fix-28af7abd3fab > > Best regards, > -- > Akhil P Oommen > -- With best wishes Dmitry
Re: [PATCH 1/3] drm/msm: Avoid NULL dereference in msm_disp_state_print_regs()
On Mon, 14 Oct 2024 09:36:08 -0700, Douglas Anderson wrote: > If the allocation in msm_disp_state_dump_regs() failed then > `block->state` can be NULL. The msm_disp_state_print_regs() function > _does_ have code to try to handle it with: > > if (*reg) > dump_addr = *reg; > > [...] Applied, thanks! [3/3] drm/msm: Simplify NULL checking in msm_disp_state_dump_regs() https://gitlab.freedesktop.org/lumag/msm/-/commit/74c374648ed0 Best regards, -- Dmitry Baryshkov
Re: [PATCH] drm/msm/gpu: Fix missing error check for dev_pm_qos_add_request()
On Sat, Oct 26, 2024 at 05:37:38PM +0800, Jinjie Ruan wrote: > dev_pm_qos_add_request() can fail, and it returns -EINVAL in case of > wrong parameters, return -ENOMEM if there's not enough memory to allocate > for data structures, and return -ENODEV if the device has just been > removed from the system. If it fails in msm_devfreq_init(), there is > no point in going on, also call dev_pm_qos_remove_request() in the next > error path is also meaningless > > Fixes: 7c0ffcd40b16 ("drm/msm/gpu: Respect PM QoS constraints") > Signed-off-by: Jinjie Ruan > --- > drivers/gpu/drm/msm/msm_gpu_devfreq.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > I'm sorry, a similar patch has already been sent: https://patchwork.freedesktop.org/series/140162/ -- With best wishes Dmitry
Re: [PATCH v4 15/18] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode
On Tue, Oct 22, 2024 at 06:15:47PM -0700, Stephen Boyd wrote: > Quoting Dmitry Baryshkov (2024-09-20 02:38:53) > > On Sat, Aug 31, 2024 at 09:06:53PM GMT, Stephen Boyd wrote: > > Either way the problem seems to be that I need to associate one > drm_bridge with two displayport altmode drivers and pass some fwnode > handle to drm_connector_oob_hotplug_event() in a way that we can map > that back to the right output endpoint in the DP bridge graph. That > seems to imply that we need to pass the fwnode for the usb-c-connector > in addition to the fwnode for the drm_bridge, so that the drm_bridge > code can look at its DT graph and find the remote node connected. > Basically something like this: > > void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode, >struct fwnode_handle > *usb_connector_fwnode, >enum drm_connector_status status) > > (We might as well also pass the number of lanes here) I think this is a bit of an overkill. The drm_connector_oob_hotplug_event() is fine as it is, it gets "fwnode_handle to report the event on". What needs to be changed (in my humble opinion) is the drm_connector_find_by_fwnode() function (or likely a new function is to be added): if it can not find drm_connector for the passed fwnode, it should look it up on the parent, then on parent's parent, etc, until we actually find the drm_connector (good) or we reach the root (sad). And finally after getting the drm_connector, the oob_hotplug_event() callback should also receive the fwnode argument. This way the connector (or the bridge) can identify the fwnode (aka usb-c-connector in our case) that caused the event. WDYT? > Corsola could work with this design, but we'll need to teach > dp_altmode_probe() to look for the drm_bridge elsewhere besides as the > parent of the usb-c-connector node. That implies using the 'displayport' > property in the cros-ec-typec node or teaching dp_altmode_probe() to > look for the port@1/endpoint@1 remote-endpoint handle in the > usb-c-connector graph. > > Assuming the bindings you've presented here are fine and good and I got > over the differences between Trogdor and Corsola, then I can make mostly > everything work with the drm_connector_oob_hotplug_event() signature > change from above and some tweaks to dp_altmode_probe() to look for > port@1/endpoint@1 first because that's the "logical" DP input endpoint > in the usb-c-connector binding's graph. Great! The final roadblock I'm > at is that HPD doesn't work on Trogdor, so I can't signal HPD through > the typec framework. Hmm, I thought that a normal DP's HPD GPIO works on the trogdor. Was I misunderstanding it? But then we don't know, which USB-C connector triggered the HPD... > This series fixes that problem by "capturing" HPD state from the > upstream drm_bridge, e.g. msm_dp, by hooking the struct > drm_bridge_funcs::hpd_notify() path and injecting HPD into the typec > messages received from the EC. That's a workaround to make the typec > framework see HPD state changes that are otherwise invisible to the > kernel. Newer firmwares actually tell us the state of HPD properly, but > even then we have to read a gpio mux controlled by the EC to figure out > which usb-c-connector is actually muxing DP when HPD changes on either > typec_port. Having a drm_bridge in cros-ec-typec helped here because we > could hook this path and signal HPD if we knew the firmware was fixed. > If we don't have the drm_bridge anymore, I'm lost how to do this. It's probably okay to add one, but let me think if we can work without it. Can we make EC driver listen for that single HPD GPIO (by making it an actual GPIO rather than "dp_hot") and then react to it? > > Maybe the right answer here is to introduce a drm_connector_dp_typec > structure that is created by the TCPM (cros-ec-typec) that sets a new > DRM_BRIDGE_OP_DP_TYPEC bridge op flag? And then teach > drm_bridge_connector about this new flag, similar to the HDMI one. The > drm_bridge could implement some function that maps the typec_port > (usb-c-connector) to the upstream drm_bridge (ANX7625) graph port, > possibly all in drm_bridge_connector_oob_hotplug_event() so that nothing > else really changes. It could also let us keep hooking the hpd_notify() > path for the workaround needed on Trogdor. And finally it may let us > harmonize the two DT bindings so that we only have one port@1/endpoint > node in the usb-c-connector. I think we have lightly discussed adding drm_connector_displayport, so that part is okay. But my gut feeling is that there should be no _type