Re: [PATCH 5/7] drm/msm/dpu: Correct dual-ctl -> dual-intf typo in comment
On 2024-04-18 02:30:59, Dmitry Baryshkov wrote: > On Wed, Apr 17, 2024 at 01:57:45AM +0200, Marijn Suijten wrote: > > This comment one line down references a single, "same CTL" that controls > > two interfaces, so the comment should clearly describe two interfaces > > used with a single active CTL and not "two CTLs". > > > > Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") > > Signed-off-by: Marijn Suijten > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c > > index d9e7dbf0499c..7e849fe74801 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c > > @@ -428,7 +428,7 @@ static void dpu_encoder_phys_vid_enable(struct > > dpu_encoder_phys *phys_enc) > > dpu_encoder_phys_vid_setup_timing_engine(phys_enc); > > > > /* > > -* For single flush cases (dual-ctl or pp-split), skip setting the > > +* For single flush cases (dual-intf or pp-split), skip setting the > > It should be fixed, but in the other way: it's 'single-ctl'. See > sde_encoder_phys_needs_single_flush(). As written in the cover letter I was unsure about this comment. You are right that sde_encoder_phys_needs_single_flush() is supposed to return true in pp-split or single-ctl. However, the second part of the comment (right below) is in conflict with another patch that I've sent as part of these series: on a single-ctl setup with dual interfaces, the second INTF needs to be marked for flushing. While that observation and fix is for CMD-mode, the exact same comment is found downstream for video mode: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/display-kernel.lnx.5.4.r1-rel/msm/sde/sde_encoder_phys_vid.c?ref_type=heads#L794-804 You were fixing exactly that in one of your preliminary Active-CTL patches by making dpu_encoder_phys_vid_needs_single_flush() return for Active-CTL, so we should probably update this comment in the same patch when you send it? (that is: the flush bit needs to be set for the slave intf in Active-CTL. Before Active-CTL, a slave encoder would actually have two CTLs and two INTFs where the flush bit was probably skipped on both slaves?) On a side-note, since the needs_single_flush callback is used elsehwere, I'm unsure if that patch affects things in the wrong way since the downstream file linked above applies the check for CTL_ACTIVE_CFG directly in-line without affecting the callback. - Marijn > > * flush bit for the slave intf, since both intfs use same ctl > > * and HW will only flush the master. > > */ > > > > -- > > 2.44.0 > > > > -- > With best wishes > Dmitry
Re: [PATCH 2/7] drm/msm/dsi: Pass bonded-DSI hdisplay/2 to DSC timing configuration
On 2024-04-17 14:58:25, Dmitry Baryshkov wrote: > On Wed, 17 Apr 2024 at 02:57, Marijn Suijten > wrote: > > > > When configuring the timing of DSI hosts (interfaces) in > > dsi_timing_setup() all values written to registers are taking bonded > > DSI into account by dividing the original mode width by 2 (half the > > data is sent over each of the two DSI hosts), but the full width > > instead of the interface width is passed as hdisplay parameter to > > dsi_update_dsc_timing(). > > > > Currently only msm_dsc_get_slices_per_intf() is called within > > dsi_update_dsc_timing() with the `hdisplay` argument which clearly > > documents that it wants the width of a single interface (which, again, > > in bonded DSI mode is half the total width of the mode). Thus pass the > > bonded-mode-adjusted hdisplay parameter into dsi_update_dsc_timing() > > otherwise all values written to registers by this function (i.e. the > > number of slices per interface or packet, and derived from this the EOL > > byte number) are twice too large. > > > > Inversely the panel driver is expected to only set the slice width and > > number of slices for half the panel, i.e. what will be sent by each > > host individually, rather than fixing that up like hdisplay here. > > > > Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") > > Signed-off-by: Marijn Suijten > > --- > > drivers/gpu/drm/msm/dsi/dsi_host.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > Reviewed-by: Dmitry Baryshkov Thanks, it seems this patch has already been picked up for 6.10 [1] to test at least, but I'd advise you to drop it until I resend it in v2, as it no longer performs as written in the title. When I wrote this patch in in June 2023, commit efcbd6f9cdeb ("drm/msm/ dsi: Enable widebus for DSI") from August 2023 wasn't there yet. That patch updates hdisplay (because it is unused after that point) with the number of compressed bytes to be sent over each interface, which is effectively hdisplay (based on slice_count * slice_width, so as explained in the commit message that corresponds to half the panel width), divided by a compression ratio of 3 or 6 depending on widebus, thus passing a way too low value into dsi_update_dsc_timing(). As a result this patch regresses the DSC panel on my SM8150 Sony Xperia 1, and likely also explains why it was quite hard to get the porches "just right" on the Xperia 1 III with its dual-DSI dual-DSC 4k@120Hz panel (that these patches are specifically for). I'm still thinking of how to best fix that: probably introducing a new separate local variable, though dsi_update_dsc_timing() only uses it to calculate the number of slices per interface, which again as written in the commit description, is currently required to already be for one interface (in other words, the Xperia 1 with only a single intf sets slice_count=2, but the Xperia 1 III with 2 bonded DSI interfaces sets slice_count=1). Which means that this is always equivalent to slice_per_intf = dsc->slice_count. Let me know which approach is preferred. - Marijn [1]: https://gitlab.freedesktop.org/drm/msm/-/merge_requests/110
Re: [PATCH v4 2/2] drm/panel: Add driver for EDO RM69380 OLED panel
On 2024-04-17 18:29:34, David Wronek wrote: > Add support for the 2560x1600@90Hz OLED panel by EDO bundled with a > Raydium RM69380 controller, as found on the Lenovo Xiaoxin Pad Pro 2021. > > Reviewed-by: Dmitry Baryshkov > Signed-off-by: David Wronek Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/panel/Kconfig | 12 + > drivers/gpu/drm/panel/Makefile| 1 + > drivers/gpu/drm/panel/panel-raydium-rm69380.c | 344 > ++ > 3 files changed, 357 insertions(+) > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 154f5bf82980..e2a66c21349f 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -542,6 +542,18 @@ config DRM_PANEL_RAYDIUM_RM692E5 > Say Y here if you want to enable support for Raydium RM692E5-based > display panels, such as the one found in the Fairphone 5 smartphone. > > +config DRM_PANEL_RAYDIUM_RM69380 > + tristate "Raydium RM69380-based DSI panel" > + depends on OF && GPIOLIB > + depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > + help > + Say Y here if you want to enable support for Raydium RM69380-based > + display panels. > + > + This panel controller can be found in the Lenovo Xiaoxin Pad Pro 2021 > + in combination with an EDO OLED panel. > + > config DRM_PANEL_RONBO_RB070D30 > tristate "Ronbo Electronics RB070D30 panel" > depends on OF > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 24a02655d726..e2a2807d4ef0 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -55,6 +55,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += > panel-raspberrypi-touchscreen > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o > +obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o > obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o > diff --git a/drivers/gpu/drm/panel/panel-raydium-rm69380.c > b/drivers/gpu/drm/panel/panel-raydium-rm69380.c > new file mode 100644 > index ..4dca6802faef > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-raydium-rm69380.c > @@ -0,0 +1,344 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device > tree. > + * Copyright (c) 2024 David Wronek > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > + > +struct rm69380_panel { > + struct drm_panel panel; > + struct mipi_dsi_device *dsi[2]; > + struct regulator_bulk_data supplies[2]; > + struct gpio_desc *reset_gpio; > +}; > + > +static inline > +struct rm69380_panel *to_rm69380_panel(struct drm_panel *panel) > +{ > + return container_of(panel, struct rm69380_panel, panel); > +} > + > +static void rm69380_reset(struct rm69380_panel *ctx) > +{ > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + usleep_range(15000, 16000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 1); > + usleep_range(1, 11000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + msleep(30); > +} > + > +static int rm69380_on(struct rm69380_panel *ctx) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi[0]; > + struct device *dev = >dev; > + int ret; > + > + dsi->mode_flags |= MIPI_DSI_MODE_LPM; > + if (ctx->dsi[1]) > + ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; > + > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd4); > + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80); > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd0); > + mipi_dsi_dcs_write_seq(dsi, 0x48, 0x00); > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x26); > + mipi_dsi_dcs_write_seq(dsi, 0x75, 0x3f); > + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1a); > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00); > + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); > + mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x08); > + > + ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); > + if (ret < 0) { > + dev_err(dev, "Failed
Re: [PATCH 6/7] drm/msm/dsi: Set PHY usescase before registering DSI host
On 2024-04-17 11:18:58, Dmitry Baryshkov wrote: > On Wed, 17 Apr 2024 at 02:57, Marijn Suijten > wrote: > > > > Ordering issues here cause an uninitalized (default STANDALONE) > > usecase to be programmed (which appears to be a MUX) in some cases > > when msm_dsi_host_register() is called, leading to the slave PLL in > > bonded-DSI mode to source from a clock parent (dsi1vco) that is off. > > > > This should seemingly not be a problem as the actual dispcc clocks from > > DSI1 that are muxed in the clock tree of DSI0 are way further down, this > > bit still seems to have an effect on them somehow and causes the right > > side of the panel controlled by DSI1 to not function. > > > > In an ideal world this code is refactored to no longer have such > > error-prone calls "across subsystems", and instead model the "PLL src" > > register field as a regular mux so that changing the clock parents > > programmatically or in DTS via `assigned-clock-parents` has the > > desired effect. > > But for the avid reader, the clocks that we *are* muxing into DSI0's > > tree are way further down, so if this bit turns out to be a simple mux > > between dsiXvco and out_div, that shouldn't have any effect as this > > whole tree is off anyway. > > > > Signed-off-by: Marijn Suijten > > --- > > drivers/gpu/drm/msm/dsi/dsi_manager.c | 15 +++ > > 1 file changed, 11 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c > > b/drivers/gpu/drm/msm/dsi/dsi_manager.c > > index af2a287cb3bd..17f43b3c0494 100644 > > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c > > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c > > @@ -85,6 +85,17 @@ static int dsi_mgr_setup_components(int id) > > msm_dsi : other_dsi; > > struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ? > > other_dsi : msm_dsi; > > + > > + /* PLL0 is to drive both 2 DSI link clocks in bonded DSI > > mode. > > +* > > +* Set the usecase before calling msm_dsi_host_register() > > to prevent it from > > +* enabling and configuring the usecase (which is just a > > mux bit) first. > > +*/ > > + msm_dsi_phy_set_usecase(clk_master_dsi->phy, > > + MSM_DSI_PHY_MASTER); > > + msm_dsi_phy_set_usecase(clk_slave_dsi->phy, > > + MSM_DSI_PHY_SLAVE); > > + > > /* Register slave host first, so that slave DSI device > > * has a chance to probe, and do not block the master > > * DSI device's probe. > > @@ -100,10 +111,6 @@ static int dsi_mgr_setup_components(int id) > > return ret; > > > > /* PLL0 is to drive both 2 DSI link clocks in bonded DSI > > mode. */ > > - msm_dsi_phy_set_usecase(clk_master_dsi->phy, > > - MSM_DSI_PHY_MASTER); > > - msm_dsi_phy_set_usecase(clk_slave_dsi->phy, > > - MSM_DSI_PHY_SLAVE); > > msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy); > > msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy); > > Please move msm_dsi_host_set_phy_mode() calls too. Ack. Yeah, given that msm_dsi_host_register() causes a modeset and finally the PLL turning on, these should be set up as well. For anyone else following along, I have pasted the stacktrace that showcases the execution flow in the drm/msm tracker: https://gitlab.freedesktop.org/drm/msm/-/issues/41#note_2376115 Abhinav also pointed out that this PLL source was correctly set in earlier devcoredump reports, so it might have been a recent development/regression? This seems to be the only issue originating from it, but folks were adamant that dsi_mgr_setup_components() (ultimately) would never turn the PLL on, which is "debunked" by said stacktrace. Maybe other assumptions are affected by this change? > Also please update the non-bonded case. Definitely, as suggested in the cover letter. A similar stacktrace to the above is acquired on a non-bonded setup, which is also relying on the variable to be initialized to 0 to select the "local PLL source", rather than being correctly set via this msm_dsi_phy_set_usecase() configuration. - Marijn > > } > > > > -- > > 2.44.0 > > > > > -- > With best wishes > Dmitry
[PATCH 2/7] drm/msm/dsi: Pass bonded-DSI hdisplay/2 to DSC timing configuration
When configuring the timing of DSI hosts (interfaces) in dsi_timing_setup() all values written to registers are taking bonded DSI into account by dividing the original mode width by 2 (half the data is sent over each of the two DSI hosts), but the full width instead of the interface width is passed as hdisplay parameter to dsi_update_dsc_timing(). Currently only msm_dsc_get_slices_per_intf() is called within dsi_update_dsc_timing() with the `hdisplay` argument which clearly documents that it wants the width of a single interface (which, again, in bonded DSI mode is half the total width of the mode). Thus pass the bonded-mode-adjusted hdisplay parameter into dsi_update_dsc_timing() otherwise all values written to registers by this function (i.e. the number of slices per interface or packet, and derived from this the EOL byte number) are twice too large. Inversely the panel driver is expected to only set the slice width and number of slices for half the panel, i.e. what will be sent by each host individually, rather than fixing that up like hdisplay here. Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/dsi_host.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index c80be74cf10b..9d0c940dcb28 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -987,7 +987,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { if (msm_host->dsc) - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); + dsi_update_dsc_timing(msm_host, false, hdisplay); dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | @@ -1008,7 +1008,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else {/* command mode */ if (msm_host->dsc) - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); + dsi_update_dsc_timing(msm_host, true, hdisplay); /* image data and 1 byte write_memory_start cmd */ if (!msm_host->dsc) -- 2.44.0
[PATCH 1/7] drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk
When dual-DSI (bonded DSI) was added in commit ed9976a09b48 ("drm/msm/dsi: adjust dsi timing for dual dsi mode") some DBG() prints were not updated, leading to print the original mode->clock rather than the adjusted (typically the mode clock divided by two, though more recently also adjusted for DSC compression) msm_host->pixel_clk_rate which is passed to clk_set_rate() just below. Fix that by printing the actual pixel_clk_rate that is being set. Fixes: ed9976a09b48 ("drm/msm/dsi: adjust dsi timing for dual dsi mode") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9d86a6aca6f2..c80be74cf10b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -356,8 +356,8 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) { int ret; - DBG("Set clk rates: pclk=%d, byteclk=%lu", - msm_host->mode->clock, msm_host->byte_clk_rate); + DBG("Set clk rates: pclk=%lu, byteclk=%lu", + msm_host->pixel_clk_rate, msm_host->byte_clk_rate); ret = dev_pm_opp_set_rate(_host->pdev->dev, msm_host->byte_clk_rate); @@ -430,9 +430,9 @@ int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host) { int ret; - DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", - msm_host->mode->clock, msm_host->byte_clk_rate, - msm_host->esc_clk_rate, msm_host->src_clk_rate); + DBG("Set clk rates: pclk=%lu, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", + msm_host->pixel_clk_rate, msm_host->byte_clk_rate, + msm_host->esc_clk_rate, msm_host->src_clk_rate); ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); if (ret) { -- 2.44.0
[PATCH 6/7] drm/msm/dsi: Set PHY usescase before registering DSI host
Ordering issues here cause an uninitalized (default STANDALONE) usecase to be programmed (which appears to be a MUX) in some cases when msm_dsi_host_register() is called, leading to the slave PLL in bonded-DSI mode to source from a clock parent (dsi1vco) that is off. This should seemingly not be a problem as the actual dispcc clocks from DSI1 that are muxed in the clock tree of DSI0 are way further down, this bit still seems to have an effect on them somehow and causes the right side of the panel controlled by DSI1 to not function. In an ideal world this code is refactored to no longer have such error-prone calls "across subsystems", and instead model the "PLL src" register field as a regular mux so that changing the clock parents programmatically or in DTS via `assigned-clock-parents` has the desired effect. But for the avid reader, the clocks that we *are* muxing into DSI0's tree are way further down, so if this bit turns out to be a simple mux between dsiXvco and out_div, that shouldn't have any effect as this whole tree is off anyway. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index af2a287cb3bd..17f43b3c0494 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -85,6 +85,17 @@ static int dsi_mgr_setup_components(int id) msm_dsi : other_dsi; struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ? other_dsi : msm_dsi; + + /* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. +* +* Set the usecase before calling msm_dsi_host_register() to prevent it from +* enabling and configuring the usecase (which is just a mux bit) first. +*/ + msm_dsi_phy_set_usecase(clk_master_dsi->phy, + MSM_DSI_PHY_MASTER); + msm_dsi_phy_set_usecase(clk_slave_dsi->phy, + MSM_DSI_PHY_SLAVE); + /* Register slave host first, so that slave DSI device * has a chance to probe, and do not block the master * DSI device's probe. @@ -100,10 +111,6 @@ static int dsi_mgr_setup_components(int id) return ret; /* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */ - msm_dsi_phy_set_usecase(clk_master_dsi->phy, - MSM_DSI_PHY_MASTER); - msm_dsi_phy_set_usecase(clk_slave_dsi->phy, - MSM_DSI_PHY_SLAVE); msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy); msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy); } -- 2.44.0
[PATCH 5/7] drm/msm/dpu: Correct dual-ctl -> dual-intf typo in comment
This comment one line down references a single, "same CTL" that controls two interfaces, so the comment should clearly describe two interfaces used with a single active CTL and not "two CTLs". Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index d9e7dbf0499c..7e849fe74801 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -428,7 +428,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) dpu_encoder_phys_vid_setup_timing_engine(phys_enc); /* -* For single flush cases (dual-ctl or pp-split), skip setting the +* For single flush cases (dual-intf or pp-split), skip setting the * flush bit for the slave intf, since both intfs use same ctl * and HW will only flush the master. */ -- 2.44.0
[PATCH 7/7] drm/msm/dpu: Rename `ctx` parameter to `intf` to match other functions
All other functions in dpu_hw_intf name the "self" parameter `intf`, except dpu_hw_intf_setup_timing_engine() and the recently added dpu_hw_intf_program_intf_cmd_cfg(). Clean that up for consistency. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 965692ef7892..34d0c4e04d27 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -96,11 +96,11 @@ #define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) -static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, +static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *intf, const struct dpu_hw_intf_timing_params *p, const struct dpu_format *fmt) { - struct dpu_hw_blk_reg_map *c = >hw; + struct dpu_hw_blk_reg_map *c = >hw; u32 hsync_period, vsync_period; u32 display_v_start, display_v_end; u32 hsync_start_x, hsync_end_x; @@ -118,7 +118,7 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, /* read interface_cfg */ intf_cfg = DPU_REG_READ(c, INTF_CONFIG); - if (ctx->cap->type == INTF_DP) + if (intf->cap->type == INTF_DP) dp_intf = true; hsync_period = p->hsync_pulse_width + p->h_back_porch + p->width + @@ -223,7 +223,7 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, DPU_REG_WRITE(c, INTF_FRAME_LINE_COUNT_EN, 0x3); DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg); DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format); - if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) { + if (intf->cap->features & BIT(DPU_DATA_HCTL_EN)) { /* * DATA_HCTL_EN controls data timing which can be different from * video timing. It is recommended to enable it for all cases, except @@ -518,10 +518,10 @@ static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, } -static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx, +static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *intf, struct dpu_hw_intf_cmd_mode_cfg *cmd_mode_cfg) { - u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); + u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); if (cmd_mode_cfg->data_compress) intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; @@ -529,7 +529,7 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx, if (cmd_mode_cfg->wide_bus_en) intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; - DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); } struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, -- 2.44.0
[PATCH 4/7] drm/msm/dpu: Allow configuring multiple active DSC blocks
Just like the active interface and writeback block in ctl_intf_cfg_v1(), and later the rest of the blocks in followup active-CTL fixes or reworks, multiple calls to this function should enable additional DSC blocks instead of overwriting the blocks that are enabled. This pattern is observed in an active-CTL scenario since DPU 5.0.0 where for example bonded-DSI uses a single CTL to drive multiple INTFs, and each encoder calls this function individually with the INTF (hence the pre-existing update instead of overwrite of this bitmask) and DSC blocks it wishes to be enabled, and expects them to be OR'd into the bitmask. The reverse already exists in reset_intf_cfg_v1() where only specified DSC blocks are removed out of the CTL_DSC_ACTIVE bitmask (same for all other blocks and ACTIVE bitmasks), leaving the rest enabled. Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index a06f69d0b257..2e50049f2f85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -545,6 +545,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, { struct dpu_hw_blk_reg_map *c = >hw; u32 intf_active = 0; + u32 dsc_active = 0; u32 wb_active = 0; u32 mode_sel = 0; @@ -560,6 +561,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); if (cfg->intf) intf_active |= BIT(cfg->intf - INTF_0); @@ -567,17 +569,18 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->wb) wb_active |= BIT(cfg->wb - WB_0); + if (cfg->dsc) + dsc_active |= cfg->dsc; + DPU_REG_WRITE(c, CTL_TOP, mode_sel); DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); - if (cfg->dsc) - DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); - if (cfg->cdm) DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm); } -- 2.44.0
[PATCH 3/7] drm/msm/dpu: Always flush the slave INTF on the CTL
As we can clearly see in a downstream kernel [1], flushing the slave INTF is skipped /only if/ the PPSPLIT topology is active. However, when DPU was originally submitted to mainline PPSPLIT was no longer part of it (seems to have been ripped out before submission), but this clause was incorrectly ported from the original SDE driver. Given that there is no support for PPSPLIT (currently), flushing the slave INTF should /never/ be skipped (as the `if (ppsplit && !master) goto skip;` clause downstream never becomes true). [1]: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/display-kernel.lnx.5.4.r1-rel/msm/sde/sde_encoder_phys_cmd.c?ref_type=heads#L1131-1139 Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index fc1d5736d7fc..489be1c0c704 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -448,9 +448,6 @@ static void dpu_encoder_phys_cmd_enable_helper( _dpu_encoder_phys_cmd_pingpong_config(phys_enc); - if (!dpu_encoder_phys_cmd_is_master(phys_enc)) - return; - ctl = phys_enc->hw_ctl; ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); } -- 2.44.0
[PATCH 0/7] drm/msm: Initial fixes for DUALPIPE (+DSC) topology
This series covers a step-up towards supporting the DUALPIPE DSC topology, also known as 2:2:2 topology (on active-CTL hardware). It involves 2 layer mixers, 2 DSC compression encoders, and 2 interfaces (on DSI, this is called bonded-DSI) where bandwidth constraints (e.g. 4k panels at 120Hz) require two interfaces to transmit pixel data. Enabling this topology will be hard(er) than downstream as hacking a layout type in DTS won't be describing the hardware, but "dynamically" determining it at runtime may pose some of a challenge that is left to a future series. Such changes will also involve the 1:1:1 topology needed for constrained hardware like the Fairphone 5 on SC7280 with access to only one DSC encoder and thus ruled out of the current 2:2:1 topology. Likewise, the patches and discussions around improving active-CTL configuration to support bonded interfaces (that share a single CTL block) are still in full swing and hence elided from this series, apart from one patch to fix the ACTIVE_DSC register coding to support updates, so that it is not forgotten about. Note that some patches are applicable to DSC-less DUALPIPE bonded mode as well, such as the patch that allows the slave interface to always be flushed as that is only supposed to be excluded in the yet-unsupported PPSPLIT topology. This series also contains some patches that I'm not too sure about: drm/msm/dpu: Correct dual-ctl -> dual-intf typo in comment Downstream doesn't skip the slave INTF flush on active-CTL [1] (again, just like cmdmode, only when PPSPLIT is enabled [2]), and even added an extra comment [1] explaining this case. Hence a dual-intf but single-flush case doesn't seem to exist as there's only one CTL according to the remainder of the comment. Maybe the whole comment is wrong? drm/msm/dsi: Set PHY usescase before registering DSI host It seems intentional to only set the usecase after msm_dsi_host_register() in case it fails, so maybe a non-zero `ret` here should reset the usecase? Likewise should the function call be moved in !IS_BONDED_DSI() above? Ideally we also understand what I am doing differently (maybe wrongly) in my panel driver that makes the PLL turn on and configure before the usecase has been set, even though these calls are messy and error-prone nevertheless. [1]: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/display-kernel.lnx.5.4.r1-rel/msm/sde/sde_encoder_phys_vid.c?ref_type=heads#L794-804 [2]: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/display-kernel.lnx.5.4.r1-rel/msm/sde/sde_encoder_phys_cmd.c?ref_type=heads#L1131-1139 Signed-off-by: Marijn Suijten --- Marijn Suijten (7): drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk drm/msm/dsi: Pass bonded-DSI hdisplay/2 to DSC timing configuration drm/msm/dpu: Always flush the slave INTF on the CTL drm/msm/dpu: Allow configuring multiple active DSC blocks drm/msm/dpu: Correct dual-ctl -> dual-intf typo in comment drm/msm/dsi: Set PHY usescase before registering DSI host drm/msm/dpu: Rename `ctx` parameter to `intf` to match other functions drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 9 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 14 +++--- drivers/gpu/drm/msm/dsi/dsi_host.c | 14 +++--- drivers/gpu/drm/msm/dsi/dsi_manager.c| 15 +++ 6 files changed, 32 insertions(+), 25 deletions(-) --- base-commit: 6bd343537461b57f3efe5dfc5fc193a232dfef1e change-id: 20240416-drm-msm-initial-dualpipe-dsc-fixes-3f0715b03bf4 Best regards, -- Marijn Suijten
Re: [PATCH] drm: Fix no_vblank field references in documentation
Hi Randy, [..] > Do you see differences in the generated html for these changes? I have not yet generated the HTML locally to test this patch, but will surely do if that's a requirement. > " somestruct" and "" should both be OK AFAIK, although > Documentation/doc-guide/kernel-doc.rst seems to say that using > " somestruct" is preferred. Keep in mind that this patch is about field/member references. Quoting the relevant paragraph under "Highlights and cross-references": ``_name->member`` or ``_name.member`` Structure or union member reference. The cross-reference will be to the struct or union definition, not the member directly. This lacks the struct tag entirely, and observation shows that links with them don't highlight correctly (hence this patch) while member links without struct tag are clickable and have an anchor link to their parent struct. - Marijn
Re: [PATCH v3 2/2] drm/panel: Add driver for EDO RM69380 OLED panel
On 2024-04-16 20:30:49, David Wronek wrote: > Add support for the 2560x1600@90Hz OLED panel by EDO bundled with a > Raydium RM69380 controller, as found on the Lenovo Xiaoxin Pad Pro 2021. > > Signed-off-by: David Wronek > --- > drivers/gpu/drm/panel/Kconfig | 14 + > drivers/gpu/drm/panel/Makefile| 1 + > drivers/gpu/drm/panel/panel-raydium-rm69380.c | 367 > ++ > 3 files changed, 382 insertions(+) > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 154f5bf82980..5b3eeb93b1a2 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -542,6 +542,20 @@ config DRM_PANEL_RAYDIUM_RM692E5 > Say Y here if you want to enable support for Raydium RM692E5-based > display panels, such as the one found in the Fairphone 5 smartphone. > > +config DRM_PANEL_RAYDIUM_RM69380 > + tristate "Raydium RM69380-based DSI panel" > + depends on BACKLIGHT_CLASS_DEVICE > + depends on DRM_DISPLAY_DP_HELPER "DRM DisplayPort helpers" But you said that this is a DSI device? Looking in -next from yesterday, Raydium-RM692E5 and Visionox-R66451 get this wrong as well. > + depends on DRM_DISPLAY_HELPER This also looks unused? The only helpers in the non-DP non-HDMI helper points to more DP AUX code. > + depends on DRM_MIPI_DSI > + depends on OF As I've shown in the SOFEF00 cleanup patch, devm_gpiod_get() is used which is behind GPIOLIB. This should probably be a dependency. > + help > + Say Y here if you want to enable support for Raydium RM69380-based > + display panels. > + > + This panel controller can be found in the Lenovo Xiaoxin Pad Pro 2021 > + in combination with an EDO OLED panel. > + > config DRM_PANEL_RONBO_RB070D30 > tristate "Ronbo Electronics RB070D30 panel" > depends on OF > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 24a02655d726..e2a2807d4ef0 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -55,6 +55,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += > panel-raspberrypi-touchscreen > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o > obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o > +obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o > obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o > diff --git a/drivers/gpu/drm/panel/panel-raydium-rm69380.c > b/drivers/gpu/drm/panel/panel-raydium-rm69380.c > new file mode 100644 > index ..f89230c969b7 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-raydium-rm69380.c > @@ -0,0 +1,367 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device > tree. > + * Copyright (c) 2024 David Wronek > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > + > +struct rm69380_panel { > + struct drm_panel panel; > + struct mipi_dsi_device *dsi[2]; > + struct regulator_bulk_data supplies[2]; > + struct gpio_desc *reset_gpio; > +}; > + > +static inline > +struct rm69380_panel *to_rm69380_panel(struct drm_panel *panel) > +{ > + return container_of(panel, struct rm69380_panel, panel); > +} > + > +static void rm69380_reset(struct rm69380_panel *ctx) > +{ > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + usleep_range(15000, 16000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 1); > + usleep_range(1, 11000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + msleep(30); > +} > + > +static int rm69380_on(struct rm69380_panel *ctx) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi[0]; > + struct device *dev = >dev; > + int ret; > + > + dsi->mode_flags |= MIPI_DSI_MODE_LPM; > + if (ctx->dsi[1]) > + ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; > + > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd4); > + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80); Is this MIPI_DCS_NOP? Strange to see that with a parameter. > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd0); > + mipi_dsi_dcs_write_seq(dsi, 0x48, 0x00); > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x26); > + mipi_dsi_dcs_write_seq(dsi, 0x75, 0x3f); > + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1a); > + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00); > + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); Separate from this patch, I feel like we should document these bits. Their meaning might be defined by a paywall, intersecting a few downstream DTS with DCS
Re: [PATCH v2 2/2] drm/panel: Add driver for EDO RM69380 OLED panel
On 2024-04-15 19:50:49, Dmitry Baryshkov wrote: > On Mon, Apr 15, 20 [...] > > +static int rm69380_on(struct rm69380_panel *ctx) [...] > ret = mipi_dsi_dcs_set_display_brightness_large(dsi, 0x7ff); Downstream may send this here, but why? As far as I've observed, update_status also sets _properties.brightness which you configure below. Try removing this line and maybe also set the initial brightness lower to the benefit of users' eyes and OLED lifetime? [...] > > + > > + if (dsi_sec) { > > + dev_dbg(dev, "Using Dual-DSI\n"); > > + > > + const struct mipi_dsi_device_info info = { "RM69380", 0, Personally I'm never really sure what to put in the name here, maybe something that signifies the second DSI interface of the panel? > > + dsi_sec }; > > + > > + dev_dbg(dev, "Found second DSI `%s`\n", dsi_sec->name); > > + > > + dsi_sec_host = of_find_mipi_dsi_host_by_node(dsi_sec); > > + of_node_put(dsi_sec); > > + if (!dsi_sec_host) { > > + return dev_err_probe(dev, -EPROBE_DEFER, > > +"Cannot get secondary DSI host\n"); > > + } > > + > > + ctx->dsi[1] = > > + mipi_dsi_device_register_full(dsi_sec_host, ); > > Either you should be using devm_mipi_dsi_device_register_full() here or > you should call mipi_dsi_device_unregister() in the error and remove > paths. I'd suggest the former. There is also devm_mipi_dsi_attach() which may solve inadequate cleanup handling in the error paths below, as pointed out by Christophe. > > > + if (IS_ERR(ctx->dsi[1])) { > > + return dev_err_probe(dev, PTR_ERR(ctx->dsi[1]), > > +"Cannot get secondary DSI node\n"); > > + } > > + > > + dev_dbg(dev, "Second DSI name `%s`\n", ctx->dsi[1]->name); It looks like you inerited /all/ my debug logging when copy-pasting this setup from my in-progress dual-DSI dual-DSC Samsung ANA6707 panel driver. Since it's all working now, I suggest to remove mostly-useless debug lines like this. I'll continue the review on v3, as I mainly wanted to extend the initial devm_ suggestion from Dmitry done on v2. - Marijn
[PATCH] drm: Fix no_vblank field references in documentation
Browsing the DRM documentation shows that drm_crtc_state.no_vblank is not turned into a reference to the no_vblank field, but rather a reference to `struct drm_crtc_state`. The only difference with other field references is that the struct name is prefixed by the literal `struct` tag, despite also already having a `&` reference prefix in two of the three cases. Remove the `struct` prefix to turn these references into proper links to the designated field. Fixes: 7beb691f1e6f ("drm: Initialize struct drm_crtc_state.no_vblank from device settings") Signed-off-by: Marijn Suijten --- Note that a simple regex like " \w+\.\w+" shows that there are only a handful of violators, most of them inside DRM files. Let me know if you'd like a v2 that addresses all of them in one go (in separate patches or one combined change)? Kind regards, Marijn --- drivers/gpu/drm/drm_vblank.c| 2 +- include/drm/drm_crtc.h | 2 +- include/drm/drm_simple_kms_helper.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 702a12bc93bd..45504732f98e 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -140,7 +140,7 @@ * must not call drm_vblank_init(). For such drivers, atomic helpers will * automatically generate fake vblank events as part of the display update. * This functionality also can be controlled by the driver by enabling and - * disabling struct drm_crtc_state.no_vblank. + * disabling _crtc_state.no_vblank. */ /* Retry timestamp calculation up to 3 times to satisfy diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 8b48a1974da3..eb75d0aec170 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -342,7 +342,7 @@ struct drm_crtc_state { *that case. * * For very simple hardware without VBLANK interrupt, enabling -* drm_crtc_state.no_vblank makes DRM's atomic commit helpers +* _crtc_state.no_vblank makes DRM's atomic commit helpers * send a fake VBLANK event at the end of the display update after all * hardware changes have been applied. See * drm_atomic_helper_fake_vblank(). diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index b2486d073763..6e64d91819e7 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -102,7 +102,7 @@ struct drm_simple_display_pipe_funcs { * drm_crtc_arm_vblank_event(), when the driver supports vblank * interrupt handling, or drm_crtc_send_vblank_event() for more * complex case. In case the hardware lacks vblank support entirely, -* drivers can set drm_crtc_state.no_vblank in +* drivers can set _crtc_state.no_vblank in * drm_simple_display_pipe_funcs.check and let DRM's * atomic helper fake a vblank event. */ --- base-commit: 6bd343537461b57f3efe5dfc5fc193a232dfef1e change-id: 20240416-drm-no_vblank-kdoc-link-fea1b53008a3 Best regards, -- Marijn Suijten
Re: [PATCH v5 3/4] drm/mipi-dsi: add mipi_dsi_compression_mode_ext()
On 2024-04-08 02:53:52, Dmitry Baryshkov wrote: > Add the extended version of mipi_dsi_compression_mode(). It provides > a way to specify the algorithm and PPS selector. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Something doesn't stick with me on the _ext() naming, but I don't have something better to propose. - Marijn > --- > drivers/gpu/drm/drm_mipi_dsi.c | 41 ++--- > include/drm/drm_mipi_dsi.h | 9 + > 2 files changed, 43 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index 9874ff6d4718..795001bb7ff1 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -645,29 +645,56 @@ int mipi_dsi_set_maximum_return_packet_size(struct > mipi_dsi_device *dsi, > EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); > > /** > - * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral > * @dsi: DSI peripheral device > * @enable: Whether to enable or disable the DSC > + * @algo: Selected compression algorithm > + * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS > entries > * > - * Enable or disable Display Stream Compression on the peripheral using the > - * default Picture Parameter Set and VESA DSC 1.1 algorithm. > + * Enable or disable Display Stream Compression on the peripheral. > * > * Return: 0 on success or a negative error code on failure. > */ > -int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, > + enum mipi_dsi_compression_algo algo, > + unsigned int pps_selector) > { > - /* Note: Needs updating for non-default PPS or algorithm */ > - u8 tx[2] = { enable << 0, 0 }; > + u8 tx[2] = { }; > struct mipi_dsi_msg msg = { > .channel = dsi->channel, > .type = MIPI_DSI_COMPRESSION_MODE, > .tx_len = sizeof(tx), > .tx_buf = tx, > }; > - int ret = mipi_dsi_device_transfer(dsi, ); > + int ret; > + > + if (algo > 3 || pps_selector > 3) > + return -EINVAL; > + > + tx[0] = (enable << 0) | > + (algo << 1) | > + (pps_selector << 4); > + > + ret = mipi_dsi_device_transfer(dsi, ); > > return (ret < 0) ? ret : 0; > } > +EXPORT_SYMBOL(mipi_dsi_compression_mode_ext); > + > +/** > + * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * @dsi: DSI peripheral device > + * @enable: Whether to enable or disable the DSC > + * > + * Enable or disable Display Stream Compression on the peripheral using the > + * default Picture Parameter Set and VESA DSC 1.1 algorithm. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +{ > + return mipi_dsi_compression_mode_ext(dsi, enable, > MIPI_DSI_COMPRESSION_DSC, 0); > +} > EXPORT_SYMBOL(mipi_dsi_compression_mode); > > /** > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h > index 3011d33eccbd..82b1cc434ea3 100644 > --- a/include/drm/drm_mipi_dsi.h > +++ b/include/drm/drm_mipi_dsi.h > @@ -226,6 +226,12 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum > mipi_dsi_pixel_format fmt) > return -EINVAL; > } > > +enum mipi_dsi_compression_algo { > + MIPI_DSI_COMPRESSION_DSC = 0, > + MIPI_DSI_COMPRESSION_VENDOR = 3, > + /* other two values are reserved, DSI 1.3 */ > +}; > + > struct mipi_dsi_device * > mipi_dsi_device_register_full(struct mipi_dsi_host *host, > const struct mipi_dsi_device_info *info); > @@ -242,6 +248,9 @@ int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device > *dsi); > int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, > u16 value); > int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable); > +int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, > + enum mipi_dsi_compression_algo algo, > + unsigned int pps_selector); > int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > const struct drm_dsc_picture_parameter_set > *pps); > > > -- > 2.39.2 >
Re: [PATCH v3 3/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)
Can we drop (fix video mode DSC) from this patch title? It looks like more patches are required to get this done, such a mention is more something for the cover letter. We could also clarify further to "set Word Count for video-mode DSC". - Marijn On 2024-04-03 17:10:59, Jun Nie wrote: > From: Jonathan Marek > > Video mode DSC won't work if this field is not set correctly. Set it to fix > video mode DSC (for slice_per_pkt==1 cases at least). > > Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") > Signed-off-by: Jonathan Marek > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 2a0422cad6de..80ea4f1d8274 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -858,6 +858,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host > *msm_host, bool is_cmd_mod > u32 slice_per_intf, total_bytes_per_intf; > u32 pkt_per_line; > u32 eol_byte_num; > + u32 bytes_per_pkt; > > /* first calculate dsc parameters and then program >* compress mode registers > @@ -865,6 +866,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host > *msm_host, bool is_cmd_mod > slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); > > total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; > + bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */ > > eol_byte_num = total_bytes_per_intf % 3; > > @@ -902,6 +904,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host > *msm_host, bool is_cmd_mod > dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, > reg_ctrl); > dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, > reg_ctrl2); > } else { > + reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt); > dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg); > } > } > > -- > 2.34.1 >
Re: [PATCH v3 5/6] drm/display: Add slice_per_pkt for dsc
On 2024-04-08 17:58:29, Jun Nie wrote: > Dmitry Baryshkov 于2024年4月3日周三 17:41写道: > > > > On Wed, 3 Apr 2024 at 12:11, Jun Nie wrote: > > > > > > Add variable for slice number of a DSC compression bit stream packet. > > > Its value shall be specified in panel driver, or default value can be set > > > in display controller driver if panel driver does not set it. > > > > This is not a part of the standard. Please justify it. > > Right, I read the standard but did not find any details of packet description. > Looks like msm silicon support tuning of number of slice packing per > downstream > code. > The slice_per_pkt can be set in the downstream msm device tree. And I test the > values 1 and 2 on vtdr6130 panel and both work. So I guess this is related to > performance or something like that. I will have more test with different panel > to check the impact. > drivers/gpu/drm/panel/panel-raydium-rm692e5.c also mentions to pass new value > to slice_per_pkt. > > Hi Konrad, > Do you remember why value 2 is TODO for slice_per_pkt for panel rm692e5? Hi Jun, I think I should indirectly answer that question, as I indirectly via "the" MDSS panel generator place that comment there based on the suggested downstream value: https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator/commit/5c82e613d987d05feca423412f6de625f9c99bae#diff-dba3766d7cec900b8de500f888c64a392cd9780f9baf00aae7e3f87a7d3fefc4R458 So I don't think Konrad's answer will be any different than "that's what downstream does, and that's what the generator put there". --- I was fairly certain that it used for performance reasons, but panels were found (e.g. on the FairPhone 5) that don't seem to function without combining multiple (2) slices in one packet at all? - Marijn > > > Signed-off-by: Jun Nie > > > --- > > > include/drm/display/drm_dsc.h | 4 > > > 1 file changed, 4 insertions(+) > > > > > > diff --git a/include/drm/display/drm_dsc.h b/include/drm/display/drm_dsc.h > > > index bc90273d06a6..4fac0a2746ae 100644 > > > --- a/include/drm/display/drm_dsc.h > > > +++ b/include/drm/display/drm_dsc.h > > > @@ -82,6 +82,10 @@ struct drm_dsc_config { > > > * @bits_per_component: Bits per component to code (8/10/12) > > > */ > > > u8 bits_per_component; > > > + /** > > > +* @slice_per_pkt: slice number per DSC bit stream packet > > > +*/ > > > + u8 slice_per_pkt; > > > /** > > > * @convert_rgb: > > > * Flag to indicate if RGB - YCoCg conversion is needed > > > > > > -- > > > 2.34.1 > > > > > > > > > -- > > With best wishes > > Dmitry
Re: [PATCH v3 4/4] drm: panel: Add LG sw43408 panel driver
On 2024-04-03 05:37:29, Dmitry Baryshkov wrote: > On Tue, Apr 02, 2024 at 11:17:52PM +0200, Marijn Suijten wrote: > > On 2024-04-02 02:51:15, Dmitry Baryshkov wrote: > > > From: Sumit Semwal > > > > > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3 > > > phones. > > > > @60Hz? > > With the current settings and timings I'm only getting 30 Hz. I have to > double the mode->clock to get 60. Still seems useful to mention (here and in Kconfig). The proposed driver emits a mode to userspace of 60Hz, maybe the commit message should say that in the current state "something" prevents it from going that fast? Since I keep forgetting (because it's not mentioned anywhere) that this is a cmdmode panel (or at least configured for that with the current driver), I'd again suggest to play with sync_cfg_height. If setting it to 0xfff0 results in timeouts, your tear GPIO is misconfigured and not making the MDP aware of the actual tick rate. Otherwise, more likely, just bump up the porches a bit, based on the discussions around reduce_pclk_for_compression() /not/ accounting for transfer time in cmdmode. In one of my drivers (pending eternal cleanup hell) I inlined the calculation to reverse what the "right" porch should be based on a downstream clock rate: https://github.com/somainline/linux/commit/85978a69cde088a23963c03758dad5f1a2e79bab#diff-a9ac8689e45c59a4fe9aa150e4bd53675687f5c8b4aecb40b5b5b66b864257e0R353-R366 And separately, though I cannot find it, there have been (more accurate?) calculations based on downstream `qcom,mdss-dsi-panel-jitter` and friends. - Marijn
Re: [PATCH v3 4/4] drm: panel: Add LG sw43408 panel driver
On 2024-04-02 02:51:15, Dmitry Baryshkov wrote: > From: Sumit Semwal > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3 > phones. @60Hz? > > Signed-off-by: Sumit Semwal > [vinod: Add DSC support] > Signed-off-by: Vinod Koul > [caleb: cleanup and support turning off the panel] > Signed-off-by: Caleb Connolly > [DB: partially rewrote the driver and fixed DSC programming] > Signed-off-by: Dmitry Baryshkov Some small nits but I think this deserves a: Reviewed-by: Marijn Suijten > --- > MAINTAINERS | 8 + > drivers/gpu/drm/panel/Kconfig| 11 ++ > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-lg-sw43408.c | 326 > +++ > 4 files changed, 346 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index d36c19c1bf81..4cc43c16e07e 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6789,6 +6789,14 @@ S: Maintained > F: Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml > F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c > > +DRM DRIVER FOR LG SW43408 PANELS > +M: Sumit Semwal > +M: Caleb Connolly > +S: Maintained > +T: git git://anongit.freedesktop.org/drm/drm-misc > +F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml > +F: drivers/gpu/drm/panel/panel-lg-sw43408.c > + > DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER > M: Paul Kocialkowski > S: Supported > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 6dc451f58a3e..a55e9437c8cf 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -335,6 +335,17 @@ config DRM_PANEL_LG_LG4573 > Say Y here if you want to enable support for LG4573 RGB panel. > To compile this driver as a module, choose M here. > > +config DRM_PANEL_LG_SW43408 > + tristate "LG SW43408 panel" > + depends on OF > + depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > + help > + Say Y here if you want to enable support for LG sw43408 panel. > + The panel has a 1080x2160 resolution and uses > + 24 bit RGB per pixel. It provides a MIPI DSI interface to > + the host and has a built-in LED backlight. > + > config DRM_PANEL_MAGNACHIP_D53E6EA8966 > tristate "Magnachip D53E6EA8966 DSI panel" > depends on OF && SPI > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 24a02655d726..0b40b010e8e7 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -34,6 +34,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += > panel-leadtek-ltk050h3146w.o > obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o > obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o > obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o > +obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o > obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += > panel-magnachip-d53e6ea8966.o > obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o > obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o > diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c > b/drivers/gpu/drm/panel/panel-lg-sw43408.c > new file mode 100644 > index ..c7611bfa796b > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c > @@ -0,0 +1,326 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2019-2024 Linaro Ltd > + * Author: Sumit Semwal > + *Dmitry Baryshkov > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#define NUM_SUPPLIES 2 > + > +struct sw43408_panel { > + struct drm_panel base; > + struct mipi_dsi_device *link; > + > + const struct drm_display_mode *mode; > + > + struct regulator_bulk_data supplies[NUM_SUPPLIES]; > + > + struct gpio_desc *reset_gpio; > + > + struct drm_dsc_config dsc; > +}; > + > +static inline struct sw43408_panel *to_panel_info(struct drm_panel *panel) > +{ > + return container_of(panel, struct sw43408_panel, base); > +} > + > +static int sw43408_unprepare(struct drm_panel *panel) > +{ > + struct sw43408_panel *ctx = to_panel_info(panel); > + int ret; > + > + ret = mipi_dsi_dcs_set_display_off(ctx->link); > + if (ret < 0) > + dev_err(panel->dev, "set_display_off cmd failed ret = %d\n", > ret
Re: [PATCH v3 3/4] drm/mipi-dsi: add mipi_dsi_compression_mode_ext()
On 2024-04-02 02:51:14, Dmitry Baryshkov wrote: > Add the extended version of mipi_dsi_compression_mode(). It provides > a way to specify the algorithm and PPS selector. > > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/drm_mipi_dsi.c | 33 +++-- > include/drm/drm_mipi_dsi.h | 9 + > 2 files changed, 36 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index 9874ff6d4718..0ecbc811eb7a 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -645,19 +645,24 @@ int mipi_dsi_set_maximum_return_packet_size(struct > mipi_dsi_device *dsi, > EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); > > /** > - * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral > * @dsi: DSI peripheral device > * @enable: Whether to enable or disable the DSC > + * @algo: Selected algorithm > + * @pps_selector: The PPS selector Not a big fan of paraphrasing the parameter name, it adds no value. How about describing what this parameter means and what it does?: PPS table index to use. Corresponds to a table pre-programmed on the peripheral or a table programmed with _dsc_picture_parameter_set.pps_identifier. (That should be a valid kernel-doc cross-reference to the field) > * > - * Enable or disable Display Stream Compression on the peripheral using the > - * default Picture Parameter Set and VESA DSC 1.1 algorithm. > + * Enable or disable Display Stream Compression on the peripheral. > * > * Return: 0 on success or a negative error code on failure. > */ > -int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, > + enum mipi_dsi_compression_algo algo, > + unsigned int pps_selector) > { > - /* Note: Needs updating for non-default PPS or algorithm */ > - u8 tx[2] = { enable << 0, 0 }; > + u8 data = (enable << 0) | > + (algo << 1) | > + (pps_selector << 4); Do we need some size validation (if > 3 return -EINVAL)? FIELD_PREP() might be too heavy though. > + u8 tx[2] = { data, 0 }; > struct mipi_dsi_msg msg = { > .channel = dsi->channel, > .type = MIPI_DSI_COMPRESSION_MODE, > @@ -668,6 +673,22 @@ int mipi_dsi_compression_mode(struct mipi_dsi_device > *dsi, bool enable) > > return (ret < 0) ? ret : 0; > } > +EXPORT_SYMBOL(mipi_dsi_compression_mode_ext); > + > +/** > + * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * @dsi: DSI peripheral device > + * @enable: Whether to enable or disable the DSC > + * > + * Enable or disable Display Stream Compression on the peripheral using the > + * default Picture Parameter Set and VESA DSC 1.1 algorithm. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +{ > + return mipi_dsi_compression_mode_ext(dsi, enable, 0, > MIPI_DSI_COMPRESSION_DSC); I hope the compiler complains here that it should be MIPI_DSI_COMPRESSION_DSC,0 (Enum algo first, int pps_selector last) > +} > EXPORT_SYMBOL(mipi_dsi_compression_mode); > > /** > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h > index 3011d33eccbd..78cb7b688b1d 100644 > --- a/include/drm/drm_mipi_dsi.h > +++ b/include/drm/drm_mipi_dsi.h > @@ -226,6 +226,12 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum > mipi_dsi_pixel_format fmt) > return -EINVAL; > } > > +enum mipi_dsi_compression_algo { > + MIPI_DSI_COMPRESSION_DSC = 0, Add 1.1? Or does it also allow 1.2 (when the version is also set via PPS)? > + MIPI_DSI_COMPRESSION_VENDOR = 3, > + /* other two values are reserved, DSI 1.3 */ > +}; > + > struct mipi_dsi_device * > mipi_dsi_device_register_full(struct mipi_dsi_host *host, > const struct mipi_dsi_device_info *info); > @@ -242,6 +248,9 @@ int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device > *dsi); > int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, > u16 value); > int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable); > +int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, > + unsigned int pps_selector, > + enum mipi_dsi_compression_algo algo); Oh, this declaration is inverse from the definition... - Marijn > int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > const struct drm_dsc_picture_parameter_set > *pps); > > > -- > 2.39.2 >
Re: [PATCH v3 2/4] drm/mipi-dsi: use correct return type for the DSC functions
On 2024-04-02 02:51:13, Dmitry Baryshkov wrote: > The functions mipi_dsi_compression_mode() and > mipi_dsi_picture_parameter_set() return 0-or-error rather than a buffer > size. Follow example of other similar MIPI DSI functions and use int > return type instead of size_t. > > Fixes: f4dea1aaa9a1 ("drm/dsi: add helpers for DSI compression mode and PPS > packets") > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/drm_mipi_dsi.c | 6 +++--- > include/drm/drm_mipi_dsi.h | 6 +++--- > 2 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index ef6e416522f8..9874ff6d4718 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -654,7 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); > * > * Return: 0 on success or a negative error code on failure. > */ > -ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > { > /* Note: Needs updating for non-default PPS or algorithm */ > u8 tx[2] = { enable << 0, 0 }; > @@ -679,8 +679,8 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode); > * > * Return: 0 on success or a negative error code on failure. > */ > -ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > -const struct > drm_dsc_picture_parameter_set *pps) > +int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > +const struct drm_dsc_picture_parameter_set > *pps) > { > struct mipi_dsi_msg msg = { > .channel = dsi->channel, > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h > index c0aec0d4d664..3011d33eccbd 100644 > --- a/include/drm/drm_mipi_dsi.h > +++ b/include/drm/drm_mipi_dsi.h > @@ -241,9 +241,9 @@ int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device > *dsi); > int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi); > int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, > u16 value); > -ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable); > -ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > -const struct > drm_dsc_picture_parameter_set *pps); > +int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable); > +int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > +const struct drm_dsc_picture_parameter_set > *pps); > > ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void > *payload, > size_t size); > > -- > 2.39.2 >
Re: [PATCH v3 1/4] dt-bindings: panel: Add LG SW43408 MIPI-DSI panel
On 2024-04-02 10:23:22, Dmitry Baryshkov wrote: > On Tue, 2 Apr 2024 at 09:31, Krzysztof Kozlowski > wrote: > > > > On 02/04/2024 01:51, Dmitry Baryshkov wrote: > > > From: Sumit Semwal > > > > > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel present on Google Pixel 3 > > > phones. > > > > > > Signed-off-by: Vinod Koul > > > Signed-off-by: Sumit Semwal > > > [caleb: convert to yaml] > > > Signed-off-by: Caleb Connolly > > > Signed-off-by: Dmitry Baryshkov > > > --- > > > > Tags missing. > > > > `b4 trailers -u` > > Excuse me, I keep on forgetting it. Does a similar thing exist for adding Cc: tags for all reviewers/replyers to an earlier version, even if said reviewer didn't yet provide R-b/A-b or other tags? I'd like to have the next revisions in my inbox as well after leaving comments :) Thanks! - Marijn
Re: [PATCH 3/3] drm: panel: Add LG sw43408 panel driver
On 2024-04-01 22:11:48, Dmitry Baryshkov wrote: > On Mon, 1 Apr 2024 at 13:29, Marijn Suijten > wrote: > > > > On 2024-03-30 16:37:08, Dmitry Baryshkov wrote: > > > On Sat, 30 Mar 2024 at 12:27, Marijn Suijten > > > wrote: > > > > > > > > On 2024-03-30 05:59:30, Dmitry Baryshkov wrote: > > > > > From: Sumit Semwal > > > > > > > > > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3 > > > > > phones. > > > > > > > > > > Whatever init sequence we have for this panel isn't capable of > > > > > initialising it completely, toggling the reset gpio ever causes the > > > > > panel to die. Until this is resolved we avoid resetting the panel. The > > > > > > > > Are you sure it is avoided? This patch seems to be toggling reset_gpio > > > > in > > > > sw43408_prepare()? > > > > > > > > > disable/unprepare functions only put the panel to sleep mode and > > > > > disable the backlight. > > > > > > > > > > Signed-off-by: Sumit Semwal > > > > > [vinod: Add DSC support] > > > > > Signed-off-by: Vinod Koul > > > > > [caleb: cleanup and support turning off the panel] > > > > > Signed-off-by: Caleb Connolly > > > > > [DB: partially rewrote the driver and fixed DSC programming] > > > > > Signed-off-by: Dmitry Baryshkov > > > > > --- > > > > > MAINTAINERS | 8 + > > > > > drivers/gpu/drm/panel/Kconfig| 11 ++ > > > > > drivers/gpu/drm/panel/Makefile | 1 + > > > > > drivers/gpu/drm/panel/panel-lg-sw43408.c | 322 > > > > > +++ > > > > > 4 files changed, 342 insertions(+) > > > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > > index 4b511a55101c..f4cf7ee97376 100644 > > > > > --- a/MAINTAINERS > > > > > +++ b/MAINTAINERS > > > > > @@ -6755,6 +6755,14 @@ S: Maintained > > > > > F: > > > > > Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml > > > > > F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c > > > > > > > > > > +DRM DRIVER FOR LG SW43408 PANELS > > > > > +M: Sumit Semwal > > > > > +M: Caleb Connolly > > > > > +S: Maintained > > > > > +T: git git://anongit.freedesktop.org/drm/drm-misc > > > > > +F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml > > > > > +F: drivers/gpu/drm/panel/panel-lg-sw43408.c > > > > > + > > > > > DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER > > > > > M: Paul Kocialkowski > > > > > S: Supported > > > > > diff --git a/drivers/gpu/drm/panel/Kconfig > > > > > b/drivers/gpu/drm/panel/Kconfig > > > > > index d037b3b8b999..f94c702735cb 100644 > > > > > --- a/drivers/gpu/drm/panel/Kconfig > > > > > +++ b/drivers/gpu/drm/panel/Kconfig > > > > > @@ -335,6 +335,17 @@ config DRM_PANEL_LG_LG4573 > > > > > Say Y here if you want to enable support for LG4573 RGB panel. > > > > > To compile this driver as a module, choose M here. > > > > > > > > > > +config DRM_PANEL_LG_SW43408 > > > > > + tristate "LG SW43408 panel" > > > > > + depends on OF > > > > > + depends on DRM_MIPI_DSI > > > > > + depends on BACKLIGHT_CLASS_DEVICE > > > > > + help > > > > > + Say Y here if you want to enable support for LG sw43408 panel. > > > > > + The panel has a 1080x2160 resolution and uses > > > > > + 24 bit RGB per pixel. It provides a MIPI DSI interface to > > > > > + the host and has a built-in LED backlight. > > > > > + > > > > > config DRM_PANEL_MAGNACHIP_D53E6EA8966 > > > > > tristate "Magnachip D53E6EA8966 DSI panel" > > > > > depends on OF && SPI > > > > > diff --git a/drivers/gpu/drm/panel/Makefile > > > > > b/drivers/gpu/drm/panel/Makefile > > > > > index f156d7fa0bcc..a75687d13caf 100644 > > > > > --- a/drive
Re: [PATCH 2/3] drm/mipi-dsi: add mipi_dsi_compression_mode_raw()
On 2024-03-30 05:59:29, Dmitry Baryshkov wrote: > The LG SW43408 panel requires sending non-standard data as a part of the > MIPI_DSI_COMPRESSION_MODE packet. Rather than hacking existing > mipi_dsi_compression_mode() add mipi_dsi_compression_mode_raw(), which > accepts raw data buffer and length. Even though I doubt the usefulness of this _raw() command before further understanding the panel and driver (according the the review-followup sent a few minutes ago), let me review this a little bit. > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/drm_mipi_dsi.c | 34 ++ > include/drm/drm_mipi_dsi.h | 1 + > 2 files changed, 27 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index ef6e416522f8..f340d1e0a9a5 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -645,29 +645,47 @@ int mipi_dsi_set_maximum_return_packet_size(struct > mipi_dsi_device *dsi, > EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); > > /** > - * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * mipi_dsi_compression_mode_raw() - control DSC on the peripheral > * @dsi: DSI peripheral device > - * @enable: Whether to enable or disable the DSC > + * @data: data to be sent to the device > + * @len: size of the data buffer > * > - * Enable or disable Display Stream Compression on the peripheral using the > + * Control the Display Stream Compression on the peripheral using the + mode? > * default Picture Parameter Set and VESA DSC 1.1 algorithm. This is no longer true. Both the algoritm identifier and "default Picture Parameter Set" (which I assume means table *index*!) are described by the custom/raw bytes that one is allowed to pass. In fact, in the SW43408 driver that you reference in the commit message the custom data passed to the _raw() function is used to select the second PPS table (unless the panel interprets the input data in a non-standard way...), and further sets the PPS for the first table only :) > * > * Return: 0 on success or a negative error code on failure. > */ > -ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +ssize_t mipi_dsi_compression_mode_raw(struct mipi_dsi_device *dsi, void > *data, size_t len) > { > - /* Note: Needs updating for non-default PPS or algorithm */ > - u8 tx[2] = { enable << 0, 0 }; > struct mipi_dsi_msg msg = { > .channel = dsi->channel, > .type = MIPI_DSI_COMPRESSION_MODE, > - .tx_len = sizeof(tx), > - .tx_buf = tx, > + .tx_len = len, > + .tx_buf = data, > }; > int ret = mipi_dsi_device_transfer(dsi, ); > > return (ret < 0) ? ret : 0; > } > +EXPORT_SYMBOL(mipi_dsi_compression_mode_raw); > + > +/** > + * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral > + * @dsi: DSI peripheral device > + * @enable: Whether to enable or disable the DSC > + * > + * Enable or disable Display Stream Compression on the peripheral using the > + * default Picture Parameter Set and VESA DSC 1.1 algorithm. And while fixing this up, let's make it clear that this doesn't change the PPS, just the *index* of which PPS to use (the PPS is updated with a different command). - Marijn > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) > +{ > + /* Note: Needs updating for non-default PPS or algorithm */ > + u8 tx[2] = { enable << 0, 0 }; > + > + return mipi_dsi_compression_mode_raw(dsi, tx, sizeof(tx)); > +} > EXPORT_SYMBOL(mipi_dsi_compression_mode); > > /** > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h > index c0aec0d4d664..321d2b019687 100644 > --- a/include/drm/drm_mipi_dsi.h > +++ b/include/drm/drm_mipi_dsi.h > @@ -242,6 +242,7 @@ int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device > *dsi); > int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, > u16 value); > ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable); > +ssize_t mipi_dsi_compression_mode_raw(struct mipi_dsi_device *dsi, void > *data, size_t len); > ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, > const struct > drm_dsc_picture_parameter_set *pps); > > > -- > 2.39.2 >
Re: [PATCH 3/3] drm: panel: Add LG sw43408 panel driver
On 2024-03-30 16:37:08, Dmitry Baryshkov wrote: > On Sat, 30 Mar 2024 at 12:27, Marijn Suijten > wrote: > > > > On 2024-03-30 05:59:30, Dmitry Baryshkov wrote: > > > From: Sumit Semwal > > > > > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3 > > > phones. > > > > > > Whatever init sequence we have for this panel isn't capable of > > > initialising it completely, toggling the reset gpio ever causes the > > > panel to die. Until this is resolved we avoid resetting the panel. The > > > > Are you sure it is avoided? This patch seems to be toggling reset_gpio in > > sw43408_prepare()? > > > > > disable/unprepare functions only put the panel to sleep mode and > > > disable the backlight. > > > > > > Signed-off-by: Sumit Semwal > > > [vinod: Add DSC support] > > > Signed-off-by: Vinod Koul > > > [caleb: cleanup and support turning off the panel] > > > Signed-off-by: Caleb Connolly > > > [DB: partially rewrote the driver and fixed DSC programming] > > > Signed-off-by: Dmitry Baryshkov > > > --- > > > MAINTAINERS | 8 + > > > drivers/gpu/drm/panel/Kconfig| 11 ++ > > > drivers/gpu/drm/panel/Makefile | 1 + > > > drivers/gpu/drm/panel/panel-lg-sw43408.c | 322 > > > +++ > > > 4 files changed, 342 insertions(+) > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > index 4b511a55101c..f4cf7ee97376 100644 > > > --- a/MAINTAINERS > > > +++ b/MAINTAINERS > > > @@ -6755,6 +6755,14 @@ S: Maintained > > > F: > > > Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml > > > F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c > > > > > > +DRM DRIVER FOR LG SW43408 PANELS > > > +M: Sumit Semwal > > > +M: Caleb Connolly > > > +S: Maintained > > > +T: git git://anongit.freedesktop.org/drm/drm-misc > > > +F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml > > > +F: drivers/gpu/drm/panel/panel-lg-sw43408.c > > > + > > > DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER > > > M: Paul Kocialkowski > > > S: Supported > > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > > > index d037b3b8b999..f94c702735cb 100644 > > > --- a/drivers/gpu/drm/panel/Kconfig > > > +++ b/drivers/gpu/drm/panel/Kconfig > > > @@ -335,6 +335,17 @@ config DRM_PANEL_LG_LG4573 > > > Say Y here if you want to enable support for LG4573 RGB panel. > > > To compile this driver as a module, choose M here. > > > > > > +config DRM_PANEL_LG_SW43408 > > > + tristate "LG SW43408 panel" > > > + depends on OF > > > + depends on DRM_MIPI_DSI > > > + depends on BACKLIGHT_CLASS_DEVICE > > > + help > > > + Say Y here if you want to enable support for LG sw43408 panel. > > > + The panel has a 1080x2160 resolution and uses > > > + 24 bit RGB per pixel. It provides a MIPI DSI interface to > > > + the host and has a built-in LED backlight. > > > + > > > config DRM_PANEL_MAGNACHIP_D53E6EA8966 > > > tristate "Magnachip D53E6EA8966 DSI panel" > > > depends on OF && SPI > > > diff --git a/drivers/gpu/drm/panel/Makefile > > > b/drivers/gpu/drm/panel/Makefile > > > index f156d7fa0bcc..a75687d13caf 100644 > > > --- a/drivers/gpu/drm/panel/Makefile > > > +++ b/drivers/gpu/drm/panel/Makefile > > > @@ -34,6 +34,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += > > > panel-leadtek-ltk050h3146w.o > > > obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += > > > panel-leadtek-ltk500hd1829.o > > > obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o > > > obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o > > > +obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o > > > obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += > > > panel-magnachip-d53e6ea8966.o > > > obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o > > > obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o > > > diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c > > > b/drivers/gpu/drm/panel/panel-lg-sw43408.c > > > new file mode 100644 > > >
Re: [PATCH] drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more sensible
On 2024-03-30 11:31:37, Marijn Suijten wrote: > On 2024-03-30 05:53:22, Dmitry Baryshkov wrote: > > There is little point in using %ps to print a value known to be NULL. On > > the other hand it makes sense to print the callback symbol in the > > 'invalid IRQ' message. Correct those two error messages to make more > > sense. > > > > Fixes: 6893199183f8 ("drm/msm/dpu: stop using raw IRQ indices in the kernel > > output") > > Signed-off-by: Dmitry Baryshkov > > Agreed, this is a lot more clear: > > Reviewed-by: Marijn Suijten Note that, as seen in [1], there are still a few codepaths that only print "invalid IRQ" without any additional context (if we could even add it - __func__ might be a good start) and inconsistently use DPU_ERROR vs pr_err too :/ Any possibility to address that? - Marijn [1]: https://lore.kernel.org/linux-arm-msm/mxwrvnqth5f2vd4m55ryzqgyj7brykiqynzldelanxkuj2zny3@4pqi6p57c2q2/ > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > index 946dd0135dff..6a0a74832fb6 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > @@ -525,14 +525,14 @@ int dpu_core_irq_register_callback(struct dpu_kms > > *dpu_kms, > > int ret; > > > > if (!irq_cb) { > > - DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", > > - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); > > + DPU_ERROR("IRQ=[%d, %d] NULL callback\n", > > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > > return -EINVAL; > > } > > > > if (!dpu_core_irq_is_valid(irq_idx)) { > > - DPU_ERROR("invalid IRQ=[%d, %d]\n", > > - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > > + DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", > > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); > > return -EINVAL; > > } > > > > > > --- > > base-commit: 13ee4a7161b6fd938aef6688ff43b163f6d83e37 > > change-id: 20240330-dpu-irq-messages-5cf13fd7568c > > > > Best regards, > > -- > > Dmitry Baryshkov > >
Re: [PATCH] drm/msm/dpu: fix vblank IRQ handling for command panels
On 2024-03-30 05:52:29, Dmitry Baryshkov wrote: > In case of CMD DSI panels, the vblank IRQ can be used outside of > irq_enable/irq_disable pair. This results in the following kind of Can you clarify when exactly that is? Is it via ops.control_vblank_irq in dpu_encoder_toggle_vblank_for_crtc()? > messages. Move assignment of IRQ indices to atomic_enable / > atomic_disable callbacks. > > [dpu error]invalid IRQ=[134217727, 31] > [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 > pp:0 ret:-22, enable true/0 > [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 > pp:0 ret:-22, enable false/0 You are right that such messages are common, both at random but also seemingly around toggling the `ACTIVE` property on the CRTC: [ 45.878300] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_disable [ 45.909941] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_unprepare [ 46.093234] [drm:dpu_encoder_helper_wait_for_irq] *ERROR* encoder is disabled id=31, callback=dpu_encoder_phys_cmd_ctl_start_irq, IRQ=[134217727, 31] [ 46.130421] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_prepare [ 46.340457] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_enable [ 65.520323] [dpu error]invalid IRQ=[134217727, 31] irq_cb:dpu_encoder_phys_cmd_te_rd_ptr_irq [ 65.520463] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable true/0 [ 65.630199] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable false/0 [ 166.576465] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_disable [ 166.609674] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_unprepare [ 166.781967] [drm:dpu_encoder_helper_wait_for_irq] *ERROR* encoder is disabled id=31, callback=dpu_encoder_phys_cmd_ctl_start_irq, IRQ=[134217727, 31] [ 166.829805] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_prepare [ 167.040476] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_enable [ 337.449827] [dpu error]invalid IRQ=[134217727, 31] irq_cb:dpu_encoder_phys_cmd_te_rd_ptr_irq [ 337.450434] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable true/0 [ 337.569526] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable false/0 [ 354.980357] [dpu error]invalid IRQ=[134217727, 31] irq_cb:dpu_encoder_phys_cmd_te_rd_ptr_irq [ 354.980495] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable true/0 [ 355.090460] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable false/0 Unfortunately with this patch, turning the CRTC off via ./modetest -M msm -a -w 81:ACTIVE:0 immediately triggers a bunch of WARNs (note that the CRTC turns on immediately again when the command returns, that's probably the framebuffer console taking over again). Running it a few times in succession this may or may not happen, or reboot the phone (Xperia Griffin) entirely: [ 23.423930] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_disable [ 23.461013] [dpu error]invalid IRQ=[134217727, 31] [ 23.461144] [dpu error]invalid IRQ=[134217727, 31] [ 23.461208] [drm:dpu_encoder_phys_cmd_control_vblank_irq] *ERROR* vblank irq err id:31 pp:0 ret:-22, enable false/1 [ 23.461340] [dpu error]invalid IRQ=[134217727, 31] [ 23.461406] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_unprepare [ 23.641721] [drm:dpu_encoder_helper_wait_for_irq] *ERROR* encoder is disabled id=31, callback=dpu_encoder_phys_cmd_ctl_start_irq, IRQ=[134217727, 31] [ 23.679938] panel-samsung-souxp ae94000.dsi.0: samsung_souxp00_prepare [ 23.900465] [ cut here ] [ 23.900813] WARNING: CPU: 1 PID: 747 at drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c:545 dpu_core_irq_register_callback+0x1b4/0x244 [ 23.901450] Modules linked in: [ 23.901814] CPU: 1 PID: 747 Comm: modetest Tainted: G U 6.9.0-rc1-next-20240328-SoMainline-02555-g27abbea53b6b #19 [ 23.902402] Hardware name: Sony Xperia 1 (DT) [ 23.902674] pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 23.903133] pc : dpu_core_irq_register_callback+0x1b4/0x244 [ 23.903455] lr : dpu_encoder_phys_cmd_irq_enable+0x30/0x8c [ 23.903880] sp : 800086833930 [ 23.904123] x29: 800086833930 x28: 0001 x27: 0273834522d0 [ 23.904604] x26: d46ebdb5edc8 x25: d46ebe0f1228 x24: 02738106b280 [ 23.904973] x23: 027383452000 x22: d46ebd086290 x21: [ 23.905452] x20: 027382712080
Re: [PATCH] drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more sensible
On 2024-03-30 05:53:22, Dmitry Baryshkov wrote: > There is little point in using %ps to print a value known to be NULL. On > the other hand it makes sense to print the callback symbol in the > 'invalid IRQ' message. Correct those two error messages to make more > sense. > > Fixes: 6893199183f8 ("drm/msm/dpu: stop using raw IRQ indices in the kernel > output") > Signed-off-by: Dmitry Baryshkov Agreed, this is a lot more clear: Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 946dd0135dff..6a0a74832fb6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -525,14 +525,14 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, > int ret; > > if (!irq_cb) { > - DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", > - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); > + DPU_ERROR("IRQ=[%d, %d] NULL callback\n", > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > return -EINVAL; > } > > if (!dpu_core_irq_is_valid(irq_idx)) { > - DPU_ERROR("invalid IRQ=[%d, %d]\n", > - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > + DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); > return -EINVAL; > } > > > --- > base-commit: 13ee4a7161b6fd938aef6688ff43b163f6d83e37 > change-id: 20240330-dpu-irq-messages-5cf13fd7568c > > Best regards, > -- > Dmitry Baryshkov >
Re: [PATCH 3/3] drm: panel: Add LG sw43408 panel driver
On 2024-03-30 05:59:30, Dmitry Baryshkov wrote: > From: Sumit Semwal > > LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3 > phones. > > Whatever init sequence we have for this panel isn't capable of > initialising it completely, toggling the reset gpio ever causes the > panel to die. Until this is resolved we avoid resetting the panel. The Are you sure it is avoided? This patch seems to be toggling reset_gpio in sw43408_prepare()? > disable/unprepare functions only put the panel to sleep mode and > disable the backlight. > > Signed-off-by: Sumit Semwal > [vinod: Add DSC support] > Signed-off-by: Vinod Koul > [caleb: cleanup and support turning off the panel] > Signed-off-by: Caleb Connolly > [DB: partially rewrote the driver and fixed DSC programming] > Signed-off-by: Dmitry Baryshkov > --- > MAINTAINERS | 8 + > drivers/gpu/drm/panel/Kconfig| 11 ++ > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-lg-sw43408.c | 322 > +++ > 4 files changed, 342 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 4b511a55101c..f4cf7ee97376 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6755,6 +6755,14 @@ S: Maintained > F: Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml > F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c > > +DRM DRIVER FOR LG SW43408 PANELS > +M: Sumit Semwal > +M: Caleb Connolly > +S: Maintained > +T: git git://anongit.freedesktop.org/drm/drm-misc > +F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml > +F: drivers/gpu/drm/panel/panel-lg-sw43408.c > + > DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER > M: Paul Kocialkowski > S: Supported > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index d037b3b8b999..f94c702735cb 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -335,6 +335,17 @@ config DRM_PANEL_LG_LG4573 > Say Y here if you want to enable support for LG4573 RGB panel. > To compile this driver as a module, choose M here. > > +config DRM_PANEL_LG_SW43408 > + tristate "LG SW43408 panel" > + depends on OF > + depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > + help > + Say Y here if you want to enable support for LG sw43408 panel. > + The panel has a 1080x2160 resolution and uses > + 24 bit RGB per pixel. It provides a MIPI DSI interface to > + the host and has a built-in LED backlight. > + > config DRM_PANEL_MAGNACHIP_D53E6EA8966 > tristate "Magnachip D53E6EA8966 DSI panel" > depends on OF && SPI > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index f156d7fa0bcc..a75687d13caf 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -34,6 +34,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += > panel-leadtek-ltk050h3146w.o > obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o > obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o > obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o > +obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o > obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += > panel-magnachip-d53e6ea8966.o > obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o > obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o > diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c > b/drivers/gpu/drm/panel/panel-lg-sw43408.c > new file mode 100644 > index ..365d25e14d54 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c > @@ -0,0 +1,322 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2019-2024 Linaro Ltd > + * Author: Sumit Semwal > + *Dmitry Baryshkov > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#define NUM_SUPPLIES 2 > + > +struct sw43408_panel { > + struct drm_panel base; > + struct mipi_dsi_device *link; > + > + const struct drm_display_mode *mode; > + > + struct regulator_bulk_data supplies[NUM_SUPPLIES]; > + > + struct gpio_desc *reset_gpio; > +}; > + > +static inline struct sw43408_panel *to_panel_info(struct drm_panel *panel) > +{ > + return container_of(panel, struct sw43408_panel, base); > +} > + > +static int sw43408_unprepare(struct drm_panel *panel) > +{ > + struct sw43408_panel *ctx = to_panel_info(panel); > + int ret; > + > + ret = mipi_dsi_dcs_set_display_off(ctx->link); > + if (ret < 0) > + dev_err(panel->dev, "set_display_off cmd failed ret = %d\n", > ret); > + > + ret = mipi_dsi_dcs_enter_sleep_mode(ctx->link); > + if (ret < 0) > + dev_err(panel->dev, "enter_sleep cmd failed ret = %d\n", ret); > + > +
[PATCH] drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled
When the topology calls for two interfaces on the current fixed topology of 2 DSC blocks, or uses 1 DSC block for a single interface (e.g. SC7280 with only one DSC block), there should be no merging of DSC output. This is already represented by the return value of dpu_encoder_use_dsc_merge(), but not yet used to correctly configure this flag. Fixes: 58dca9810749 ("drm/msm/disp/dpu1: Add support for DSC in encoder") Signed-off-by: Marijn Suijten --- Note that more changes are needed to properly support the proposed 2:2:2 and 1:1:1 topology (in contrast to the already-supported 2:2:1 topology), but this could be a trivial patch to get going separately before all that extra work is done. --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 83380bc92a00..6d3ed4d870d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1857,7 +1857,9 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, dsc_common_mode = 0; pic_width = dsc->pic_width; - dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; + dsc_common_mode = DSC_MODE_SPLIT_PANEL; + if (dpu_encoder_use_dsc_merge(enc_master->parent)) + dsc_common_mode |= DSC_MODE_MULTIPLEX; if (enc_master->intf_mode == INTF_MODE_VIDEO) dsc_common_mode |= DSC_MODE_VIDEO; --- base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc change-id: 20240204-dpu-dsc-multiplex-49c14b73f3e0 Best regards, -- Marijn Suijten
[PATCH] drm/msm/dsi: Replace dsi_get_bpp() with mipi_dsi header function
drm_mipi_dsi.h already provides a conversion function from MIPI_DSI_FMT_ to bpp, named mipi_dsi_pixel_format_to_bpp(). Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/dsi_host.c | 18 -- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index deeecdfd6c4e..9fa0053fac74 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -183,16 +183,6 @@ struct msm_dsi_host { int irq; }; -static u32 dsi_get_bpp(const enum mipi_dsi_pixel_format fmt) -{ - switch (fmt) { - case MIPI_DSI_FMT_RGB565: return 16; - case MIPI_DSI_FMT_RGB666_PACKED:return 18; - case MIPI_DSI_FMT_RGB666: - case MIPI_DSI_FMT_RGB888: - default:return 24; - } -} static inline u32 dsi_read(struct msm_dsi_host *msm_host, u32 reg) { @@ -567,7 +557,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); u8 lanes = msm_host->lanes; - u32 bpp = dsi_get_bpp(msm_host->format); + u32 bpp = mipi_dsi_pixel_format_to_bpp(msm_host->format); unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi); unsigned long pclk_bpp; @@ -610,7 +600,7 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi) int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { - u32 bpp = dsi_get_bpp(msm_host->format); + u32 bpp = mipi_dsi_pixel_format_to_bpp(msm_host->format); unsigned int esc_mhz, esc_div; unsigned long byte_mhz; @@ -993,7 +983,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) /* image data and 1 byte write_memory_start cmd */ if (!msm_host->dsc) - wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; + wc = hdisplay * mipi_dsi_pixel_format_to_bpp(msm_host->format) / 8 + 1; else /* * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1. @@ -1413,7 +1403,7 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host, { int len, ret; int bllp_len = msm_host->mode->hdisplay * - dsi_get_bpp(msm_host->format) / 8; + mipi_dsi_pixel_format_to_bpp(msm_host->format) / 8; len = dsi_cmd_dma_add(msm_host, msg); if (len < 0) { --- base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc change-id: 20231019-drm-msm-dsi-remove-open-coded-get-bpp-e7864b0b11dd Best regards, -- Marijn Suijten
Re: [PATCH 7/8] arm64: dts: qcom: msm8976: Declare and wire SDC pins
On 2024-01-21 20:41:05, Adam Skladowski wrote: > Declare pinctrls for SDC pins and wire them to consumers. > > Signed-off-by: Adam Skladowski Where'd the original sign-offs go? https://lore.kernel.org/linux-arm-msm/20221214232049.703484-1-marijn.suij...@somainline.org/ Thanks taking taking care of this SoC though. My SM8976 Suzu device finally emitted the magic smoke after rebasing on the latest MSM8976 patches, and will need board repairs or a replacement before patches can be tested again :( - Marijn > --- > arch/arm64/boot/dts/qcom/msm8976.dtsi | 100 ++ > 1 file changed, 100 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi > b/arch/arm64/boot/dts/qcom/msm8976.dtsi > index 765c90ac14cb..5a7be93a0115 100644 > --- a/arch/arm64/boot/dts/qcom/msm8976.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi > @@ -771,6 +771,96 @@ blsp2_i2c4_sleep: blsp2-i2c4-sleep-state { > drive-strength = <2>; > bias-disable; > }; > + > + sdc1_default: sdc1-default-state { > + clk-pins { > + pins = "sdc1_clk"; > + drive-strength = <16>; > + bias-disable; > + }; > + > + cmd-pins { > + pins = "sdc1_cmd"; > + drive-strength = <10>; > + bias-pull-up; > + }; > + > + data-pins { > + pins = "sdc1_data"; > + drive-strength = <10>; > + bias-pull-up; > + }; > + > + rclk-pins { > + pins = "sdc1_rclk"; > + bias-pull-down; > + }; > + }; > + > + sdc1_sleep: sdc1-sleep-state { > + clk-pins { > + pins = "sdc1_clk"; > + drive-strength = <2>; > + bias-disable; > + }; > + > + cmd-pins { > + pins = "sdc1_cmd"; > + drive-strength = <2>; > + bias-pull-up; > + }; > + > + data-pins { > + pins = "sdc1_data"; > + drive-strength = <2>; > + bias-pull-up; > + }; > + > + rclk-pins { > + pins = "sdc1_rclk"; > + bias-pull-down; > + }; > + }; > + > + sdc2_default: sdc2-default-state { > + clk-pins { > + pins = "sdc2_clk"; > + drive-strength = <16>; > + bias-disable; > + }; > + > + cmd-pins { > + pins = "sdc2_cmd"; > + drive-strength = <10>; > + bias-pull-up; > + }; > + > + data-pins { > + pins = "sdc2_data"; > + drive-strength = <10>; > + bias-pull-up; > + }; > + }; > + > + sdc2_sleep: sdc2-sleep-state { > + clk-pins { > + pins = "sdc2_clk"; > + drive-strength = <2>; > + bias-disable; > + }; > + > + cmd-pins { > + pins = "sdc2_cmd"; > + drive-strength = <2>; > + bias-pull-up; > + }; > + > + data-pins { > + pins = "sdc2_data"; > + drive-strength = <2>; > + bias-pull-up; > + }; > + }; > }; > > gcc: clock-controller@180 { > @@ -1246,6 +1336,11 @@ sdhc_1:
Re: [RFT PATCH v2 2/4] drm/msm/dpu: enable writeback on SC8108X
Title typo: SC8108X -> SC8180X :) On 2023-12-03 03:32:01, Dmitry Baryshkov wrote: > Enable WB2 hardware block, enabling writeback support on this platform. > > Signed-off-by: Dmitry Baryshkov > --- > .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 18 ++ > 1 file changed, 18 insertions(+) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > index 9ffc8804a6fc..d4b531752ec2 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > @@ -34,6 +34,7 @@ static const struct dpu_mdp_cfg sc8180x_mdp = { > [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, > [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, > [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, > + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, > }, > }; > > @@ -298,6 +299,21 @@ static const struct dpu_dsc_cfg sc8180x_dsc[] = { > }, > }; > > +static const struct dpu_wb_cfg sc8180x_wb[] = { > + { > + .name = "wb_2", .id = WB_2, > + .base = 0x65000, .len = 0x2c8, > + .features = WB_SDM845_MASK, > + .format_list = wb2_formats, > + .num_formats = ARRAY_SIZE(wb2_formats), > + .clk_ctrl = DPU_CLK_CTRL_WB2, > + .xin_id = 6, > + .vbif_idx = VBIF_RT, > + .maxlinewidth = 4096, > + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), > + }, > +}; > + > static const struct dpu_intf_cfg sc8180x_intf[] = { > { > .name = "intf_0", .id = INTF_0, > @@ -411,6 +427,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { > .pingpong = sc8180x_pp, > .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), > .merge_3d = sc8180x_merge_3d, > + .wb_count = ARRAY_SIZE(sc8180x_wb), > + .wb = sc8180x_wb, > .intf_count = ARRAY_SIZE(sc8180x_intf), > .intf = sc8180x_intf, > .vbif_count = ARRAY_SIZE(sdm845_vbif), > -- > 2.39.2 >
Re: [PATCH] drm/msm/dpu: Ratelimit framedone timeout msgs
On 2023-12-11 10:19:55, Rob Clark wrote: > From: Rob Clark > > When we start getting these, we get a *lot*. So ratelimit it to not > flood dmesg. > > Signed-off-by: Rob Clark > --- > > dpu should probably stop rolling it's own trace macros, but that would > be a larger cleanup. That would be lovely, use is currently all over the place. Should this patch also ratelimit the corresponding: [drm:dpu_encoder_phys_cmd_prepare_for_kickoff] *ERROR* failed wait_for_idle: id:31 ret:-110 pp:0 On CMD-mode panels? Note that this is a prime example of using DRM_ERROR over DPU_ERROR*, resulting in unnecessary divergence (and un-readability) between error messages and the code (DPU_DEBUG_CMDENC, which has a corresponding DPU_ERROR variant, is also used within that function...) Reviewed-by: Marijn Suijten > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 - > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + > 2 files changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 82538844614b..7c22235d0eba 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -39,6 +39,9 @@ > #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ > (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) > > +#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d > " fmt,\ > + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) > + > /* > * Two to anticipate panels that can do cmd/vid dynamic switching > * plan is to create all possible physical encoder types, and switch between > @@ -2339,7 +2342,7 @@ static void dpu_encoder_frame_done_timeout(struct > timer_list *t) > return; > } > > - DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); > + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); > > event = DPU_ENCODER_FRAME_EVENT_ERROR; > trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > index b6f53ca6e962..f5473d4dea92 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > @@ -51,6 +51,7 @@ > } while (0) > > #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) > +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" > fmt, ##__VA_ARGS__) > > /** > * ktime_compare_safe - compare two ktime structures > -- > 2.43.0 >
Re: [PATCH v2 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
On 2023-11-14 17:58:30, Jonathan Marek wrote: > The value returned by msm_dsi_wide_bus_enabled() doesn't match what the > driver is doing in video mode. Fix that by actually enabling widebus for > video mode. > > Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI") > Signed-off-by: Jonathan Marek Conditional r-b assuming this will be submitted to mesa, otherwise it'll disappear when the next person updates and regenerates these bindings. Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + > drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++ > 2 files changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h > b/drivers/gpu/drm/msm/dsi/dsi.xml.h > index 2a7d980e12c3..f0b3cdc020a1 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h > +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h > @@ -231,6 +231,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum > dsi_traffic_mode val) > #define DSI_VID_CFG0_HSA_POWER_STOP 0x0001 > #define DSI_VID_CFG0_HBP_POWER_STOP 0x0010 > #define DSI_VID_CFG0_HFP_POWER_STOP 0x0100 > +#define DSI_VID_CFG0_DATABUS_WIDEN 0x0200 > #define DSI_VID_CFG0_PULSE_MODE_HSA_HE > 0x1000 > > #define REG_DSI_VID_CFG1 0x001c > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index deeecdfd6c4e..f2c1cbd08d4d 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -745,6 +745,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host, > data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags)); > data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt)); > data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel); > + if (msm_dsi_host_is_wide_bus_enabled(_host->base)) > + data |= DSI_VID_CFG0_DATABUS_WIDEN; > dsi_write(msm_host, REG_DSI_VID_CFG0, data); > > /* Do not swap RGB colors */ > -- > 2.26.1 >
Re: [PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case
On 2023-11-14 14:00:19, Jonathan Marek wrote: > On 11/14/23 1:28 PM, Marijn Suijten wrote: > > On what hardware have you been testing this? Dmitry and I have a stack of > > patches to resolve support for Active CTL programming on newer hardware (DPU > > 5.0+ IIRC), where a single CTL is responsible for programming multiple INTF > > and > > DSC blocks as used in bonded DSI. > > > > I am also using DPU 6+ but I won't be posting patches for DPU to support > this as I am not using the upstream DPU codebase. Oh that is an odd situation! At least glad to hear we aren't completely duplicating our efforts :) > > On 2023-11-14 12:42:16, Jonathan Marek wrote: > >> For the bonded DSI case, DSC pic_width and timing calculations should use > >> the width of a single panel instead of the total combined width. > >> > >> Signed-off-by: Jonathan Marek > >> --- > >> drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- > >> drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++- > >> drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- > >> 3 files changed, 14 insertions(+), 11 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > >> index 28379b1af63f..3a641e69447c 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi.h > >> +++ b/drivers/gpu/drm/msm/dsi/dsi.h > >> @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); > >> int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > >> const struct drm_display_mode *mode); > >> enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > >> - const struct drm_display_mode > >> *mode); > >> + const struct drm_display_mode *mode, > >> + bool is_bonded_dsi); > >> unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); > >> int msm_dsi_host_register(struct mipi_dsi_host *host); > >> void msm_dsi_host_unregister(struct mipi_dsi_host *host); > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > >> b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> index 7284346ab787..a6286eb9d006 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > >> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host > >> *msm_host, bool is_bonded_dsi) > >> mode->hdisplay, mode->vdisplay); > >>return; > >>} > >> - > >> - dsc->pic_width = mode->hdisplay; > >> + dsc->pic_width = hdisplay; > > > > In my testing and debugging on CMDmode panels downstream this value/register > > was always programmed to the _full_ width of the bonded panel. Is that > > maybe > > different for video mode? > > > > downstream dual DSI panel timings are specified for a single panel > ("qcom,mdss-dsi-panel-width" is for a single panel, not both panels) _dual panels_? In my case I have a "single panel" that is driven by two "bonded" DSI hosts, just to achieve enough bandwidth. Indeed my downstream DTS has qcom,mdss-dsi-panel-width set to half the total panel width, but I recall seeing the full width in the register dump. I'll scan through my logs and see if I can back this up. > >>dsc->pic_height = mode->vdisplay; > >>DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); > >> > >> @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host > >> *msm_host, bool is_bonded_dsi) > >>if (ret) > >>return; > >> > >> + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) > >> + dsi_update_dsc_timing(msm_host, false, hdisplay); > >> + else > >> + dsi_update_dsc_timing(msm_host, true, hdisplay); Another thought: it's probably clearer to write: bool is_cmd_mode = msm_host->mode_flags & MIPI_DSI_MODE_VIDEO; dsi_update_dsc_timing(msm_host, is_cmd_mode, hdisplay); > >> + > > > > Such cleanups (which appear unrelated) should probably be posted as separate > > patches. > > > > - Marijn > > > > Its not unrelated, dsi_update_dsc_timing call is moved up so it can use > the single-panel "hdisplay" value before it gets adjusted for DSC. Th
Re: [PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case
On what hardware have you been testing this? Dmitry and I have a stack of patches to resolve support for Active CTL programming on newer hardware (DPU 5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and DSC blocks as used in bonded DSI. On 2023-11-14 12:42:16, Jonathan Marek wrote: > For the bonded DSI case, DSC pic_width and timing calculations should use > the width of a single panel instead of the total combined width. > > Signed-off-by: Jonathan Marek > --- > drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- > drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++- > drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- > 3 files changed, 14 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > index 28379b1af63f..3a641e69447c 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.h > +++ b/drivers/gpu/drm/msm/dsi/dsi.h > @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); > int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > const struct drm_display_mode *mode); > enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > - const struct drm_display_mode > *mode); > + const struct drm_display_mode *mode, > + bool is_bonded_dsi); > unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); > int msm_dsi_host_register(struct mipi_dsi_host *host); > void msm_dsi_host_unregister(struct mipi_dsi_host *host); > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 7284346ab787..a6286eb9d006 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > mode->hdisplay, mode->vdisplay); > return; > } > - > - dsc->pic_width = mode->hdisplay; > + dsc->pic_width = hdisplay; In my testing and debugging on CMDmode panels downstream this value/register was always programmed to the _full_ width of the bonded panel. Is that maybe different for video mode? > dsc->pic_height = mode->vdisplay; > DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); > > @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > if (ret) > return; > > + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) > + dsi_update_dsc_timing(msm_host, false, hdisplay); > + else > + dsi_update_dsc_timing(msm_host, true, hdisplay); > + Such cleanups (which appear unrelated) should probably be posted as separate patches. - Marijn > /* Divide the display by 3 but keep back/font porch and >* pulse width same >*/ > @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > } > > if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { > - if (msm_host->dsc) > - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); > - > dsi_write(msm_host, REG_DSI_ACTIVE_H, > DSI_ACTIVE_H_START(ha_start) | > DSI_ACTIVE_H_END(ha_end)); > @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | > DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); > } else {/* command mode */ > - if (msm_host->dsc) > - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); > - > /* image data and 1 byte write_memory_start cmd */ > if (!msm_host->dsc) > wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; > @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host > *host, > } > > enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > - const struct drm_display_mode *mode) > + const struct drm_display_mode *mode, > + bool is_bonded_dsi) > { > struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > struct drm_dsc_config *dsc = msm_host->dsc; > @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct > mipi_dsi_host *host, > if (!msm_host->dsc) > return MODE_OK; > > + if (is_bonded_dsi) > + pic_width = mode->hdisplay / 2; > + > if (pic_width % dsc->slice_width) { > pr_err("DSI: pic_width %d has to be multiple
Re: [PATCH RFC 0/5] drm/msm: dpu1: correctly implement SSPP & WB Clock Control Split
On 2023-10-09 18:36:11, Neil Armstrong wrote: > Starting with the SM8550 platform, the SSPP & WB Clock Controls are > no more in the MDP TOP registers, but in the SSPP & WB register space. > > Add the corresponding SSPP & WB ops and use them from the vbif QoS > and OT limit setup functions. > > Signed-off-by: Neil Armstrong > --- > Neil Armstrong (5): > drm/msm: dpu1: create a dpu_hw_clk_force_ctrl() helper > drm/msm: dpu1: add setup_clk_force_ctrl() op to sspp & wb > drm/msm: dpu1: vbif: add dpu_vbif_setup_clk_force_ctrl() helper > drm/msm: dpu1: call wb & sspp clk_force_ctrl op if split clock control > drm/msm: dpu1: sm8550: move split clock controls to sspp entries Fyi we're all using drm/msm/dpu: now :) - Marijn > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 35 +--- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 4 +-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c| 9 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h| 9 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 23 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c| 21 > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h| 4 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 9 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 4 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 9 +++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 38 > +- > drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h | 12 --- > 13 files changed, 120 insertions(+), 61 deletions(-) > --- > base-commit: 9119cf579b4432b36be9d33a92f4331922067d92 > change-id: 20231009-topic-sm8550-graphics-sspp-split-clk-43c32e37b6aa > > Best regards, > -- > Neil Armstrong >
Re: [PATCH v3 1/8] drm/msm/dpu: populate SSPP scaler block version
On 2023-09-05 04:25:19, Dmitry Baryshkov wrote: > The function _dpu_hw_sspp_setup_scaler3() passes and > dpu_hw_setup_scaler3() uses scaler_blk.version to determine in which way > the scaler (QSEED3) block should be programmed. However up to now we > were not setting this field. Set it now, splitting the vig_sblk data > which has different version fields. > > Reported-by: Marijn Suijten > Fixes: 9b6f4fedaac2 ("drm/msm/dpu: Add SM6125 support") > Fixes: 27f0df03f3ff ("drm/msm/dpu: Add SM6375 support") > Fixes: 3186acba5cdc ("drm/msm/dpu: Add SM6350 support") > Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550") > Fixes: 4a352c2fc15a ("drm/msm/dpu: Introduce SC8280XP") > Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog") > Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450") > Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115") > Fixes: dabfdd89eaa9 ("drm/msm/disp/dpu1: add inline rotation support for > sc7280") > Fixes: f3af2d6ee9ab ("drm/msm/dpu: Add SC8180x to hw catalog") > Fixes: 94391a14fc27 ("drm/msm/dpu1: Add MSM8998 to hw catalog") > Fixes: af776a3e1c30 ("drm/msm/dpu: add SM8250 to hw catalog") > Fixes: 386fced3f76f ("drm/msm/dpu: add SM8150 to hw catalog") > Fixes: b75ab05a3479 ("msm:disp:dpu1: add scaler support on SC7180 display") > Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") > Signed-off-by: Dmitry Baryshkov So as it turns out this patch is basically [1] with review comments applied, though no mention whatsoever that .version isn't just a convenient way to represent the version but what the register read by _dpu_hw_sspp_get_scaler3_ver() contains? (That was the review: hardcode the constants instead of doing runtime register reads) With that, `_dpu_hw_sspp_get_scaler3_ver()` and `dpu_hw_sspp->get_scaler_ver` must now be completely unused? [1]: https://lore.kernel.org/linux-arm-msm/caa8ejpobxpsyeqzq3zgwsqg6fc7pzqumwr9ddpdmgoemts-...@mail.gmail.com/#t It seems patch 6 in this series also has a matching - r-b'd - patch in that series ;) - Marijn > --- > .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 8 +- > .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 8 +- > .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 8 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 95 ++- > 4 files changed, 85 insertions(+), 34 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > index 99acaf917e43..f0c3804f4258 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { > .name = "sspp_0", .id = SSPP_VIG0, > .base = 0x4000, .len = 0x1f0, > .features = VIG_SDM845_MASK, > - .sblk = _vig_sblk_0, > + .sblk = _vig_sblk_0, > .xin_id = 0, > .type = SSPP_TYPE_VIG, > .clk_ctrl = DPU_CLK_CTRL_VIG0, > @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { > .name = "sspp_1", .id = SSPP_VIG1, > .base = 0x6000, .len = 0x1f0, > .features = VIG_SDM845_MASK, > - .sblk = _vig_sblk_1, > + .sblk = _vig_sblk_1, > .xin_id = 4, > .type = SSPP_TYPE_VIG, > .clk_ctrl = DPU_CLK_CTRL_VIG1, > @@ -93,7 +93,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { > .name = "sspp_2", .id = SSPP_VIG2, > .base = 0x8000, .len = 0x1f0, > .features = VIG_SDM845_MASK, > - .sblk = _vig_sblk_2, > + .sblk = _vig_sblk_2, > .xin_id = 8, > .type = SSPP_TYPE_VIG, > .clk_ctrl = DPU_CLK_CTRL_VIG2, > @@ -101,7 +101,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { > .name = "sspp_3", .id = SSPP_VIG3, > .base = 0xa000, .len = 0x1f0, > .features = VIG_SDM845_MASK, > - .sblk = _vig_sblk_3, > + .sblk = _vig_sblk_3, > .xin_id = 12, > .type = SSPP_TYPE_VIG, > .clk_ctrl = DPU_CLK_CTRL_VIG3, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > index f3de21025ca7..3ec954722a8e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1
Re: [PATCH v4 4/4] drm/msm/dsi: Enable widebus for DSI
On 2023-08-22 10:42:07, Jessica Zhang wrote: > DSI 6G v2.5.x+ supports a data-bus widen mode that allows DSI to send > 48 bits of compressed data instead of 24. > > Enable this mode whenever DSC is enabled for supported chipsets. > > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/dsi/dsi.c | 2 +- > drivers/gpu/drm/msm/dsi/dsi.h | 1 + > drivers/gpu/drm/msm/dsi/dsi_host.c | 31 +++ > 3 files changed, 29 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c > index 4cf424b3509f..7327bfc06a84 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.c > +++ b/drivers/gpu/drm/msm/dsi/dsi.c > @@ -19,7 +19,7 @@ struct drm_dsc_config *msm_dsi_get_dsc_config(struct > msm_dsi *msm_dsi) > > bool msm_dsi_wide_bus_enabled(struct msm_dsi *msm_dsi) > { > - return false; > + return msm_dsi_host_is_widebus_enabled(msm_dsi->host); > } > > static int dsi_get_phy(struct msm_dsi *msm_dsi) > diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > index bd3763a5d723..a557d2c1aaff 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.h > +++ b/drivers/gpu/drm/msm/dsi/dsi.h > @@ -134,6 +134,7 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, > bool is_bonded_dsi); > void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct > mipi_dsi_host *host); > void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host); > struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host > *host); > +bool msm_dsi_host_is_widebus_enabled(struct mipi_dsi_host *host); > > /* dsi phy */ > struct msm_dsi_phy; > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 645927214871..267c7fda8854 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -710,6 +710,15 @@ static void dsi_ctrl_disable(struct msm_dsi_host > *msm_host) > dsi_write(msm_host, REG_DSI_CTRL, 0); > } > > +bool msm_dsi_host_is_widebus_enabled(struct mipi_dsi_host *host) I thought you settled on wide_bus? > +{ > + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > + > + return msm_host->dsc && > + (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G && > + msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_5_0); > +} > + > static void dsi_ctrl_enable(struct msm_dsi_host *msm_host, > struct msm_dsi_phy_shared_timings *phy_shared_timings, > struct msm_dsi_phy *phy) > { > @@ -753,10 +762,16 @@ static void dsi_ctrl_enable(struct msm_dsi_host > *msm_host, > data |= DSI_CMD_CFG1_INSERT_DCS_COMMAND; > dsi_write(msm_host, REG_DSI_CMD_CFG1, data); > > - if (msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G && > - msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3) { > + if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) { > data = dsi_read(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2); > - data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE; > + > + if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3) > + data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE; > + > + /* TODO: Allow for video-mode support once tested/fixed > */ > + if (msm_dsi_host_is_widebus_enabled(_host->base)) > + data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN; > + > dsi_write(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2, data); > } > } > @@ -894,6 +909,7 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > u32 hdisplay = mode->hdisplay; > u32 wc; > int ret; > + bool widebus_enabled = msm_dsi_host_is_widebus_enabled(_host->base); > > DBG(""); > > @@ -914,6 +930,7 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > > if (msm_host->dsc) { > struct drm_dsc_config *dsc = msm_host->dsc; > + u32 bytes_per_pclk; > > /* update dsc params with timing params */ > if (!dsc || !mode->hdisplay || !mode->vdisplay) { > @@ -937,7 +954,13 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) >* pulse width same >*/ > h_total -= hdisplay; > - hdisplay = > DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); > + if (widebus_enabled && !(msm_host->mode_flags & > MIPI_DSI_MODE_VIDEO)) > + bytes_per_pclk = 6; > + else > + bytes_per_pclk = 3; > + > + hdisplay = > DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk); > + > h_total += hdisplay; > ha_end = ha_start + hdisplay; > } > > -- > 2.42.0 >
Re: [PATCH v5 6/8] drm/msm/dpu: stop using raw IRQ indices in the kernel output
On 2023-08-02 13:04:24, Dmitry Baryshkov wrote: > In preparation to reworking IRQ indcies, stop using raw IRQ indices in > kernel output (both printk and debugfs). Instead use a pair of register > index and bit. This corresponds closer to the values in HW catalog. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 26 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 51 +++ > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 2 + > 3 files changed, 46 insertions(+), 33 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 051447a3620c..b464df7a2dcf 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -351,7 +351,7 @@ static int dpu_encoder_helper_wait_event_timeout(int32_t > drm_id, > u32 irq_idx, struct dpu_encoder_wait_info *info); > > int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, > - int irq, > + int irq_idx, > void (*func)(void *arg), > struct dpu_encoder_wait_info *wait_info) > { > @@ -366,36 +366,36 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > > /* return EWOULDBLOCK since we know the wait isn't necessary */ > if (phys_enc->enable_state == DPU_ENC_DISABLED) { > - DRM_ERROR("encoder is disabled id=%u, callback=%ps, irq=%d\n", > + DRM_ERROR("encoder is disabled id=%u, callback=%ps, IRQ=[%d, > %d]\n", > DRMID(phys_enc->parent), func, > - irq); > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > return -EWOULDBLOCK; > } > > - if (irq < 0) { > + if (irq_idx < 0) { > DRM_DEBUG_KMS("skip irq wait id=%u, callback=%ps\n", > DRMID(phys_enc->parent), func); > return 0; > } > > - DRM_DEBUG_KMS("id=%u, callback=%ps, irq=%d, pp=%d, pending_cnt=%d\n", > + DRM_DEBUG_KMS("id=%u, callback=%ps, IRQ=[%d, %d], pp=%d, > pending_cnt=%d\n", > DRMID(phys_enc->parent), func, > - irq, phys_enc->hw_pp->idx - PINGPONG_0, > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > > ret = dpu_encoder_helper_wait_event_timeout( > DRMID(phys_enc->parent), > - irq, > + irq_idx, > wait_info); > > if (ret <= 0) { > - irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq); > + irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq_idx); > if (irq_status) { > unsigned long flags; > > - DRM_DEBUG_KMS("irq not triggered id=%u, callback=%ps, > irq=%d, pp=%d, atomic_cnt=%d\n", > + DRM_DEBUG_KMS("IRQ=[%d, %d] not triggered id=%u, > callback=%ps, pp=%d, atomic_cnt=%d\n", > + DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), > DRMID(phys_enc->parent), func, > - irq, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > local_irq_save(flags); > @@ -404,16 +404,16 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > ret = 0; > } else { > ret = -ETIMEDOUT; > - DRM_DEBUG_KMS("irq timeout id=%u, callback=%ps, irq=%d, > pp=%d, atomic_cnt=%d\n", > + DRM_DEBUG_KMS("IRQ=[%d, %d] timeout id=%u, > callback=%ps, pp=%d, atomic_cnt=%d\n", > + DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), > DRMID(phys_enc->parent), func, > - irq, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > } > } else { > ret = 0; > trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent), > - func, irq, > +
Re: [PATCH v5 1/8] drm/msm/dpu: fix the irq index in dpu_encoder_phys_wb_wait_for_commit_done
On 2023-08-02 13:04:19, Dmitry Baryshkov wrote: > Since commit 1e7ac595fa46 ("drm/msm/dpu: pass irq to > dpu_encoder_helper_wait_for_irq()") the > dpu_encoder_phys_wb_wait_for_commit_done expects the IRQ index rather > than the IRQ index in phys_enc->intr table, however writeback got the > older invocation in place. This was unnoticed for several releases, but > now it's time to fix it. > > Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for > writeback") > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > index a466ff70a4d6..78037a697633 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c > @@ -446,7 +446,8 @@ static int dpu_encoder_phys_wb_wait_for_commit_done( > wait_info.atomic_cnt = _enc->pending_kickoff_cnt; > wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; > > - ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_WB_DONE, > + ret = dpu_encoder_helper_wait_for_irq(phys_enc, > + phys_enc->irq[INTR_IDX_WB_DONE], > dpu_encoder_phys_wb_done_irq, _info); > if (ret == -ETIMEDOUT) > _dpu_encoder_phys_wb_handle_wbdone_timeout(phys_enc); > -- > 2.39.2 >
Re: [PATCH 2/2] drm/msm/dpu: Add SM7150 support
On 2023-08-03 22:47:24, Danila Tikhonov wrote: > Add definitions for the display hardware used on the Qualcomm SM7150 > platform. > > Signed-off-by: Danila Tikhonov > --- > .../msm/disp/dpu1/catalog/dpu_5_2_sm7150.h| 277 ++ > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 1 + > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 1 + > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 + > 4 files changed, 280 insertions(+) > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h > new file mode 100644 > index ..5823879a705a > --- /dev/null > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h > @@ -0,0 +1,277 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. > + * Copyright (c) 2023, Danila Tikhonov > + */ > + > +#ifndef _DPU_5_2_SM7150_H > +#define _DPU_5_2_SM7150_H > + > +static const struct dpu_caps sm7150_dpu_caps = { > + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, > + .max_mixer_blendstages = 0xb, > + .qseed_type = DPU_SSPP_SCALER_QSEED4, > + .has_src_split = true, > + .has_dim_layer = true, > + .has_idle_pc = true, > + .has_3d_merge = true, > + .max_linewidth = 4096, > + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > + .max_hdeci_exp = MAX_HORZ_DECIMATION, > + .max_vdeci_exp = MAX_VERT_DECIMATION, > +}; > + > +static const struct dpu_mdp_cfg sm7150_mdp[] = { > + { > + .name = "top_0", > + .base = 0x0, .len = 0x45c, > + .features = BIT(DPU_MDP_AUDIO_SELECT), > + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, > + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, > + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, > + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, > + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, > + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, This array can be written more concisely, as done in the other catalog files: .clk_ctrls = { [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, }, > + }, > +}; > + > +static const struct dpu_sspp_cfg sm7150_sspp[] = { > + { > + .name = "sspp_0", .id = SSPP_VIG0, > + .base = 0x4000, .len = 0x1f0, > + .features = VIG_SDM845_MASK, > + .sblk = _vig_sblk_0, > + .xin_id = 0, > + .type = SSPP_TYPE_VIG, > + .clk_ctrl = DPU_CLK_CTRL_VIG0, > + }, { > + .name = "sspp_1", .id = SSPP_VIG1, > + .base = 0x6000, .len = 0x1f0, > + .features = VIG_SDM845_MASK, > + .sblk = _vig_sblk_1, > + .xin_id = 4, > + .type = SSPP_TYPE_VIG, > + .clk_ctrl = DPU_CLK_CTRL_VIG1, > + }, { > + .name = "sspp_2", .id = SSPP_DMA0, > + .base = 0x24000, .len = 0x1f0, > + .features = DMA_SDM845_MASK, > + .sblk = _dma_sblk_0, > + .xin_id = 1, > + .type = SSPP_TYPE_DMA, > + .clk_ctrl = DPU_CLK_CTRL_DMA0, > + }, { > + .name = "sspp_9", .id = SSPP_DMA1, > + .base = 0x26000, .len = 0x1f0, > + .features = DMA_SDM845_MASK, > + .sblk = _dma_sblk_1, > + .xin_id = 5, > + .type = SSPP_TYPE_DMA, > + .clk_ctrl = DPU_CLK_CTRL_DMA1, > + }, { > + .name = "sspp_10", .id = SSPP_DMA2, > + .base = 0x28000, .len = 0x1f0, > + .features = DMA_CURSOR_SDM845_MASK, > + .sblk = _dma_sblk_2, > + .xin_id = 9, > + .type = SSPP_TYPE_DMA, > + .clk_ctrl = DPU_CLK_CTRL_DMA2, > + }, > +}; > + > +static const struct dpu_lm_cfg sm7150_lm[] = { > + { > + .name = "lm_0", .id = LM_0, > + .base = 0x44000, .len = 0x320, > + .features = MIXER_SDM845_MASK, > + .sblk = _lm_sblk, > + .lm_pair = LM_1, > + .pingpong = PINGPONG_0, > + .dspp = DSPP_0, > + }, { > + .name = "lm_1", .id = LM_1, > + .base = 0x45000, .len = 0x320, > + .features = MIXER_SDM845_MASK, > + .sblk = _lm_sblk, > + .lm_pair = LM_0, > + .pingpong = PINGPONG_1, > +
Re: [PATCH 1/2] dt-bindings: display/msm: document DPU on SM7150
On 2023-08-03 22:47:23, Danila Tikhonov wrote: > Document the DPU hardware found on the Qualcomm SM7150 platform. > > Signed-off-by: Danila Tikhonov > --- > .../bindings/display/msm/qcom,sm7150-dpu.yaml | 116 ++ > 1 file changed, 116 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/msm/qcom,sm7150-dpu.yaml > > diff --git > a/Documentation/devicetree/bindings/display/msm/qcom,sm7150-dpu.yaml > b/Documentation/devicetree/bindings/display/msm/qcom,sm7150-dpu.yaml > new file mode 100644 > index ..0d86997ae09f > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm7150-dpu.yaml > @@ -0,0 +1,116 @@ > +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/msm/qcom,sm7150-dpu.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Qualcomm SM7150 Display DPU > + > +maintainers: > + - Dmitry Baryshkov > + - Danila Tikhonov > + > +$ref: /schemas/display/msm/dpu-common.yaml# > + > +properties: > + compatible: > +const: qcom,sm7150-dpu > + > + reg: > +items: > + - description: Address offset and size for mdp register set > + - description: Address offset and size for vbif register set > + > + reg-names: > +items: > + - const: mdp > + - const: vbif > + > + clocks: > +items: > + - description: Display hf axi clock > + - description: Display ahb clock > + - description: Display rotator clock > + - description: Display lut clock > + - description: Display core clock > + - description: Display vsync clock > + > + clock-names: > +items: > + - const: bus > + - const: iface > + - const: rot > + - const: lut > + - const: core > + - const: vsync > + > +required: > + - compatible > + - reg > + - reg-names > + - clocks > + - clock-names > + > +unevaluatedProperties: false > + > +examples: > + - | > +#include > +#include > +#include > +#include > + > +display-controller@ae01000 { > +compatible = "qcom,sm7150-dpu"; > +reg = <0x0ae01000 0x8f000>, > + <0x0aeb 0x2008>; > +reg-names = "mdp", "vbif"; > + > +clocks = < GCC_DISP_HF_AXI_CLK>, > + < DISP_CC_MDSS_AHB_CLK>, > + < DISP_CC_MDSS_ROT_CLK>, > + < DISP_CC_MDSS_MDP_LUT_CLK>, > + < DISP_CC_MDSS_MDP_CLK>, > + < DISP_CC_MDSS_VSYNC_CLK>; > +clock-names = "bus", "iface", "rot", "lut", "core", > + "vsync"; > + > +assigned-clocks = < DISP_CC_MDSS_VSYNC_CLK>, > + < DISP_CC_MDSS_ROT_CLK>, > + < DISP_CC_MDSS_AHB_CLK>; > +assigned-clock-rates = <1920>, > + <1920>, > + <1920>; > + > +operating-points-v2 = <_opp_table>; > +power-domains = < SM7150_CX>; > + > +interrupt-parent = <>; > +interrupts = <0>; > + > +ports { > +#address-cells = <1>; > +#size-cells = <0>; > + > +port@0 { > +reg = <0>; > +endpoint { > +remote-endpoint = <_in>; > +}; > +}; > + > +port@1 { > +reg = <1>; > +endpoint { > +remote-endpoint = <_in>; > +}; I don't think this compiles with a missing closing bracket. Did you test the bindings? - Marijn > + > +port@2 { > +reg = <2>; > +endpoint { > +remote-endpoint = <_in>; > +}; > +}; > +}; > +}; > +... > -- > 2.41.0 >
Re: [PATCH v2 1/2] drm/msm/dpu: fix DSC 1.2 block lengths
On 2023-08-02 21:36:54, Dmitry Baryshkov wrote: > All DSC_BLK_1_2 declarations incorrectly pass 0x29c as the block length. > This includes the common block itself, enc subblocks and some empty > space around. Change that to pass 0x4 instead, the length of common > register block itself. > > Fixes: 0d1b10c63346 ("drm/msm/dpu: add DSC 1.2 hw blocks for relevant > chipsets") > Reported-by: Ryan McCann > Reviewed-by: Abhinav Kumar > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > > Changes since v1: > - Rebased on top of the catalog changes > > --- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 8 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 2 +- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 12 ++-- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 8 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 8 > 5 files changed, 19 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > index c906b6864b5e..f8d16f9bf528 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > @@ -283,22 +283,22 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] > = { > static const struct dpu_dsc_cfg sm8350_dsc[] = { > { > .name = "dce_0_0", .id = DSC_0, > - .base = 0x8, .len = 0x29c, > + .base = 0x8, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2), > .sblk = _sblk_0, > }, { > .name = "dce_0_1", .id = DSC_1, > - .base = 0x8, .len = 0x29c, > + .base = 0x8, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2), > .sblk = _sblk_1, > }, { > .name = "dce_1_0", .id = DSC_2, > - .base = 0x81000, .len = 0x29c, > + .base = 0x81000, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2) | > BIT(DPU_DSC_NATIVE_42x_EN), > .sblk = _sblk_0, > }, { > .name = "dce_1_1", .id = DSC_3, > - .base = 0x81000, .len = 0x29c, > + .base = 0x81000, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2) | > BIT(DPU_DSC_NATIVE_42x_EN), > .sblk = _sblk_1, > }, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > index 2bf9f34e54c6..3b5061c4402a 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > @@ -163,7 +163,7 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { > static const struct dpu_dsc_cfg sc7280_dsc[] = { > { > .name = "dce_0_0", .id = DSC_0, > - .base = 0x8, .len = 0x29c, > + .base = 0x8, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2) | > BIT(DPU_DSC_NATIVE_42x_EN), > .sblk = _sblk_0, > }, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > index ccd0477f4877..58f5e25679b1 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > @@ -286,32 +286,32 @@ static const struct dpu_merge_3d_cfg > sc8280xp_merge_3d[] = { > static const struct dpu_dsc_cfg sc8280xp_dsc[] = { > { > .name = "dce_0_0", .id = DSC_0, > - .base = 0x8, .len = 0x29c, > + .base = 0x8, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2), > .sblk = _sblk_0, > }, { > .name = "dce_0_1", .id = DSC_1, > - .base = 0x8, .len = 0x29c, > + .base = 0x8, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2), > .sblk = _sblk_1, > }, { > .name = "dce_1_0", .id = DSC_2, > - .base = 0x81000, .len = 0x29c, > + .base = 0x81000, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2) | > BIT(DPU_DSC_NATIVE_42x_EN), > .sblk = _sblk_0, > }, { > .name = "dce_1_1", .id = DSC_3, > - .base = 0x81000, .len = 0x29c, > + .base = 0x81000, .len = 0x4, > .features = BIT(DPU_DSC_HW_REV_1_2) | > BIT(DPU_DSC_NATIVE_42
Re: [PATCH v2 2/2] drm/msm/dpu: fix DSC 1.2 enc subblock length
On 2023-08-02 21:36:55, Dmitry Baryshkov wrote: > Both struct dpu_dsc_sub_blks instances declare enc subblock length to be > 0x100, while the actual length is 0x9c (last register having offset 0x98). > Reduce subblock length to remove the empty register space from being > dumped. > > Fixes: 0d1b10c63346 ("drm/msm/dpu: add DSC 1.2 hw blocks for relevant > chipsets") > Reviewed-by: Abhinav Kumar > Reviewed-by: Marijn Suijten > Signed-off-by: Dmitry Baryshkov > --- > > Changes since v1: > - Rebased on top of the catalog changes > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index 3ff07d7cbf4b..f1bac5e88249 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -456,12 +456,12 @@ static const struct dpu_pingpong_sub_blks > sc7280_pp_sblk = { > * DSC sub blocks config > */ > static const struct dpu_dsc_sub_blks dsc_sblk_0 = { > - .enc = {.name = "enc", .base = 0x100, .len = 0x100}, > + .enc = {.name = "enc", .base = 0x100, .len = 0x9c}, > .ctl = {.name = "ctl", .base = 0xF00, .len = 0x10}, For the time being only ctl register 0x00 and 0x04 is touched, DATA_IN_SWAP and CLK_CTRL at 0x08 and 0x0c are defined but not used, though it might still be useful to see their current value in the dump. - Marijn > }; > > static const struct dpu_dsc_sub_blks dsc_sblk_1 = { > - .enc = {.name = "enc", .base = 0x200, .len = 0x100}, > + .enc = {.name = "enc", .base = 0x200, .len = 0x9c}, > .ctl = {.name = "ctl", .base = 0xF80, .len = 0x10}, > }; > > -- > 2.39.2 >
Re: [PATCH v3 2/4] drm/msm/dpu: Enable widebus for DSI INTF
On 2023-08-02 11:08:49, Jessica Zhang wrote: > DPU supports a data-bus widen mode for DSI INTF. > > Enable this mode for all supported chipsets if widebus is enabled for DSI. > > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 3 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 + > drivers/gpu/drm/msm/msm_drv.h| 6 +- > 5 files changed, 20 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 3dcd37c48aac..de08aad39e15 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -1196,15 +1196,20 @@ static void dpu_encoder_virt_atomic_enable(struct > drm_encoder *drm_enc, > struct drm_display_mode *cur_mode = NULL; > struct msm_drm_private *priv = drm_enc->dev->dev_private; > struct msm_display_info *disp_info; > + int index; > > dpu_enc = to_dpu_encoder_virt(drm_enc); > disp_info = _enc->disp_info; > > + disp_info = _enc->disp_info; > + index = disp_info->h_tile_instance[0]; > + > dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc); > > - if (disp_info->intf_type == INTF_DP) > - dpu_enc->wide_bus_en = msm_dp_wide_bus_available( > - priv->dp[disp_info->h_tile_instance[0]]); > + if (disp_info->intf_type == INTF_DSI) > + dpu_enc->wide_bus_en = > msm_dsi_is_widebus_enabled(priv->dsi[index]); > + else if (disp_info->intf_type == INTF_DP) > + dpu_enc->wide_bus_en = > msm_dp_wide_bus_available(priv->dp[index]); This inconsistency really is killing. wide_bus vs widebus, and one function has an is_ while the other does not. > > mutex_lock(_enc->enc_lock); > cur_mode = _enc->base.crtc->state->adjusted_mode; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index df88358e7037..dace6168be2d 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > phys_enc->hw_intf, > phys_enc->hw_pp->idx); > > - if (intf_cfg.dsc != 0) > + if (intf_cfg.dsc != 0) { > cmd_mode_cfg.data_compress = true; > + cmd_mode_cfg.wide_bus_en = > dpu_encoder_is_widebus_enabled(phys_enc->parent); > + } > > if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) > phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, > _mode_cfg); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > index 8ec6505d9e78..dc6f3febb574 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > @@ -521,6 +521,9 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct > dpu_hw_intf *ctx, > if (cmd_mode_cfg->data_compress) > intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; > > + if (cmd_mode_cfg->wide_bus_en) > + intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; > + > DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); > } > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > index 77f80531782b..c539025c418b 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > @@ -50,6 +50,7 @@ struct dpu_hw_intf_status { > > struct dpu_hw_intf_cmd_mode_cfg { > u8 data_compress; /* enable data compress between dpu and dsi */ > + u8 wide_bus_en; /* enable databus widen mode */ Any clue why these weren't just bool types? These suffix-comments also aren't adhering to the kerneldoc format, or is there a different variant? > }; > > /** > diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h > index 9d9d5e009163..e4f706b16aad 100644 > --- a/drivers/gpu/drm/msm/msm_drv.h > +++ b/drivers/gpu/drm/msm/msm_drv.h > @@ -344,6 +344,7 @@ void msm_dsi_snapshot(struct msm_disp_state *disp_state, > struct msm_dsi *msm_dsi > bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi); > bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi); > bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi); > +bool msm_dsi_is_widebus_enabled(struct msm_dsi *msm_dsi); > struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi); > #else > static inline void __init msm_dsi_register(void) > @@ -373,7 +374,10 @@ static inline bool msm_dsi_is_master_dsi(struct msm_dsi > *msm_dsi) > { > return false; > } > - > +static inline bool
Re: [PATCH v3 1/4] drm/msm/dpu: Move DPU encoder wide_bus_en setting
I find this title very undescriptive, it doesn't really explain from/to where this move is happening nor why. On 2023-08-02 11:08:48, Jessica Zhang wrote: > Move the setting of dpu_enc.wide_bus_en to > dpu_encoder_virt_atomic_enable() so that it mirrors the setting of > dpu_enc.dsc. mirroring "the setting of dpu_enc.dsc" very much sounds like you are mirroring _its value_, but that is not the case. You are moving the initialization (or just setting, because it could also be overwriting?) to _the same place_ where .dsc is assigned. I am pretty sure that this has a runtime impact which we discussed before (hotplug...?) but the commit message omits that. This is mandatory. - Marijn > > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++ > 1 file changed, 7 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index d34e684a4178..3dcd37c48aac 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -1194,11 +1194,18 @@ static void dpu_encoder_virt_atomic_enable(struct > drm_encoder *drm_enc, > struct dpu_encoder_virt *dpu_enc = NULL; > int ret = 0; > struct drm_display_mode *cur_mode = NULL; > + struct msm_drm_private *priv = drm_enc->dev->dev_private; > + struct msm_display_info *disp_info; > > dpu_enc = to_dpu_encoder_virt(drm_enc); > + disp_info = _enc->disp_info; > > dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc); > > + if (disp_info->intf_type == INTF_DP) > + dpu_enc->wide_bus_en = msm_dp_wide_bus_available( > + priv->dp[disp_info->h_tile_instance[0]]); > + > mutex_lock(_enc->enc_lock); > cur_mode = _enc->base.crtc->state->adjusted_mode; > > @@ -2383,10 +2390,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device > *dev, > timer_setup(_enc->frame_done_timer, > dpu_encoder_frame_done_timeout, 0); > > - if (disp_info->intf_type == INTF_DP) > - dpu_enc->wide_bus_en = msm_dp_wide_bus_available( > - priv->dp[disp_info->h_tile_instance[0]]); > - > INIT_DELAYED_WORK(_enc->delayed_off_work, > dpu_encoder_off_work); > dpu_enc->idle_timeout = IDLE_TIMEOUT; > > -- > 2.41.0 >
Re: [PATCH v2 8/8] drm/msm/dpu: move INTF tearing checks to dpu_encoder_phys_cmd_init
On 2023-07-30 03:35:18, Dmitry Baryshkov wrote: > As the INTF is fixed at the encoder creation time, we can move the > check whether INTF supports tearchck to dpu_encoder_phys_cmd_init(). > This function can return an error if INTF doesn't have required feature. > Performing this check in dpu_encoder_phys_cmd_tearcheck_config() is less > useful, as this function returns void. > > Signed-off-by: Dmitry Baryshkov > --- > .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 41 +++ > 1 file changed, 25 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index 012986cff38c..adbd559a5290 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -325,24 +325,21 @@ static void dpu_encoder_phys_cmd_tearcheck_config( > unsigned long vsync_hz; > struct dpu_kms *dpu_kms; > > - if (phys_enc->has_intf_te) { > - if (!phys_enc->hw_intf || > - !phys_enc->hw_intf->ops.enable_tearcheck) { > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > - return; > - } > - > - DPU_DEBUG_CMDENC(cmd_enc, ""); > - } else { > - if (!phys_enc->hw_pp || > - !phys_enc->hw_pp->ops.enable_tearcheck) { > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > - return; > - } > - > - DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - > PINGPONG_0); > + /* > + * TODO: if/when resource allocation is refactored, move this to a > + * place where the driver can actually return an error. > + */ > + if (!phys_enc->has_intf_te && > + (!phys_enc->hw_pp || > + !phys_enc->hw_pp->ops.enable_tearcheck)) { We're probably overdoing it here if I request a WARN_ON when has_intf_te is true while enable_tearcheck is also non-NULL? > + DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > + return; > } > > + DPU_DEBUG_CMDENC(cmd_enc, "intf %d pp %d\n", > + phys_enc->hw_intf->idx - INTF_0, > + phys_enc->hw_pp->idx - PINGPONG_0); Note that hw_pp wasn't printed when has_intf_te is true. And it doesn't seem like that pointer is dereferenced anywhere in that case, perhaps hw_pp may even be NULL within dpu_encoder_phys_cmd_tearcheck_config() at some point. > + > mode = _enc->cached_mode; > > dpu_kms = phys_enc->dpu_kms; > @@ -768,10 +765,22 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( > phys_enc->intf_mode = INTF_MODE_CMD; > cmd_enc->stream_sel = 0; > > + if (!phys_enc->hw_intf) { > + DPU_ERROR_CMDENC(cmd_enc, "no INTF provided\n"); > + No need for this newline? > + return ERR_PTR(-EINVAL); > + } > + > /* DPU before 5.0 use PINGPONG for TE handling */ > if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5) > phys_enc->has_intf_te = true; > > + if (phys_enc->has_intf_te && !phys_enc->hw_intf->ops.enable_tearcheck) { > + DPU_ERROR_CMDENC(cmd_enc, "tearcheck not supported\n"); > + Same here? - Marijn > + return ERR_PTR(-EINVAL); > + } > + > atomic_set(_enc->pending_vblank_cnt, 0); > init_waitqueue_head(_enc->pending_vblank_wq); > > -- > 2.39.2 >
Re: [PATCH v2 2/8] drm/msm/dpu: enable PINGPONG TE operations only when supported by HW
On 2023-07-30 03:35:12, Dmitry Baryshkov wrote: > The DPU_PINGPONG_TE bit is set for all PINGPONG blocks on DPU < 5.0. > Rather than checking for the flag, check for the presense of the > corresponding interrupt line. > > Reviewed-by: Marijn Suijten This patch changed significantly since the last submission, but it is still to my liking so this r-b stays! - Marijn > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 6 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 3 ++- > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 2 +- > 3 files changed, 7 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > index 9298c166b213..057cac7f5d93 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > @@ -282,7 +282,7 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp) > } > > struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg > *cfg, > - void __iomem *addr) > + void __iomem *addr, const struct dpu_mdss_version *mdss_rev) > { > struct dpu_hw_pingpong *c; > > @@ -296,7 +296,9 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct > dpu_pingpong_cfg *cfg, > c->idx = cfg->id; > c->caps = cfg; > > - if (test_bit(DPU_PINGPONG_TE, >features)) { > + if (mdss_rev->core_major_ver < 5) { > + WARN_ON(!cfg->intr_rdptr); > + > c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h > index d3246a9a5808..0d541ca5b056 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h > @@ -123,10 +123,11 @@ static inline struct dpu_hw_pingpong > *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) > * pingpong catalog entry. > * @cfg: Pingpong catalog entry for which driver object is required > * @addr: Mapped register io address of MDP > + * @mdss_rev: dpu core's major and minor versions > * Return: Error code or allocated dpu_hw_pingpong context > */ > struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg > *cfg, > - void __iomem *addr); > + void __iomem *addr, const struct dpu_mdss_version *mdss_rev); > > /** > * dpu_hw_pingpong_destroy - destroys pingpong driver context > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > index 4a53e2c931d6..9894eea77b5f 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > @@ -145,7 +145,7 @@ int dpu_rm_init(struct dpu_rm *rm, > struct dpu_hw_pingpong *hw; > const struct dpu_pingpong_cfg *pp = >pingpong[i]; > > - hw = dpu_hw_pingpong_init(pp, mmio); > + hw = dpu_hw_pingpong_init(pp, mmio, cat->mdss_ver); > if (IS_ERR(hw)) { > rc = PTR_ERR(hw); > DPU_ERROR("failed pingpong object creation: err %d\n", > -- > 2.39.2 >
Re: [PATCH v2 1/8] drm/msm/dpu: inline _setup_pingpong_ops()
On 2023-07-30 03:35:11, Dmitry Baryshkov wrote: > Inline the _setup_pingpong_ops() function, it makes it easier to handle > different conditions involving PINGPONG configuration. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 39 --- > 1 file changed, 17 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > index 437d9e62a841..9298c166b213 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > @@ -281,27 +281,6 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong > *pp) > return 0; > } > > -static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, > - unsigned long features) > -{ > - if (test_bit(DPU_PINGPONG_TE, )) { > - c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > - c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > - c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > - c->ops.get_line_count = dpu_hw_pp_get_line_count; > - c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; > - } > - > - if (test_bit(DPU_PINGPONG_DSC, )) { > - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; > - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; > - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; > - } > - > - if (test_bit(DPU_PINGPONG_DITHER, )) > - c->ops.setup_dither = dpu_hw_pp_setup_dither; > -}; > - > struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg > *cfg, > void __iomem *addr) > { > @@ -316,7 +295,23 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const > struct dpu_pingpong_cfg *cfg, > > c->idx = cfg->id; > c->caps = cfg; > - _setup_pingpong_ops(c, c->caps->features); > + > + if (test_bit(DPU_PINGPONG_TE, >features)) { > + c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > + c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > + c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > + c->ops.get_line_count = dpu_hw_pp_get_line_count; > + c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; > + } > + > + if (test_bit(DPU_PINGPONG_DSC, >features)) { > + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; > + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; > + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; > + } > + > + if (test_bit(DPU_PINGPONG_DITHER, >features)) > + c->ops.setup_dither = dpu_hw_pp_setup_dither; > > return c; > } > -- > 2.39.2 >
Re: [PATCH v4 6/7] drm/msm/dpu: stop using raw IRQ indices in the kernel traces
On 2023-07-30 01:27:07, Dmitry Baryshkov wrote: > In preparation to reworking IRQ indcies, stop using raw indices in > kernel traces. Instead use a pair of register index and bit. This > corresponds closer to the values in HW catalog. > > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 8 +-- > drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 72 +++ > 3 files changed, 49 insertions(+), 37 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index b81daa415efb..126ad2707dba 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -413,7 +413,7 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > } else { > ret = 0; > trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent), > - func, irq_idx, > + func, DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > } > @@ -1554,7 +1554,9 @@ static int dpu_encoder_helper_wait_event_timeout( > atomic_read(info->atomic_cnt) == 0, jiffies); > time = ktime_to_ms(ktime_get()); > > - trace_dpu_enc_wait_event_timeout(drm_id, irq_idx, rc, time, > + trace_dpu_enc_wait_event_timeout(drm_id, > + DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), > + rc, time, >expected_time, >atomic_read(info->atomic_cnt)); > /* If we timed out, counter is valid and time is less, wait again */ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index b1592d73470d..04e5b889c6d6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -546,7 +546,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > return -EBUSY; > } > > - trace_dpu_core_irq_register_callback(irq_idx, irq_cb); > + trace_dpu_core_irq_register_callback(DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), irq_cb); > irq_entry->arg = irq_arg; > irq_entry->cb = irq_cb; > > @@ -558,7 +558,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > - trace_dpu_irq_register_success(irq_idx); > + trace_dpu_irq_register_success(DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx)); > > return 0; > } > @@ -579,7 +579,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) >DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > > spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags); > - trace_dpu_core_irq_unregister_callback(irq_idx); > + trace_dpu_core_irq_unregister_callback(DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx)); > > ret = dpu_hw_intr_disable_irq_locked(dpu_kms->hw_intr, irq_idx); > if (ret) > @@ -592,7 +592,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > - trace_dpu_irq_unregister_success(irq_idx); > + trace_dpu_irq_unregister_success(DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx)); > > return 0; > } > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h > index 1a92d21094f4..b64bd8eba26c 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h > @@ -168,46 +168,50 @@ TRACE_EVENT(dpu_perf_crtc_update, > ); > > DECLARE_EVENT_CLASS(dpu_irq_template, > - TP_PROTO(int irq_idx), > - TP_ARGS(irq_idx), > + TP_PROTO(unsigned int irq_reg, unsigned int irq_bit), > + TP_ARGS(irq_reg, irq_bit), > TP_STRUCT__entry( > - __field(int,irq_idx ) > + __field(unsigned int, irq_reg ) > + __field(unsigned int, irq_bit ) > ), > TP_fast_assign( > -
Re: [PATCH v4 5/7] drm/msm/dpu: stop using raw IRQ indices in the kernel output
On 2023-07-30 01:27:06, Dmitry Baryshkov wrote: > In preparation to reworking IRQ indcies, stop using raw indices in IRQ indices* > kernel output (both printk and debugfs). Instead use a pair of register > index and bit. This corresponds closer to the values in HW catalog. > > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 26 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 51 +++ > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 2 + > 3 files changed, 46 insertions(+), 33 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 051447a3620c..b81daa415efb 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -351,7 +351,7 @@ static int dpu_encoder_helper_wait_event_timeout(int32_t > drm_id, > u32 irq_idx, struct dpu_encoder_wait_info *info); > > int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, > - int irq, > + int irq_idx, > void (*func)(void *arg), > struct dpu_encoder_wait_info *wait_info) > { > @@ -366,36 +366,36 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > > /* return EWOULDBLOCK since we know the wait isn't necessary */ > if (phys_enc->enable_state == DPU_ENC_DISABLED) { > - DRM_ERROR("encoder is disabled id=%u, callback=%ps, irq=%d\n", > + DRM_ERROR("encoder is disabled id=%u, callback=%ps, IRQ: [%d, > %d]\n", > DRMID(phys_enc->parent), func, > - irq); > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > return -EWOULDBLOCK; > } > > - if (irq < 0) { > + if (irq_idx < 0) { > DRM_DEBUG_KMS("skip irq wait id=%u, callback=%ps\n", > DRMID(phys_enc->parent), func); > return 0; > } > > - DRM_DEBUG_KMS("id=%u, callback=%ps, irq=%d, pp=%d, pending_cnt=%d\n", > + DRM_DEBUG_KMS("id=%u, callback=%ps, IRQ: [%d, %d], pp=%d, > pending_cnt=%d\n", > DRMID(phys_enc->parent), func, > - irq, phys_enc->hw_pp->idx - PINGPONG_0, > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > > ret = dpu_encoder_helper_wait_event_timeout( > DRMID(phys_enc->parent), > - irq, > + irq_idx, > wait_info); > > if (ret <= 0) { > - irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq); > + irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq_idx); > if (irq_status) { > unsigned long flags; > > - DRM_DEBUG_KMS("irq not triggered id=%u, callback=%ps, > irq=%d, pp=%d, atomic_cnt=%d\n", > + DRM_DEBUG_KMS("IRQ [%d, %d] not triggered id=%u, > callback=%ps, pp=%d, atomic_cnt=%d\n", IRQ: (add colon), which you seem to have settled on? > + DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), > DRMID(phys_enc->parent), func, > - irq, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > local_irq_save(flags); > @@ -404,16 +404,16 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > ret = 0; > } else { > ret = -ETIMEDOUT; > - DRM_DEBUG_KMS("irq timeout id=%u, callback=%ps, irq=%d, > pp=%d, atomic_cnt=%d\n", > + DRM_DEBUG_KMS("IRQ: [%d, %d] timeout id=%u, > callback=%ps, pp=%d, atomic_cnt=%d\n", > + DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx), > DRMID(phys_enc->parent), func, > - irq, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > } > } else { > ret = 0; > trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent), > - func, irq, > + func, irq_idx, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > } > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 3d6d13407dde..b1592d73470d 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++
Re: [PATCH 4/7] drm/msm/dpu: enable INTF TE operations only when supported by HW
On 2023-07-30 03:22:46, Dmitry Baryshkov wrote: > On 27/07/2023 23:12, Marijn Suijten wrote: > > On 2023-07-27 19:21:01, Dmitry Baryshkov wrote: > >> The DPU_INTF_TE bit is set for all INTF blocks on DPU >= 5.0, however > >> only INTF_1 and INTF_2 actually support tearing control. Rather than > >> trying to fix the DPU_INTF_TE, check for the presense of the > > > > I would more exactly expand "fix" to "Rather than specifying that > > feature bit on DSI INTF_1 and INTF_2 exclusively..." > > > >> corresponding interrupt line. > > > > ... which the catalog will only provide on DPU >= 5.0. > > I'm going to rephrase this in a slightly different way to follow the irq > presence -> major & type change. Sure, looks good, including the validation (that doesn't really need to be mentioned in the commit message anymore). - Marijn
Re: [PATCH 7/7] drm/msm/dpu: move INTF tearing checks to dpu_encoder_phys_cmd_init
On 2023-07-30 03:16:59, Dmitry Baryshkov wrote: > >>> + if (!phys_enc->has_intf_te && > >>> + (!phys_enc->hw_pp || > >>> + !phys_enc->hw_pp->ops.enable_tearcheck)) { > >> > >> when is hw_pp assigned? Can't we also check that somewhere in an init > >> phase? > > > > It would happen right before dpu_encoder_phys_cmd_atomic_mode_set() > > where we already happen to check has_intf_te to switch on PP > > intr_readptr vs INTF intr_tear_rd_ptr. Might be the perfect place for > > the pingpong callback checks? > > The problem is that mode_set doesn't return an error (by design). I'd > put a TODO here, so that if we ever move/change resource allocation, > this check can be done next to it (atomic_check isn't a good place, > since phys_enc.atomic_check happens before resource reallocation). As thought of in another patch, perhaps it could just be a WARN_ON() as these almost always relate directly to constant information provided by the catalog, which we trust to be sound (and these error cases to hardly be reachable) after it has been validated, reviewed and merged. - Marijn
Re: [PATCH 1/7] drm/msm/dpu: enable PINGPONG TE operations only when supported by HW
On 2023-07-30 02:18:10, Dmitry Baryshkov wrote: > On 29/07/2023 21:31, Marijn Suijten wrote: > > On 2023-07-29 02:59:32, Dmitry Baryshkov wrote: > >> On 27/07/2023 23:03, Marijn Suijten wrote: > >>> On 2023-07-27 19:20:58, Dmitry Baryshkov wrote: > >>>> The DPU_PINGPONG_TE bit is set for all PINGPONG blocks on DPU < 5.0. > >>>> Rather than checking for the flag, check for the presense of the > >>>> corresponding interrupt line. > >>>> > >>>> Signed-off-by: Dmitry Baryshkov > >>> > >>> That's a smart use of the interrupt field. I both like it, and I do > >>> not. While we didn't do any validation for consistency previously, this > >>> means we now have multiple ways of controlling available "features": > >>> > >>> - Feature flags on hardware blocks; > >>> - Presence of certain IRQs; > >>> - DPU core revision. > >> > >> I hesitated here too. For INTF it is clear that there is no other good > >> way to check for the TE feature. For PP we can just check for the DPU > >> revision. > > > > For both we could additionally check the DPU revision, and for INTF we > > could check for TYPE_DSI. Both would aid in extra validation, if we > > require the IRQ to be present or absent under these conditions. > > Yep, maybe that's better. > > > > > It might also help to document this, either here and on the respective > > struct fields so that catalog implementers know when they should supply > > or leave out an IRQ? > > Probably a WARN_ON would be enough. SGTM, it is after all only for bring-up as after that (additions have been validated, reviewed and merged) we "trust the kernel" including our catalog, so errors like this should pretty much be unreachable. - Marijn
Re: [PATCH v3 5/6] drm/msm/dpu: stop using raw IRQ indices in the kernel output
On 2023-07-29 02:31:59, Dmitry Baryshkov wrote: > In preparation to reworking IRQ indcies, stop using raw indices in > kernel output (both printk and debugfs). Instead use a pair of register > index and bit. This corresponds closer to the values in HW catalog. > > Signed-off-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 49 --- > 1 file changed, 31 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 308b122059cd..6071d3f05b0c 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -199,6 +199,7 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > > #define DPU_IRQ_REG(irq_idx) (irq_idx / 32) > #define DPU_IRQ_MASK(irq_idx)(BIT(irq_idx % 32)) > +#define DPU_IRQ_BIT(irq_idx) (ffs(DPU_IRQ_MASK(irq_idx)) - 1) Another nit: I'd find it clearer to define DPU_IRQ_MASK in terms of DPU_IRQ_BIT[_INDEX...] than the other way around, because this is just irq_idx%32. - Marijn
Re: [PATCH v3 6/6] drm/msm/dpu: shift IRQ indices by 1
On 2023-07-29 02:32:00, Dmitry Baryshkov wrote: > In order to simplify IRQ declarations, shift IRQ indices by 1. This > makes 0 the 'no IRQ' value. Thanks to this change, we do no longer have > to explicitly set the 'no interrupt' fields in catalog structures. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten One nit all the way at the end. > --- > .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 4 -- > .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 4 -- > .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 8 > .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 10 - > .../msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 8 > .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 1 - > .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 - > .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 1 - > .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 8 > .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 6 --- > .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 13 -- > .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 12 -- > .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 12 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 6 +-- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 --- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 14 +++--- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 43 +++ > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 2 +- > 22 files changed, 36 insertions(+), 133 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > index 92530aec3bdc..b99bb323ec37 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > @@ -249,7 +249,6 @@ static const struct dpu_intf_cfg msm8998_intf[] = { > .prog_fetch_lines_worst_case = 21, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), > - .intr_tear_rd_ptr = -1, > }, { > .name = "intf_1", .id = INTF_1, > .base = 0x6a800, .len = 0x280, > @@ -258,7 +257,6 @@ static const struct dpu_intf_cfg msm8998_intf[] = { > .prog_fetch_lines_worst_case = 21, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - .intr_tear_rd_ptr = -1, > }, { > .name = "intf_2", .id = INTF_2, > .base = 0x6b000, .len = 0x280, > @@ -267,7 +265,6 @@ static const struct dpu_intf_cfg msm8998_intf[] = { > .prog_fetch_lines_worst_case = 21, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), > - .intr_tear_rd_ptr = -1, > }, { > .name = "intf_3", .id = INTF_3, > .base = 0x6b800, .len = 0x280, > @@ -275,7 +272,6 @@ static const struct dpu_intf_cfg msm8998_intf[] = { > .prog_fetch_lines_worst_case = 21, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31), > - .intr_tear_rd_ptr = -1, > }, > }; > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > index 3034c1b6ed90..ed30ea033da5 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > @@ -265,7 +265,6 @@ static const struct dpu_intf_cfg sdm845_intf[] = { > .prog_fetch_lines_worst_case = 24, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), > - .intr_tear_rd_ptr = -1, > }, { > .name = "intf_1", .id = INTF_1, > .base = 0x6a800, .len = 0x280, > @@ -274,7 +273,6 @@ static const struct dpu_intf_cfg sdm845_intf[] = { > .prog_fetch_lines_worst_case = 24, > .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - .intr_tear_rd_ptr = -1, > }, { > .name = "intf_2", .id = INTF_2, > .base = 0x6b000,
Re: [PATCH v3 5/6] drm/msm/dpu: stop using raw IRQ indices in the kernel output
Title suggestion: replace "stop using" with "Replace RAW IRQ indices in prints with tuple" or something else that describes what the new case is that we can expect after this PR was applied (at your discretion, it might be hard to fit that in 72 chars). Otherwise this reads as if you just dropped the index from printk's and systfs altogether. On 2023-07-29 02:31:59, Dmitry Baryshkov wrote: > In preparation to reworking IRQ indcies, stop using raw indices in > kernel output (both printk and debugfs). Instead use a pair of register > index and bit. This corresponds closer to the values in HW catalog. This is rather painful to read: irq=[%d, %d] IRQ:[%d, %d] IRQ: [%d, %d] IRQ [%d, %d] Four variations within the first **four** hunks. It looks like you tried to consistenize some of them, but can we please go all the way? Perhaps we also want to correct the format in dpu_trace.h? > > Signed-off-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 49 --- > 1 file changed, 31 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 308b122059cd..6071d3f05b0c 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -199,6 +199,7 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > > #define DPU_IRQ_REG(irq_idx) (irq_idx / 32) > #define DPU_IRQ_MASK(irq_idx)(BIT(irq_idx % 32)) > +#define DPU_IRQ_BIT(irq_idx) (ffs(DPU_IRQ_MASK(irq_idx)) - 1) > > static inline bool dpu_core_irq_is_valid(struct dpu_hw_intr *intr, >int irq_idx) > @@ -221,10 +222,11 @@ static void dpu_core_irq_callback_handler(struct > dpu_kms *dpu_kms, int irq_idx) > { > struct dpu_hw_intr_entry *irq_entry = > dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); > > - VERB("irq_idx=%d\n", irq_idx); > + VERB("irq=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > > if (!irq_entry->cb) > - DRM_ERROR("no registered cb, idx:%d\n", irq_idx); > + DRM_ERROR("no registered cb, IRQ:[%d, %d]\n", > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > > atomic_inc(_entry->count); > > @@ -306,7 +308,8 @@ static int dpu_hw_intr_enable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > return -EINVAL; > > if (!dpu_core_irq_is_valid(intr, irq_idx)) { > - pr_err("invalid IRQ index: [%d]\n", irq_idx); > + pr_err("invalid IRQ: [%d, %d]\n", > +DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > return -EINVAL; > } > > @@ -342,7 +345,8 @@ static int dpu_hw_intr_enable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > intr->cache_irq_mask[reg_idx] = cache_irq_mask; > } > > - pr_debug("DPU IRQ %d %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", > irq_idx, dbgstr, > + pr_debug("DPU IRQ [%d, %d] %senabled: MASK:0x%.8lx, > CACHE-MASK:0x%.8x\n", > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr, > DPU_IRQ_MASK(irq_idx), cache_irq_mask); > > return 0; > @@ -359,7 +363,8 @@ static int dpu_hw_intr_disable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > return -EINVAL; > > if (!dpu_core_irq_is_valid(intr, irq_idx)) { > - pr_err("invalid IRQ index: [%d]\n", irq_idx); > + pr_err("invalid IRQ: [%d, %d]\n", > +DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); > return -EINVAL; > } > > @@ -391,7 +396,8 @@ static int dpu_hw_intr_disable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > intr->cache_irq_mask[reg_idx] = cache_irq_mask; > } > > - pr_debug("DPU IRQ %d %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", > irq_idx, dbgstr, > + pr_debug("DPU IRQ [%d, %d] %sdisabled: MASK:0x%.8lx, > CACHE-MASK:0x%.8x\n", > + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr, > DPU_IRQ_MASK(irq_idx), cache_irq_mask); > > return 0; > @@ -444,7 +450,7 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int > irq_idx) > return 0; > > if (!dpu_core_irq_is_valid(intr, irq_idx)) { > - pr_err("invalid IRQ index: [%d]\n", irq_idx); > + pr_err("invalid IRQ: [%d, %d]\n", DPU_IRQ_REG(irq_idx), > DPU_IRQ_BIT(irq_idx)); > return 0; > } > > @@ -520,16 +526,19 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > int ret; > > if (!irq_cb) { > - DPU_ERROR("invalid ird_idx:%d irq_cb:%ps\n", irq_idx, irq_cb); > + DPU_ERROR("invalid ird_IRQ:[%d, %d] irq_cb:%ps\n", I think this was a typo that should have been irq_idx in the original code, so this just becomes IRQ (with one of the
Re: [PATCH v3 4/6] drm/msm/dpu: make the irq table size static
On 2023-07-29 02:31:58, Dmitry Baryshkov wrote: > The size of the irq table is static, it has MDP_INTR_MAX * 32 interrupt > entries. Provide the fixed length and drop struct_size() statement. Good call. I thought it was supposed to be allocated based on enabled interrupts (but then indexing becomes a big problem) to lighten the tables on platforms where the higher registers aren't even used, but it was always the constant MDP_INTR_MAX * 32. It's even better now that you removed all the 7xxx defines of which there were 11, times 32 interrupts, times sizeof(dpu_hw_intr_entry)=20 (or 24). > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 13 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 +++--- > 2 files changed, 8 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 14d374de30c5..308b122059cd 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -203,7 +203,7 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > static inline bool dpu_core_irq_is_valid(struct dpu_hw_intr *intr, Now you can drop the intr argument :) After fixing that: Reviewed-by: Marijn Suijten >int irq_idx) > { > - return irq_idx >= 0 && irq_idx < intr->total_irqs; > + return irq_idx >= 0 && irq_idx < DPU_NUM_IRQS; > } > > static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct > dpu_hw_intr *intr, > @@ -470,13 +470,12 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > const struct dpu_mdss_cfg *m) > { > struct dpu_hw_intr *intr; > - int nirq = MDP_INTR_MAX * 32; > unsigned int i; > > if (!addr || !m) > return ERR_PTR(-EINVAL); > > - intr = kzalloc(struct_size(intr, irq_tbl, nirq), GFP_KERNEL); > + intr = kzalloc(sizeof(*intr), GFP_KERNEL); > if (!intr) > return ERR_PTR(-ENOMEM); > > @@ -487,8 +486,6 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > > intr->hw.blk_addr = addr + m->mdp[0].base; > > - intr->total_irqs = nirq; > - > intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | >BIT(MDP_SSPP_TOP0_INTR2) | >BIT(MDP_SSPP_TOP0_HIST_INTR); > @@ -601,7 +598,7 @@ static int dpu_debugfs_core_irq_show(struct seq_file *s, > void *v) > int i, irq_count; > void *cb; > > - for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { > + for (i = 0; i < DPU_NUM_IRQS; i++) { > spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags); > irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); > irq_count = atomic_read(_entry->count); > @@ -636,7 +633,7 @@ void dpu_core_irq_preinstall(struct msm_kms *kms) > dpu_disable_all_irqs(dpu_kms); > pm_runtime_put_sync(_kms->pdev->dev); > > - for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { > + for (i = 0; i < DPU_NUM_IRQS; i++) { > irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); > atomic_set(_entry->count, 0); > } > @@ -652,7 +649,7 @@ void dpu_core_irq_uninstall(struct msm_kms *kms) > return; > > pm_runtime_get_sync(_kms->pdev->dev); > - for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { > + for (i = 0; i < DPU_NUM_IRQS; i++) { > irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i); > if (irq_entry->cb) > DPU_ERROR("irq_idx=%d still enabled/registered\n", i); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > index 391fb268ad90..bb775b6a2432 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > @@ -38,6 +38,8 @@ enum dpu_hw_intr_reg { > > #define DPU_IRQ_IDX(reg_idx, offset) (reg_idx * 32 + offset) > > +#define DPU_NUM_IRQS (MDP_INTR_MAX * 32) > + > struct dpu_hw_intr_entry { > void (*cb)(void *arg); > void *arg; > @@ -50,7 +52,6 @@ struct dpu_hw_intr_entry { > * @ops: function pointer mapping for IRQ handling > * @cache_irq_mask: array of IRQ enable masks reg storage created during > init > * @save_irq_status: array of IRQ status reg storage created during init > - * @total_irqs: total number of irq_idx mapped
Re: [PATCH v3 3/6] drm/msm/dpu: add helper to get IRQ-related data
On 2023-07-29 02:31:57, Dmitry Baryshkov wrote: > In preparation to reworking the IRQ indices, move irq_tbl access to > separate helper. Nit: "to _a_ separate helper" > > Reviewed-by: Marijn Suijten > Signed-off-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 48 +-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 12 +++-- > 2 files changed, 41 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 81d03b6c67d1..14d374de30c5 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -206,6 +206,12 @@ static inline bool dpu_core_irq_is_valid(struct > dpu_hw_intr *intr, > return irq_idx >= 0 && irq_idx < intr->total_irqs; > } > > +static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct > dpu_hw_intr *intr, > +int irq_idx) > +{ > + return >irq_tbl[irq_idx]; > +} > + > /** > * dpu_core_irq_callback_handler - dispatch core interrupts > * @dpu_kms: Pointer to DPU's KMS structure > @@ -213,17 +219,19 @@ static inline bool dpu_core_irq_is_valid(struct > dpu_hw_intr *intr, > */ > static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int > irq_idx) > { > + struct dpu_hw_intr_entry *irq_entry = > dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); > + > VERB("irq_idx=%d\n", irq_idx); > > - if (!dpu_kms->hw_intr->irq_tbl[irq_idx].cb) > + if (!irq_entry->cb) > DRM_ERROR("no registered cb, idx:%d\n", irq_idx); > > - atomic_inc(_kms->hw_intr->irq_tbl[irq_idx].count); > + atomic_inc(_entry->count); > > /* >* Perform registered function callback >*/ > - > dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg); > + irq_entry->cb(irq_entry->arg); > } > > irqreturn_t dpu_core_irq(struct msm_kms *kms) > @@ -510,6 +518,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > void (*irq_cb)(void *arg), > void *irq_arg) > { > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int ret; > > @@ -527,15 +536,16 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > > spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags); > > - if (unlikely(WARN_ON(dpu_kms->hw_intr->irq_tbl[irq_idx].cb))) { > + irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); > + if (unlikely(WARN_ON(irq_entry->cb))) { > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > return -EBUSY; > } > > trace_dpu_core_irq_register_callback(irq_idx, irq_cb); > - dpu_kms->hw_intr->irq_tbl[irq_idx].arg = irq_arg; > - dpu_kms->hw_intr->irq_tbl[irq_idx].cb = irq_cb; > + irq_entry->arg = irq_arg; > + irq_entry->cb = irq_cb; > > ret = dpu_hw_intr_enable_irq_locked( > dpu_kms->hw_intr, > @@ -552,6 +562,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > > int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx) > { > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int ret; > > @@ -570,8 +581,9 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > DPU_ERROR("Fail to disable IRQ for irq_idx:%d: %d\n", > irq_idx, ret); > > - dpu_kms->hw_intr->irq_tbl[irq_idx].cb = NULL; > - dpu_kms->hw_intr->irq_tbl[irq_idx].arg = NULL; > + irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx); > + irq_entry->cb = NULL; > + irq_entry->arg = NULL; > > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > @@ -584,14 +596,16 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) > { > struct dpu_kms *dpu_kms = s->private; > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int i, irq_count; > void *cb; > > for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { > spin_lock_irqsave(_kms->h
Re: [PATCH v3 2/6] drm/msm/dpu: extract dpu_core_irq_is_valid() helper
On 2023-07-29 02:31:56, Dmitry Baryshkov wrote: > In preparation to reworking the IRQ indices, move irq_idx validation to > the separate helper. Nit: "the" sounds as if "separate helper" is a thing that already exists, where you just moved it to. Instead, you created a new helper that now contains the validation that was open-coded before. > Signed-off-by: Dmitry Baryshkov For the contents though: Reviewed-by: Marijn Suijten > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 22 +-- > 1 file changed, 11 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 01a9ccfcd54b..81d03b6c67d1 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -200,6 +200,12 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > #define DPU_IRQ_REG(irq_idx) (irq_idx / 32) > #define DPU_IRQ_MASK(irq_idx)(BIT(irq_idx % 32)) > > +static inline bool dpu_core_irq_is_valid(struct dpu_hw_intr *intr, > + int irq_idx) > +{ > + return irq_idx >= 0 && irq_idx < intr->total_irqs; > +} > + > /** > * dpu_core_irq_callback_handler - dispatch core interrupts > * @dpu_kms: Pointer to DPU's KMS structure > @@ -291,7 +297,7 @@ static int dpu_hw_intr_enable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > if (!intr) > return -EINVAL; > > - if (irq_idx < 0 || irq_idx >= intr->total_irqs) { > + if (!dpu_core_irq_is_valid(intr, irq_idx)) { > pr_err("invalid IRQ index: [%d]\n", irq_idx); > return -EINVAL; > } > @@ -344,7 +350,7 @@ static int dpu_hw_intr_disable_irq_locked(struct > dpu_hw_intr *intr, int irq_idx) > if (!intr) > return -EINVAL; > > - if (irq_idx < 0 || irq_idx >= intr->total_irqs) { > + if (!dpu_core_irq_is_valid(intr, irq_idx)) { > pr_err("invalid IRQ index: [%d]\n", irq_idx); > return -EINVAL; > } > @@ -429,13 +435,7 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int > irq_idx) > if (!intr) > return 0; > > - if (irq_idx < 0) { > - DPU_ERROR("[%pS] invalid irq_idx=%d\n", > - __builtin_return_address(0), irq_idx); > - return 0; > - } > - > - if (irq_idx < 0 || irq_idx >= intr->total_irqs) { > + if (!dpu_core_irq_is_valid(intr, irq_idx)) { > pr_err("invalid IRQ index: [%d]\n", irq_idx); > return 0; > } > @@ -518,7 +518,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > return -EINVAL; > } > > - if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { > + if (!dpu_core_irq_is_valid(dpu_kms->hw_intr, irq_idx)) { > DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); > return -EINVAL; > } > @@ -555,7 +555,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > unsigned long irq_flags; > int ret; > > - if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { > + if (!dpu_core_irq_is_valid(dpu_kms->hw_intr, irq_idx)) { > DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); > return -EINVAL; > } > -- > 2.39.2 >
Re: [PATCH v2 4/4] drm/msm/dpu: shift IRQ indices by 1
On 2023-07-28 18:03:35, Dmitry Baryshkov wrote: > > > - if (irq_idx < 0 || irq_idx >= intr->total_irqs) { > > > + if (!irq_idx || irq_idx > intr->total_irqs) { > > > pr_err("invalid IRQ index: [%d]\n", irq_idx); > > > > Logs like this might be harder to interpret (and compare) when the > > numbering is different. In addition, all the IRQs in > > /d/dri/0/debug/core_irq are shifted up by 1 making them harder to > > compare to downstream. > > (Which I hope to not have to do again for a while, now that my INTF TE > > series is finalized and merged) > > I hesitated here. Maybe we should log the register and index instead > of logging the raw index. Sure that might help. > As for the core_irq vs downstream, that's a good question. I don't > like the idea of adding -1 there. Maybe I'll change that again to > register + index. I don't like that either. It also isn't a given that the numbers will always match up, as they're a software/kernel construct for bookkeeping purposes and not a hardware index. In other words, it only matches when enum dpu_hw_intr_reg is in sync with downstream. And I don't think it still is (in the higher numbers) now that 7xxx variants have been culled. Preferably both downstream and upstream should have a named "interrupt register" together with the bit index, but again it's not something that's super critical nor used often. - Marijn
Re: [PATCH 1/7] drm/msm/dpu: enable PINGPONG TE operations only when supported by HW
On 2023-07-29 02:59:32, Dmitry Baryshkov wrote: > On 27/07/2023 23:03, Marijn Suijten wrote: > > On 2023-07-27 19:20:58, Dmitry Baryshkov wrote: > >> The DPU_PINGPONG_TE bit is set for all PINGPONG blocks on DPU < 5.0. > >> Rather than checking for the flag, check for the presense of the > >> corresponding interrupt line. > >> > >> Signed-off-by: Dmitry Baryshkov > > > > That's a smart use of the interrupt field. I both like it, and I do > > not. While we didn't do any validation for consistency previously, this > > means we now have multiple ways of controlling available "features": > > > > - Feature flags on hardware blocks; > > - Presence of certain IRQs; > > - DPU core revision. > > I hesitated here too. For INTF it is clear that there is no other good > way to check for the TE feature. For PP we can just check for the DPU > revision. For both we could additionally check the DPU revision, and for INTF we could check for TYPE_DSI. Both would aid in extra validation, if we require the IRQ to be present or absent under these conditions. It might also help to document this, either here and on the respective struct fields so that catalog implementers know when they should supply or leave out an IRQ? - Marijn > > Maybe that is more confusing to follow? Regardless of that I'm > > convinced that this patch does what it's supposed to and gets rid of > > some ambiguity. Maybe a comment above the IF explaining the "PP TE" > > feature could alleviate the above concerns thoo. Hence: > > > > Reviewed-by: Marijn Suijten > > > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > >> index 9298c166b213..912a3bdf8ad4 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > >> @@ -296,7 +296,7 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const > >> struct dpu_pingpong_cfg *cfg, > >>c->idx = cfg->id; > >>c->caps = cfg; > >> > >> - if (test_bit(DPU_PINGPONG_TE, >features)) { > >> + if (cfg->intr_rdptr) { > >>c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > >>c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > >>c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > >> -- > >> 2.39.2 > >> > > -- > With best wishes > Dmitry >
Re: [PATCH 3/7] drm/msm/dpu: inline _setup_intf_ops()
On 2023-07-29 02:45:43, Dmitry Baryshkov wrote: > On 27/07/2023 23:10, Marijn Suijten wrote: > > On 2023-07-27 19:21:00, Dmitry Baryshkov wrote: > >> Inline the _setup_intf_ops() function, it makes it easier to handle > >> different conditions involving INTF configuration. > >> > >> Signed-off-by: Dmitry Baryshkov > > > > Reviewed-by: Marijn Suijten > > > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 47 + > >> 1 file changed, 21 insertions(+), 26 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > >> index 8ec6505d9e78..7ca772791a73 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > >> @@ -524,31 +524,6 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct > >> dpu_hw_intf *ctx, > >>DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); > >> } > >> > >> -static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > >> - unsigned long cap, const struct dpu_mdss_version *mdss_rev) > >> -{ > >> - ops->setup_timing_gen = dpu_hw_intf_setup_timing_engine; > >> - ops->setup_prg_fetch = dpu_hw_intf_setup_prg_fetch; > >> - ops->get_status = dpu_hw_intf_get_status; > >> - ops->enable_timing = dpu_hw_intf_enable_timing_engine; > >> - ops->get_line_count = dpu_hw_intf_get_line_count; > >> - if (cap & BIT(DPU_INTF_INPUT_CTRL)) > >> - ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; > >> - ops->setup_misr = dpu_hw_intf_setup_misr; > >> - ops->collect_misr = dpu_hw_intf_collect_misr; > >> - > >> - if (cap & BIT(DPU_INTF_TE)) { > >> - ops->enable_tearcheck = dpu_hw_intf_enable_te; > >> - ops->disable_tearcheck = dpu_hw_intf_disable_te; > >> - ops->connect_external_te = dpu_hw_intf_connect_external_te; > >> - ops->vsync_sel = dpu_hw_intf_vsync_sel; > >> - ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; > >> - } > >> - > >> - if (mdss_rev->core_major_ver >= 7) > >> - ops->program_intf_cmd_cfg = dpu_hw_intf_program_intf_cmd_cfg; > >> -} > >> - > >> struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, > >>void __iomem *addr, const struct dpu_mdss_version *mdss_rev) > >> { > >> @@ -571,7 +546,27 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct > >> dpu_intf_cfg *cfg, > >> */ > >>c->idx = cfg->id; > >>c->cap = cfg; > >> - _setup_intf_ops(>ops, c->cap->features, mdss_rev); > >> + > >> + c->ops.setup_timing_gen = dpu_hw_intf_setup_timing_engine; > >> + c->ops.setup_prg_fetch = dpu_hw_intf_setup_prg_fetch; > >> + c->ops.get_status = dpu_hw_intf_get_status; > >> + c->ops.enable_timing = dpu_hw_intf_enable_timing_engine; > >> + c->ops.get_line_count = dpu_hw_intf_get_line_count; > >> + if (cfg->features & BIT(DPU_INTF_INPUT_CTRL)) > >> + c->ops.bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; > > > > While at it, could we sort these down with the other conditional > > callbacks? > > What kind of sorting do you have in mind? Moving this conditional ( if (...) ) down with the other conditional assignment below, instead of being right in the middle of get_line_count and setup_misr, both which are not conditional and make it harder to read, especially considering the lack of newlines and/or curly braces. > >> + c->ops.setup_misr = dpu_hw_intf_setup_misr; > >> + c->ops.collect_misr = dpu_hw_intf_collect_misr; > >> + > >> + if (cfg->features & BIT(DPU_INTF_TE)) { > > > > Any clue why we're not using test_bit()? Feels a bit inconsistent. > > Yes, some files use test_bit(), others just check the bit directly. > Maybe after moving some/most of conditionals to core_major_ver we can > clean that too. Sounds good. - Marijn > >> + c->ops.enable_tearcheck = dpu_hw_intf_enable_te; > >> + c->ops.disable_tearcheck = dpu_hw_intf_disable_te; > >> + c->ops.connect_external_te = dpu_hw_intf_connect_external_te; > >> + c->ops.vsync_sel = dpu_hw_intf_vsync_sel; > >> + c->ops.disable_autorefresh = dpu_hw_intf_disable_autorefresh; > >> + } > >> + > >> + if (mdss_rev->core_major_ver >= 7) > >> + c->ops.program_intf_cmd_cfg = dpu_hw_intf_program_intf_cmd_cfg; > >> > >>return c; > >> } > >> -- > >> 2.39.2 > >> > > -- > With best wishes > Dmitry >
Re: [PATCH 7/7] drm/msm/dpu: move INTF tearing checks to dpu_encoder_phys_cmd_init
On 2023-07-27 22:22:20, Marijn Suijten wrote: > On 2023-07-27 19:21:04, Dmitry Baryshkov wrote: > > As the INTF is fixed at the encoder creation time, we can move the > > check whether INTF supports tearchck to dpu_encoder_phys_cmd_init(). > > This function can return an error if INTF doesn't have required feature. > > Performing this check in dpu_encoder_phys_cmd_tearcheck_config() is less > > useful, as this function returns void. > > > > Signed-off-by: Dmitry Baryshkov > > --- > > .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 37 +++ > > 1 file changed, 21 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > index 04a1106101a7..e1dd0e1b4793 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > @@ -325,24 +325,17 @@ static void dpu_encoder_phys_cmd_tearcheck_config( > > unsigned long vsync_hz; > > struct dpu_kms *dpu_kms; > > > > - if (phys_enc->has_intf_te) { > > - if (!phys_enc->hw_intf || > > - !phys_enc->hw_intf->ops.enable_tearcheck) { > > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > > - return; > > - } > > - > > - DPU_DEBUG_CMDENC(cmd_enc, ""); > > - } else { > > - if (!phys_enc->hw_pp || > > - !phys_enc->hw_pp->ops.enable_tearcheck) { > > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > > - return; > > - } > > - > > - DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - > > PINGPONG_0); > > + if (!phys_enc->has_intf_te && > > + (!phys_enc->hw_pp || > > +!phys_enc->hw_pp->ops.enable_tearcheck)) { > > when is hw_pp assigned? Can't we also check that somewhere in an init > phase? It would happen right before dpu_encoder_phys_cmd_atomic_mode_set() where we already happen to check has_intf_te to switch on PP intr_readptr vs INTF intr_tear_rd_ptr. Might be the perfect place for the pingpong callback checks? - Marijn > > Also, you won't go over 100 chars (not even 80) by having the (!... || > !...) on a single line. > > > + DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > > + return; > > } > > > > + DPU_DEBUG_CMDENC(cmd_enc, "intf %d pp %d\n", > > +phys_enc->hw_intf->idx - INTF_0, > > +phys_enc->hw_pp->idx - PINGPONG_0); > > + > > mode = _enc->cached_mode; > > > > dpu_kms = phys_enc->dpu_kms; > > @@ -768,9 +761,21 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( > > phys_enc->intf_mode = INTF_MODE_CMD; > > cmd_enc->stream_sel = 0; > > > > + if (!phys_enc->hw_intf) { > > + DPU_ERROR_CMDENC(cmd_enc, "no INTF provided\n"); > > + > > + return ERR_PTR(-EINVAL); > > + } > > + > > if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5) > > phys_enc->has_intf_te = true; > > > > + if (phys_enc->has_intf_te && !phys_enc->hw_intf->ops.enable_tearcheck) { > > Any other callbacks we could check here, and remove the checks > elsewhere? > > As with enable_tearcheck() though, it does make the code less consistent > with its PP counterpart, which is checked ad-hoc everywhere (but maybe > that is fixable too). > > - Marijn > > > + DPU_ERROR_CMDENC(cmd_enc, "tearcheck not supported\n"); > > + > > + return ERR_PTR(-EINVAL); > > + } > > + > > atomic_set(_enc->pending_vblank_cnt, 0); > > init_waitqueue_head(_enc->pending_vblank_wq); > > > > -- > > 2.39.2 > >
Re: [PATCH 5/7] drm/msm/dpu: drop DPU_INTF_TE feature flag
On 2023-07-27 23:16:22, Dmitry Baryshkov wrote: > On 27/07/2023 23:14, Marijn Suijten wrote: > > On 2023-07-27 19:21:02, Dmitry Baryshkov wrote: > >> Replace the only user of the DPU_INTF_TE feature flag with the direct > >> DPU version comparison. > >> > >> Signed-off-by: Dmitry Baryshkov > > > > Reviewed-by: Marijn Suijten > > > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 ++-- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 - > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 -- > >> 3 files changed, 2 insertions(+), 5 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> index 9589fe719452..60d4dd88725e 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> @@ -776,8 +776,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( > >>phys_enc->intf_mode = INTF_MODE_CMD; > >>cmd_enc->stream_sel = 0; > >> > >> - phys_enc->has_intf_te = test_bit(DPU_INTF_TE, > >> - _enc->hw_intf->cap->features); > >> + if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5) > >> + phys_enc->has_intf_te = true; > > > > We could also check if the INTF block has the callbacks (which it based > > on the presence of the interrupt line in the catalog instead), but then > > I think we might loose some extra validation which you tidied up in a > > later patch in this series? > > Almost. The logic was the following: we should be using INTF for DPU >= > 5.0. And if we have DPU >= 5.0 and no callbacks, it's an error. Indeed. Let's keep that validation just in case. - Marijn
Re: [PATCH 7/7] drm/msm/dpu: move INTF tearing checks to dpu_encoder_phys_cmd_init
On 2023-07-27 19:21:04, Dmitry Baryshkov wrote: > As the INTF is fixed at the encoder creation time, we can move the > check whether INTF supports tearchck to dpu_encoder_phys_cmd_init(). > This function can return an error if INTF doesn't have required feature. > Performing this check in dpu_encoder_phys_cmd_tearcheck_config() is less > useful, as this function returns void. > > Signed-off-by: Dmitry Baryshkov > --- > .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 37 +++ > 1 file changed, 21 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index 04a1106101a7..e1dd0e1b4793 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -325,24 +325,17 @@ static void dpu_encoder_phys_cmd_tearcheck_config( > unsigned long vsync_hz; > struct dpu_kms *dpu_kms; > > - if (phys_enc->has_intf_te) { > - if (!phys_enc->hw_intf || > - !phys_enc->hw_intf->ops.enable_tearcheck) { > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > - return; > - } > - > - DPU_DEBUG_CMDENC(cmd_enc, ""); > - } else { > - if (!phys_enc->hw_pp || > - !phys_enc->hw_pp->ops.enable_tearcheck) { > - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > - return; > - } > - > - DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - > PINGPONG_0); > + if (!phys_enc->has_intf_te && > + (!phys_enc->hw_pp || > + !phys_enc->hw_pp->ops.enable_tearcheck)) { when is hw_pp assigned? Can't we also check that somewhere in an init phase? Also, you won't go over 100 chars (not even 80) by having the (!... || !...) on a single line. > + DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); > + return; > } > > + DPU_DEBUG_CMDENC(cmd_enc, "intf %d pp %d\n", > + phys_enc->hw_intf->idx - INTF_0, > + phys_enc->hw_pp->idx - PINGPONG_0); > + > mode = _enc->cached_mode; > > dpu_kms = phys_enc->dpu_kms; > @@ -768,9 +761,21 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( > phys_enc->intf_mode = INTF_MODE_CMD; > cmd_enc->stream_sel = 0; > > + if (!phys_enc->hw_intf) { > + DPU_ERROR_CMDENC(cmd_enc, "no INTF provided\n"); > + > + return ERR_PTR(-EINVAL); > + } > + > if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5) > phys_enc->has_intf_te = true; > > + if (phys_enc->has_intf_te && !phys_enc->hw_intf->ops.enable_tearcheck) { Any other callbacks we could check here, and remove the checks elsewhere? As with enable_tearcheck() though, it does make the code less consistent with its PP counterpart, which is checked ad-hoc everywhere (but maybe that is fixable too). - Marijn > + DPU_ERROR_CMDENC(cmd_enc, "tearcheck not supported\n"); > + > + return ERR_PTR(-EINVAL); > + } > + > atomic_set(_enc->pending_vblank_cnt, 0); > init_waitqueue_head(_enc->pending_vblank_wq); > > -- > 2.39.2 >
Re: [PATCH 6/7] drm/msm/dpu: drop useless check from dpu_encoder_phys_cmd_te_rd_ptr_irq()
On 2023-07-27 19:21:03, Dmitry Baryshkov wrote: > The dpu_encoder_phys_cmd_te_rd_ptr_irq() function uses neither hw_intf > nor hw_pp data, so we can drop the corresponding check. Maybe because it would catch "bogus" interrupts, or these blocks are accessed somewhere down the line in the vblank callback chain? I have no clue :) > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 8 > 1 file changed, 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index 60d4dd88725e..04a1106101a7 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -108,14 +108,6 @@ static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg) > struct dpu_encoder_phys *phys_enc = arg; > struct dpu_encoder_phys_cmd *cmd_enc; > > - if (phys_enc->has_intf_te) { > - if (!phys_enc->hw_intf) > - return; > - } else { > - if (!phys_enc->hw_pp) > - return; > - } > - > DPU_ATRACE_BEGIN("rd_ptr_irq"); > cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); > > -- > 2.39.2 >
Re: [PATCH 5/7] drm/msm/dpu: drop DPU_INTF_TE feature flag
On 2023-07-27 19:21:02, Dmitry Baryshkov wrote: > Replace the only user of the DPU_INTF_TE feature flag with the direct > DPU version comparison. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 - > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 -- > 3 files changed, 2 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index 9589fe719452..60d4dd88725e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -776,8 +776,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( > phys_enc->intf_mode = INTF_MODE_CMD; > cmd_enc->stream_sel = 0; > > - phys_enc->has_intf_te = test_bit(DPU_INTF_TE, > - _enc->hw_intf->cap->features); > + if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5) > + phys_enc->has_intf_te = true; We could also check if the INTF block has the callbacks (which it based on the presence of the interrupt line in the catalog instead), but then I think we might loose some extra validation which you tidied up in a later patch in this series? > > atomic_set(_enc->pending_vblank_cnt, 0); > init_waitqueue_head(_enc->pending_vblank_wq); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index c19dc70d4456..17426f0f981e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -100,7 +100,6 @@ > > #define INTF_SC7180_MASK \ > (BIT(DPU_INTF_INPUT_CTRL) | \ > - BIT(DPU_INTF_TE) | \ >BIT(DPU_INTF_STATUS_SUPPORTED) | \ >BIT(DPU_DATA_HCTL_EN)) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index a6f8eee58b92..69c9099cf5a6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -175,7 +175,6 @@ enum { > * INTF sub-blocks > * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from > which > * pixel data arrives to this INTF > - * @DPU_INTF_TE INTF block has TE configuration support > * @DPU_DATA_HCTL_ENAllows data to be transferred at > different rate > * than video timing > * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register > @@ -183,7 +182,6 @@ enum { > */ > enum { > DPU_INTF_INPUT_CTRL = 0x1, > - DPU_INTF_TE, > DPU_DATA_HCTL_EN, > DPU_INTF_STATUS_SUPPORTED, > DPU_INTF_MAX > -- > 2.39.2 >
Re: [PATCH 4/7] drm/msm/dpu: enable INTF TE operations only when supported by HW
On 2023-07-27 19:21:01, Dmitry Baryshkov wrote: > The DPU_INTF_TE bit is set for all INTF blocks on DPU >= 5.0, however > only INTF_1 and INTF_2 actually support tearing control. Rather than > trying to fix the DPU_INTF_TE, check for the presense of the I would more exactly expand "fix" to "Rather than specifying that feature bit on DSI INTF_1 and INTF_2 exclusively..." > corresponding interrupt line. ... which the catalog will only provide on DPU >= 5.0. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > index 7ca772791a73..8abdf9553f3b 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > @@ -557,7 +557,7 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct > dpu_intf_cfg *cfg, > c->ops.setup_misr = dpu_hw_intf_setup_misr; > c->ops.collect_misr = dpu_hw_intf_collect_misr; > > - if (cfg->features & BIT(DPU_INTF_TE)) { > + if (cfg->intr_tear_rd_ptr) { > c->ops.enable_tearcheck = dpu_hw_intf_enable_te; > c->ops.disable_tearcheck = dpu_hw_intf_disable_te; > c->ops.connect_external_te = dpu_hw_intf_connect_external_te; > -- > 2.39.2 >
Re: [PATCH 3/7] drm/msm/dpu: inline _setup_intf_ops()
On 2023-07-27 19:21:00, Dmitry Baryshkov wrote: > Inline the _setup_intf_ops() function, it makes it easier to handle > different conditions involving INTF configuration. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 47 + > 1 file changed, 21 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > index 8ec6505d9e78..7ca772791a73 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > @@ -524,31 +524,6 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct > dpu_hw_intf *ctx, > DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); > } > > -static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > - unsigned long cap, const struct dpu_mdss_version *mdss_rev) > -{ > - ops->setup_timing_gen = dpu_hw_intf_setup_timing_engine; > - ops->setup_prg_fetch = dpu_hw_intf_setup_prg_fetch; > - ops->get_status = dpu_hw_intf_get_status; > - ops->enable_timing = dpu_hw_intf_enable_timing_engine; > - ops->get_line_count = dpu_hw_intf_get_line_count; > - if (cap & BIT(DPU_INTF_INPUT_CTRL)) > - ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; > - ops->setup_misr = dpu_hw_intf_setup_misr; > - ops->collect_misr = dpu_hw_intf_collect_misr; > - > - if (cap & BIT(DPU_INTF_TE)) { > - ops->enable_tearcheck = dpu_hw_intf_enable_te; > - ops->disable_tearcheck = dpu_hw_intf_disable_te; > - ops->connect_external_te = dpu_hw_intf_connect_external_te; > - ops->vsync_sel = dpu_hw_intf_vsync_sel; > - ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; > - } > - > - if (mdss_rev->core_major_ver >= 7) > - ops->program_intf_cmd_cfg = dpu_hw_intf_program_intf_cmd_cfg; > -} > - > struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, > void __iomem *addr, const struct dpu_mdss_version *mdss_rev) > { > @@ -571,7 +546,27 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct > dpu_intf_cfg *cfg, >*/ > c->idx = cfg->id; > c->cap = cfg; > - _setup_intf_ops(>ops, c->cap->features, mdss_rev); > + > + c->ops.setup_timing_gen = dpu_hw_intf_setup_timing_engine; > + c->ops.setup_prg_fetch = dpu_hw_intf_setup_prg_fetch; > + c->ops.get_status = dpu_hw_intf_get_status; > + c->ops.enable_timing = dpu_hw_intf_enable_timing_engine; > + c->ops.get_line_count = dpu_hw_intf_get_line_count; > + if (cfg->features & BIT(DPU_INTF_INPUT_CTRL)) > + c->ops.bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; While at it, could we sort these down with the other conditional callbacks? > + c->ops.setup_misr = dpu_hw_intf_setup_misr; > + c->ops.collect_misr = dpu_hw_intf_collect_misr; > + > + if (cfg->features & BIT(DPU_INTF_TE)) { Any clue why we're not using test_bit()? Feels a bit inconsistent. > + c->ops.enable_tearcheck = dpu_hw_intf_enable_te; > + c->ops.disable_tearcheck = dpu_hw_intf_disable_te; > + c->ops.connect_external_te = dpu_hw_intf_connect_external_te; > + c->ops.vsync_sel = dpu_hw_intf_vsync_sel; > + c->ops.disable_autorefresh = dpu_hw_intf_disable_autorefresh; > + } > + > + if (mdss_rev->core_major_ver >= 7) > + c->ops.program_intf_cmd_cfg = dpu_hw_intf_program_intf_cmd_cfg; > > return c; > } > -- > 2.39.2 >
Re: [PATCH 2/7] drm/msm/dpu: drop the DPU_PINGPONG_TE flag
On 2023-07-27 19:20:59, Dmitry Baryshkov wrote: > The DPU_PINGPONG_TE flag became unused, we can drop it now. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +--- > 2 files changed, 2 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index 3ff07d7cbf4b..c19dc70d4456 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -79,7 +79,7 @@ > (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) > > #define PINGPONG_SDM845_MASK \ > - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | > BIT(DPU_PINGPONG_DSC)) > + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) > > #define PINGPONG_SDM845_TE2_MASK \ > (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 945b88c5ab58..a6f8eee58b92 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -136,7 +136,6 @@ enum { > > /** > * PINGPONG sub-blocks > - * @DPU_PINGPONG_TE Tear check block > * @DPU_PINGPONG_TE2Additional tear check block for split pipes > * @DPU_PINGPONG_SPLIT PP block supports split fifo > * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo > @@ -145,8 +144,7 @@ enum { > * @DPU_PINGPONG_MAX > */ > enum { > - DPU_PINGPONG_TE = 0x1, > - DPU_PINGPONG_TE2, > + DPU_PINGPONG_TE2 = 0x1, > DPU_PINGPONG_SPLIT, > DPU_PINGPONG_SLAVE, > DPU_PINGPONG_DITHER, > -- > 2.39.2 >
Re: [PATCH 1/7] drm/msm/dpu: enable PINGPONG TE operations only when supported by HW
On 2023-07-27 19:20:58, Dmitry Baryshkov wrote: > The DPU_PINGPONG_TE bit is set for all PINGPONG blocks on DPU < 5.0. > Rather than checking for the flag, check for the presense of the > corresponding interrupt line. > > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > index 9298c166b213..912a3bdf8ad4 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > @@ -296,7 +296,7 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct > dpu_pingpong_cfg *cfg, > c->idx = cfg->id; > c->caps = cfg; In hindsight, maybe there's one patch missing from this series. You inlined _setup_intf_ops() later, but there's no patch inlining _setup_pingpong_ops() which looks to be required for applying this patch. - Marijn > > - if (test_bit(DPU_PINGPONG_TE, >features)) { > + if (cfg->intr_rdptr) { > c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > -- > 2.39.2 >
Re: [PATCH 1/7] drm/msm/dpu: enable PINGPONG TE operations only when supported by HW
On 2023-07-27 19:20:58, Dmitry Baryshkov wrote: > The DPU_PINGPONG_TE bit is set for all PINGPONG blocks on DPU < 5.0. > Rather than checking for the flag, check for the presense of the > corresponding interrupt line. > > Signed-off-by: Dmitry Baryshkov That's a smart use of the interrupt field. I both like it, and I do not. While we didn't do any validation for consistency previously, this means we now have multiple ways of controlling available "features": - Feature flags on hardware blocks; - Presence of certain IRQs; - DPU core revision. Maybe that is more confusing to follow? Regardless of that I'm convinced that this patch does what it's supposed to and gets rid of some ambiguity. Maybe a comment above the IF explaining the "PP TE" feature could alleviate the above concerns thoo. Hence: Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > index 9298c166b213..912a3bdf8ad4 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > @@ -296,7 +296,7 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct > dpu_pingpong_cfg *cfg, > c->idx = cfg->id; > c->caps = cfg; > > - if (test_bit(DPU_PINGPONG_TE, >features)) { > + if (cfg->intr_rdptr) { > c->ops.enable_tearcheck = dpu_hw_pp_enable_te; > c->ops.disable_tearcheck = dpu_hw_pp_disable_te; > c->ops.connect_external_te = dpu_hw_pp_connect_external_te; > -- > 2.39.2 >
Re: [PATCH v2 3/4] drm/msm/dpu: add helper to get IRQ-related data
On 2023-07-27 22:51:32, Dmitry Baryshkov wrote: > On 27/07/2023 22:41, Marijn Suijten wrote: > > On 2023-07-27 22:34:59, Dmitry Baryshkov wrote: > >> On 27/07/2023 22:29, Marijn Suijten wrote: > >>> On 2023-07-27 18:04:54, Dmitry Baryshkov wrote: > >>>> In preparation to reworking the IRQ indices, move irq_tbl access to > >>>> separate helper. > >>> > >>> I am not seeing the advantage of the helper, but making every function > >>> look up dpu_kms->hw_intr->irq_tbl[irq_idx] only once and storing that in > >>> a local dpu_hw_intr_entry pointer is much tidier. > >> > >> There was a bonus point when I tried to do a irq_idx-1 in the next > >> patch. But since that code has gone, maybe I can drop this patch too. > > > > Don't drop the whole patch though. While maybe not necessary, having > > the lookup only once is much easier to follow. > > Then it's easier to keep it as is. While reviewing patch 4/4 though, the -1 might be missing after all. You still allocate "nirq = total_irqs" spots in the table, but then allow any number 0 < irq_idx <= total_irqs. Indexing irq_idx == total_irqs would be out of bounds? - Marijn
Re: [PATCH v2 4/4] drm/msm/dpu: shift IRQ indices by 1
Title nit: How about making this "UP by 1"? On 2023-07-27 18:04:55, Dmitry Baryshkov wrote: > In order to simplify IRQ declarations, shift IRQ indices by 1. This Same here, UP by one. > makes 0 the 'no IRQ' value. Thanks to this change, we do no longer have > to explicitly set the 'no interrupt' fields in catalog structures. "explicitly set unused interrupts to -1" or "explicitly signifiy 'no interrupt' fields with -1"? On the other hand this might be confusing since -1 thanks to this patch no longer means 'no interrupt'. Also okay to leave it as-is. > Signed-off-by: Dmitry Baryshkov > --- > .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 4 -- > .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 4 -- > .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 8 --- > .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 10 > .../msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 8 --- > .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 1 - > .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 3 -- > .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 - > .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 1 - > .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 8 --- > .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 6 --- > .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 13 - > .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 12 - > .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 12 - > drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 6 +-- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 +- > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 14 +++--- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 49 +-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 +-- > 22 files changed, 39 insertions(+), 137 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 ba06312cbb16..7c286bafb948 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h > @@ -37,7 +37,7 @@ irqreturn_t dpu_core_irq(struct msm_kms *kms); > */ > u32 dpu_core_irq_read( > struct dpu_kms *dpu_kms, > - int irq_idx); > + unsigned int irq_idx); > > /** > * dpu_core_irq_register_callback - For registering callback function on IRQ > @@ -52,7 +52,7 @@ u32 dpu_core_irq_read( > */ > int dpu_core_irq_register_callback( > struct dpu_kms *dpu_kms, > - int irq_idx, > + unsigned int irq_idx, > void (*irq_cb)(void *arg), > void *irq_arg); > > @@ -67,7 +67,7 @@ int dpu_core_irq_register_callback( > */ > int dpu_core_irq_unregister_callback( > struct dpu_kms *dpu_kms, > - int irq_idx); > + unsigned int irq_idx); > > /** > * dpu_debugfs_core_irq_init - register core irq debugfs > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 051447a3620c..8ccfeb002b5f 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -2555,7 +2555,7 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys > *phys_enc, > phys_enc->enable_state = DPU_ENC_DISABLED; > > for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) > - phys_enc->irq[i] = -EINVAL; > + phys_enc->irq[i] = 0; phys_enc seems to always be kzalloc'ed before it is passed here, so maybe we don't need to change the initialization value at all unless you want to be super-specific. And could memset() otherwise create faster code? > > atomic_set(_enc->vblank_refcount, 0); > atomic_set(_enc->pending_kickoff_cnt, 0); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > index f91661a69888..e203f3775ed3 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > @@ -193,7 +193,7 @@ struct dpu_encoder_phys { > atomic_t pending_ctlstart_cnt; > atomic_t pending_kickoff_cnt; > wait_queue_head_t pending_kickoff_wq; > - int irq[INTR_IDX_MAX]; > + unsigned int irq[INTR_IDX_MAX]; > bool has_intf_te; > }; > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index c72ed0e35dce..945b88c5ab58 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -524,7 +524,7 @@ struct dpu_ubwc_cfg { > */ > struct dpu_ctl_cfg { > DPU_HW_BLK_INFO; > - s32 intr_start; > + unsigned int intr_start; > }; > > /** > @@ -587,8 +587,8 @@ struct dpu_dspp_cfg { > struct dpu_pingpong_cfg {
Re: [PATCH v2 3/4] drm/msm/dpu: add helper to get IRQ-related data
On 2023-07-27 22:34:59, Dmitry Baryshkov wrote: > On 27/07/2023 22:29, Marijn Suijten wrote: > > On 2023-07-27 18:04:54, Dmitry Baryshkov wrote: > >> In preparation to reworking the IRQ indices, move irq_tbl access to > >> separate helper. > > > > I am not seeing the advantage of the helper, but making every function > > look up dpu_kms->hw_intr->irq_tbl[irq_idx] only once and storing that in > > a local dpu_hw_intr_entry pointer is much tidier. > > There was a bonus point when I tried to do a irq_idx-1 in the next > patch. But since that code has gone, maybe I can drop this patch too. Don't drop the whole patch though. While maybe not necessary, having the lookup only once is much easier to follow. - Marijn > > Maybe I expected it to do extra mutations to irq_idx in 4/4? > > > >> Signed-off-by: Dmitry Baryshkov > > > > Reviewed-by: Marijn Suijten > > > >> --- > >> .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 48 +-- > >> .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 12 +++-- > >> 2 files changed, 41 insertions(+), 19 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > >> index eaae7f11f57f..ede7161ae904 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > >> @@ -199,6 +199,12 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] > >> = { > >> > >> #define DPU_IRQ_MASK(irq_idx)(BIT(DPU_IRQ_OFFSET(irq_idx))) > >> > >> +static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct > >> dpu_kms *dpu_kms, > >> + int irq_idx) > >> +{ > >> + return _kms->hw_intr->irq_tbl[irq_idx]; > >> +} > >> + > >> /** > >>* dpu_core_irq_callback_handler - dispatch core interrupts > >>* @dpu_kms: Pointer to DPU's KMS structure > >> @@ -206,17 +212,19 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] > >> = { > >>*/ > >> static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int > >> irq_idx) > >> { > >> + struct dpu_hw_intr_entry *irq_entry = dpu_core_irq_get_entry(dpu_kms, > >> irq_idx); > >> + > >>VERB("irq_idx=%d\n", irq_idx); > >> > >> - if (!dpu_kms->hw_intr->irq_tbl[irq_idx].cb) > >> + if (!irq_entry->cb) > >>DRM_ERROR("no registered cb, idx:%d\n", irq_idx); > >> > >> - atomic_inc(_kms->hw_intr->irq_tbl[irq_idx].count); > >> + atomic_inc(_entry->count); > >> > >>/* > >> * Perform registered function callback > >> */ > >> - > >> dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg); > >> + irq_entry->cb(irq_entry->arg); > >> } > >> > >> irqreturn_t dpu_core_irq(struct msm_kms *kms) > >> @@ -509,6 +517,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > >> *dpu_kms, int irq_idx, > >>void (*irq_cb)(void *arg), > >>void *irq_arg) > >> { > >> + struct dpu_hw_intr_entry *irq_entry; > >>unsigned long irq_flags; > >>int ret; > >> > >> @@ -526,15 +535,16 @@ int dpu_core_irq_register_callback(struct dpu_kms > >> *dpu_kms, int irq_idx, > >> > >>spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags); > >> > >> - if (unlikely(WARN_ON(dpu_kms->hw_intr->irq_tbl[irq_idx].cb))) { > >> + irq_entry = dpu_core_irq_get_entry(dpu_kms, irq_idx); > >> + if (unlikely(WARN_ON(irq_entry->cb))) { > >>spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > >> > >>return -EBUSY; > >>} > >> > >>trace_dpu_core_irq_register_callback(irq_idx, irq_cb); > >> - dpu_kms->hw_intr->irq_tbl[irq_idx].arg = irq_arg; > >> - dpu_kms->hw_intr->irq_tbl[irq_idx].cb = irq_cb; > >> + irq_entry->arg = irq_arg; > >> + irq_entry->cb = irq_cb; > >> > >>ret = dpu_hw_intr_enable_irq_locked( > >>dpu_kms->hw_intr, > >> @@ -551,6 +561,7 @@ int dpu_core_irq_register_callback(struct dpu_kms &g
Re: [PATCH v2 3/4] drm/msm/dpu: add helper to get IRQ-related data
On 2023-07-27 18:04:54, Dmitry Baryshkov wrote: > In preparation to reworking the IRQ indices, move irq_tbl access to > separate helper. I am not seeing the advantage of the helper, but making every function look up dpu_kms->hw_intr->irq_tbl[irq_idx] only once and storing that in a local dpu_hw_intr_entry pointer is much tidier. Maybe I expected it to do extra mutations to irq_idx in 4/4? > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 48 +-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 12 +++-- > 2 files changed, 41 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index eaae7f11f57f..ede7161ae904 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -199,6 +199,12 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > > #define DPU_IRQ_MASK(irq_idx)(BIT(DPU_IRQ_OFFSET(irq_idx))) > > +static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct > dpu_kms *dpu_kms, > +int irq_idx) > +{ > + return _kms->hw_intr->irq_tbl[irq_idx]; > +} > + > /** > * dpu_core_irq_callback_handler - dispatch core interrupts > * @dpu_kms: Pointer to DPU's KMS structure > @@ -206,17 +212,19 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > */ > static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int > irq_idx) > { > + struct dpu_hw_intr_entry *irq_entry = dpu_core_irq_get_entry(dpu_kms, > irq_idx); > + > VERB("irq_idx=%d\n", irq_idx); > > - if (!dpu_kms->hw_intr->irq_tbl[irq_idx].cb) > + if (!irq_entry->cb) > DRM_ERROR("no registered cb, idx:%d\n", irq_idx); > > - atomic_inc(_kms->hw_intr->irq_tbl[irq_idx].count); > + atomic_inc(_entry->count); > > /* >* Perform registered function callback >*/ > - > dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg); > + irq_entry->cb(irq_entry->arg); > } > > irqreturn_t dpu_core_irq(struct msm_kms *kms) > @@ -509,6 +517,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > void (*irq_cb)(void *arg), > void *irq_arg) > { > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int ret; > > @@ -526,15 +535,16 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > > spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags); > > - if (unlikely(WARN_ON(dpu_kms->hw_intr->irq_tbl[irq_idx].cb))) { > + irq_entry = dpu_core_irq_get_entry(dpu_kms, irq_idx); > + if (unlikely(WARN_ON(irq_entry->cb))) { > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > return -EBUSY; > } > > trace_dpu_core_irq_register_callback(irq_idx, irq_cb); > - dpu_kms->hw_intr->irq_tbl[irq_idx].arg = irq_arg; > - dpu_kms->hw_intr->irq_tbl[irq_idx].cb = irq_cb; > + irq_entry->arg = irq_arg; > + irq_entry->cb = irq_cb; > > ret = dpu_hw_intr_enable_irq_locked( > dpu_kms->hw_intr, > @@ -551,6 +561,7 @@ int dpu_core_irq_register_callback(struct dpu_kms > *dpu_kms, int irq_idx, > > int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx) > { > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int ret; > > @@ -569,8 +580,9 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > DPU_ERROR("Fail to disable IRQ for irq_idx:%d: %d\n", > irq_idx, ret); > > - dpu_kms->hw_intr->irq_tbl[irq_idx].cb = NULL; > - dpu_kms->hw_intr->irq_tbl[irq_idx].arg = NULL; > + irq_entry = dpu_core_irq_get_entry(dpu_kms, irq_idx); > + irq_entry->cb = NULL; > + irq_entry->arg = NULL; > > spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags); > > @@ -583,14 +595,16 @@ int dpu_core_irq_unregister_callback(struct dpu_kms > *dpu_kms, int irq_idx) > static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) > { > struct dpu_kms *dpu_kms = s->private; > + struct dpu_hw_intr_entry *irq_entry; > unsigned long irq_flags; > int i, i
Re: [PATCH v2 2/4] drm/msm/dpu: move several IRQ-related defines
On 2023-07-27 18:04:53, Dmitry Baryshkov wrote: > In preparation of slighly changing IRQ numbering, move DPU_IRQ_REG() > macro to the dpu_hw_interrupts.h header. Also split the DPU_IRQ_MASK() > macro into local DPU_IRQ_MASK() and the global DPU_IRQ_OFFSET() macros. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 3 +-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 2 ++ > 2 files changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 01a9ccfcd54b..eaae7f11f57f 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -197,8 +197,7 @@ static const struct dpu_intr_reg dpu_intr_set_7xxx[] = { > }, > }; > > -#define DPU_IRQ_REG(irq_idx) (irq_idx / 32) > -#define DPU_IRQ_MASK(irq_idx)(BIT(irq_idx % 32)) > +#define DPU_IRQ_MASK(irq_idx)(BIT(DPU_IRQ_OFFSET(irq_idx))) > > /** > * dpu_core_irq_callback_handler - dispatch core interrupts > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > index e2b00dd32619..3a988a4e4f33 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > @@ -37,6 +37,8 @@ enum dpu_hw_intr_reg { > #define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0)) > > #define DPU_IRQ_IDX(reg_idx, offset) (reg_idx * 32 + offset) > +#define DPU_IRQ_REG(irq_idx) ((irq_idx) / 32) > +#define DPU_IRQ_OFFSET(irq_idx) ((irq_idx) % 32) > > /** > * struct dpu_hw_intr: hw interrupts handling data structure > -- > 2.39.2 >
Re: [PATCH v2 1/4] drm/msm/dpu: remove irq_idx argument from IRQ callbacks
On 2023-07-27 18:04:52, Dmitry Baryshkov wrote: > There is no point in passing the IRQ index to IRQ callbacks, no function > uses that. Drop it at last. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 2 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 +- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 8 > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 4 ++-- > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 16 +--- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c| 4 ++-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h| 2 +- > 8 files changed, 18 insertions(+), 24 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 b5b6e7031fb9..ba06312cbb16 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h > @@ -53,7 +53,7 @@ u32 dpu_core_irq_read( > int dpu_core_irq_register_callback( > struct dpu_kms *dpu_kms, > int irq_idx, > - void (*irq_cb)(void *arg, int irq_idx), > + void (*irq_cb)(void *arg), > void *irq_arg); > > /** > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index f0a2a1dca741..051447a3620c 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -352,7 +352,7 @@ static int dpu_encoder_helper_wait_event_timeout(int32_t > drm_id, > > int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, > int irq, > - void (*func)(void *arg, int irq_idx), > + void (*func)(void *arg), > struct dpu_encoder_wait_info *wait_info) > { > u32 irq_status; > @@ -399,7 +399,7 @@ int dpu_encoder_helper_wait_for_irq(struct > dpu_encoder_phys *phys_enc, > phys_enc->hw_pp->idx - PINGPONG_0, > atomic_read(wait_info->atomic_cnt)); > local_irq_save(flags); > - func(phys_enc, irq); > + func(phys_enc); > local_irq_restore(flags); > ret = 0; > } else { > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > index d48558ede488..f91661a69888 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > @@ -365,7 +365,7 @@ void dpu_encoder_helper_report_irq_timeout(struct > dpu_encoder_phys *phys_enc, > */ > int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, > int irq, > - void (*func)(void *arg, int irq_idx), > + void (*func)(void *arg), > struct dpu_encoder_wait_info *wait_info); > > /** > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index df88358e7037..9589fe719452 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -76,7 +76,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, > _mode_cfg); > } > > -static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) > +static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg) > { > struct dpu_encoder_phys *phys_enc = arg; > unsigned long lock_flags; > @@ -103,7 +103,7 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void > *arg, int irq_idx) > DPU_ATRACE_END("pp_done_irq"); > } > > -static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx) > +static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg) > { > struct dpu_encoder_phys *phys_enc = arg; > struct dpu_encoder_phys_cmd *cmd_enc; > @@ -126,7 +126,7 @@ static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, > int irq_idx) > DPU_ATRACE_END("rd_ptr_irq"); > } > > -static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) > +static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg) > { > struct dpu_encoder_phys *phys_enc = arg; > > @@ -139,7 +139,7 @@ static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg, > int irq_idx) > DPU_ATRACE_END("
Re: [PATCH v4 0/5] drm/msm/dpu: rework interrupt handling
On 2023-07-27 17:45:38, Dmitry Baryshkov wrote: > Please exuse me for the spam, I missed the triggered WARN_ON because of > the dropped patch. > > Declaring the mask of supported interrupts proved to be error-prone. It > is very easy to add a bit with no corresponding backing block or to miss > the INTF TE bit. Replace this static configuration with the irq mask > calculated from the HW catalog data. > > Changes since v3: > - Rework INTF_TE handling. Stop depending on DPU_INTF_TE and enable the >relevant interrupt explicitly. Yeah that seems like a good idea. I had at some point considered, but it would be much more messy, to collect all the `.intr_` members of every cfg structure to accumulate the used flags instead. But that's more cumbersome especially since everything uses TOP0 etc anyway. I do miss b4 inserting links to lore.kernel.org for earlier series revisions though. Finally I retested this whole series on sdm845 (PP TE) and sm6125 (INTF TE) and both behave fine. - Marijn > Changes since v2: > - Rebased on top of msm-next-lumag to be able to use core_major_ver >instead of adding yet another flag. > - Dropped the DPU_INTF_TE movement patch, useless after rebasing. > > Changes since v1: > - Enable dpu_caps::has_7xxx_intr for DPU >= 7.0 (Neil) > > Dmitry Baryshkov (5): > drm/msm/dpu: inline __intr_offset > drm/msm/dpu: split interrupt address arrays > drm/msm/dpu: autodetect supported interrupts > drm/msm/dpu: drop now-unused mdss_irqs field from hw catalog > drm/msm/dpu: drop compatibility INTR defines > > .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 8 -- > .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 9 -- > .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 11 -- > .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 13 --- > .../msm/disp/dpu1/catalog/dpu_5_4_sm6125.h| 6 - > .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 10 -- > .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 6 - > .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 5 - > .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 6 - > .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 5 - > .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 5 - > .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 13 +-- > .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 9 +- > .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 18 +-- > .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 13 +-- > .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 13 +-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 3 - > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 106 -- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 18 ++- > 19 files changed, 87 insertions(+), 190 deletions(-) > > -- > 2.39.2 >
Re: [PATCH v4 00/17] drm/msm: Add SM6125 MDSS/DPU hardware and enable Sony Xperia 10 II panel
On 2023-07-27 16:34:49, Dmitry Baryshkov wrote: > On 27/07/2023 15:22, Dmitry Baryshkov wrote: > > > > On Sun, 23 Jul 2023 18:08:38 +0200, Marijn Suijten wrote: > >> Bring up the SM6125 DPU now that all preliminary series (such as INTF > >> TE) have been merged (for me to test the hardware properly), and most > >> other conflicting work (barring ongoing catalog *improvements*) has made > >> its way in as well or is still being discussed. > >> > >> The second part of the series complements that by immediately utilizing > >> this hardware in DT, and even enabling the MDSS/DSI nodes complete with > >> a 6.0" 1080x2520 panel for Sony's Seine PDX201 (Xperia 10 II). > >> > >> [...] > > > > Applied, thanks! > > > > [01/17] drm/msm/dsi: Drop unused regulators from QCM2290 14nm DSI PHY config > > https://gitlab.freedesktop.org/lumag/msm/-/commit/a7e3fda5948a > > [02/17] arm64: dts: qcom: sm6125: Pad APPS IOMMU address to 8 characters > > https://gitlab.freedesktop.org/lumag/msm/-/commit/b7d35a8eae54 > > [03/17] arm64: dts: qcom: sm6125: Sort spmi_bus node numerically by reg > > https://gitlab.freedesktop.org/lumag/msm/-/commit/2be52ca96a71 > > Of course, these two patches sneaked in by the mistake, dropped them now. Lovely, glad to have that resolved so quickly. Thanks! - Marijn > > > [04/17] dt-bindings: display/msm: Remove DSI1 ports from SM6350/SM6375 > > example > > https://gitlab.freedesktop.org/lumag/msm/-/commit/4be2c19261fc > > [05/17] dt-bindings: clock: qcom,dispcc-sm6125: Require GCC PLL0 DIV clock > > https://gitlab.freedesktop.org/lumag/msm/-/commit/4f86e343f3c6 > > [06/17] dt-bindings: clock: qcom,dispcc-sm6125: Allow power-domains property > > https://gitlab.freedesktop.org/lumag/msm/-/commit/91043642f28c > > [07/17] dt-bindings: display/msm: dsi-controller-main: Document SM6125 > > https://gitlab.freedesktop.org/lumag/msm/-/commit/cf5859476e5d > > [08/17] dt-bindings: display/msm: sc7180-dpu: Describe SM6125 > > https://gitlab.freedesktop.org/lumag/msm/-/commit/04a664dffd19 > > [09/17] dt-bindings: display/msm: Add SM6125 MDSS > > https://gitlab.freedesktop.org/lumag/msm/-/commit/3bde3b8f8a04 > > [10/17] drm/msm/dpu: Add SM6125 support > > https://gitlab.freedesktop.org/lumag/msm/-/commit/76c5dffd0bc4 > > [11/17] drm/msm/mdss: Add SM6125 support > > https://gitlab.freedesktop.org/lumag/msm/-/commit/de50357565d3 > > [12/17] dt-bindings: msm: dsi-phy-14nm: Document SM6125 variant > > https://gitlab.freedesktop.org/lumag/msm/-/commit/cdac445883cc > > [13/17] drm/msm/dsi: Reuse QCM2290 14nm DSI PHY configuration for SM6125 > > https://gitlab.freedesktop.org/lumag/msm/-/commit/7638d8059ace > > > > Best regards, > > -- > With best wishes > Dmitry >
Re: [PATCH] dt-bindings: display: msm: sm6125-mdss: drop unneeded status from examples
On 2023-07-26 10:42:24, Dmitry Baryshkov wrote: > On 26/07/2023 10:31, Krzysztof Kozlowski wrote: > > On 26/07/2023 09:27, Krzysztof Kozlowski wrote: > >> On 25/07/2023 13:46, Marijn Suijten wrote: > >>> On 2023-07-25 12:16:10, Krzysztof Kozlowski wrote: > >>>> Example DTS should not have 'status' property. > >>>> > >>>> Signed-off-by: Krzysztof Kozlowski > >>>> --- > >>>> .../devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml | 6 -- > >>> > >>> This is not needed: it has already been corrected in v3 and v4 of the > >>> respective series (among other changes) and the patches were only picked > >>> to a preliminary (draft) pull to get an overview of the outstanding work > >>> for this subsystem. That branch happens to be included in regular -next > >>> releases though. > >>> > >>> 6.6 drm/msm display pull: > >>> https://gitlab.freedesktop.org/drm/msm/-/merge_requests/69 > >>> v3: > >>> https://lore.kernel.org/linux-arm-msm/20230718-sm6125-dpu-v3-0-6c5a56e99...@somainline.org/ > >>> v4: > >>> https://lore.kernel.org/linux-arm-msm/20230723-sm6125-dpu-v4-0-a3f287dd6...@somainline.org/ > >> > >> What do you mean? The old code (one I am fixing) is in current next... > >> > >> If this was fixed, why next gets some outdated branches of drm next? > >> Each maintainers next tree is supposed to be fed into the next, without > >> delays. > >> > > > > Ah, I think I understood - some work in progress was applied to > > work-in-progress branch of drm/msm and this somehow got pushed to > > linux-next? How anyone is supposed to work on next branches if they are > > outdated or have stuff known to be incomplete? > > The drm/msm & bindings parts were considered final, but then I failed to > send 'applied' series for some reason. And then it was natural for > Marijn to send an updated revision. There were comments on some of the patches that would have an effect on the binding parts (including the examples). - Marijn
Re: [PATCH] dt-bindings: display: msm: sm6125-mdss: drop unneeded status from examples
On 2023-07-25 12:16:10, Krzysztof Kozlowski wrote: > Example DTS should not have 'status' property. > > Signed-off-by: Krzysztof Kozlowski > --- > .../devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml | 6 -- This is not needed: it has already been corrected in v3 and v4 of the respective series (among other changes) and the patches were only picked to a preliminary (draft) pull to get an overview of the outstanding work for this subsystem. That branch happens to be included in regular -next releases though. 6.6 drm/msm display pull: https://gitlab.freedesktop.org/drm/msm/-/merge_requests/69 v3: https://lore.kernel.org/linux-arm-msm/20230718-sm6125-dpu-v3-0-6c5a56e99...@somainline.org/ v4: https://lore.kernel.org/linux-arm-msm/20230723-sm6125-dpu-v4-0-a3f287dd6...@somainline.org/ - Marijn > 1 file changed, 6 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml > b/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml > index 2525482424cb..479c82e6a0d8 100644 > --- a/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml > +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml > @@ -95,8 +95,6 @@ examples: > #size-cells = <1>; > ranges; > > -status = "disabled"; > - > display-controller@5e01000 { > compatible = "qcom,sm6125-dpu"; > reg = <0x05e01000 0x83208>, > @@ -170,8 +168,6 @@ examples: > #address-cells = <1>; > #size-cells = <0>; > > -status = "disabled"; > - > ports { > #address-cells = <1>; > #size-cells = <0>; > @@ -210,8 +206,6 @@ examples: > > required-opps = <_opp_svs>; > power-domains = < SM6125_VDDMX>; > - > -status = "disabled"; > }; > }; > ... > -- > 2.34.1 >
[PATCH v4 16/17] arm64: dts: qcom: sm6125: Add display hardware nodes
Add the DT nodes that describe the MDSS hardware on SM6125, containing one MDP (display controller) together with a single DSI and DSI PHY. No DisplayPort support is added for now. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten --- arch/arm64/boot/dts/qcom/sm6125.dtsi | 193 ++- 1 file changed, 191 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index 23d1284793d2..ba1d716355bc 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -1209,13 +1209,202 @@ sram@469 { reg = <0x0469 0x1>; }; + mdss: display-subsystem@5e0 { + compatible = "qcom,sm6125-mdss"; + reg = <0x05e0 0x1000>; + reg-names = "mdss"; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + clocks = < GCC_DISP_AHB_CLK>, +< DISP_CC_MDSS_AHB_CLK>, +< DISP_CC_MDSS_MDP_CLK>; + clock-names = "iface", + "ahb", + "core"; + + power-domains = < MDSS_GDSC>; + + iommus = <_smmu 0x400 0x0>; + + #address-cells = <1>; + #size-cells = <1>; + ranges; + + status = "disabled"; + + mdss_mdp: display-controller@5e01000 { + compatible = "qcom,sm6125-dpu"; + reg = <0x05e01000 0x83208>, + <0x05eb 0x2008>; + reg-names = "mdp", "vbif"; + + interrupt-parent = <>; + interrupts = <0>; + + clocks = < GCC_DISP_HF_AXI_CLK>, +< DISP_CC_MDSS_AHB_CLK>, +< DISP_CC_MDSS_ROT_CLK>, +< DISP_CC_MDSS_MDP_LUT_CLK>, +< DISP_CC_MDSS_MDP_CLK>, +< DISP_CC_MDSS_VSYNC_CLK>, +< GCC_DISP_THROTTLE_CORE_CLK>; + clock-names = "bus", + "iface", + "rot", + "lut", + "core", + "vsync", + "throttle"; + assigned-clocks = < DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <1920>; + + operating-points-v2 = <_opp_table>; + power-domains = < SM6125_VDDCX>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <_dsi0_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-19200 { + opp-hz = /bits/ 64 <19200>; + required-opps = <_opp_low_svs>; + }; + + opp-25600 { + opp-hz = /bits/ 64 <25600>; + required-opps = <_opp_svs>; + }; + + opp-30720 { + o
[PATCH v4 15/17] arm64: dts: qcom: sm6125: Add dispcc node
Enable and configure the dispcc node on SM6125 for consumption by MDSS later on. Signed-off-by: Marijn Suijten --- arch/arm64/boot/dts/qcom/sm6125.dtsi | 29 + 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index 90e242ad7943..23d1284793d2 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -3,6 +3,7 @@ * Copyright (c) 2021, Martin Botka */ +#include #include #include #include @@ -1208,6 +1209,34 @@ sram@469 { reg = <0x0469 0x1>; }; + dispcc: clock-controller@5f0 { + compatible = "qcom,sm6125-dispcc"; + reg = <0x05f0 0x2>; + + clocks = < RPM_SMD_XO_CLK_SRC>, +<0>, +<0>, +<0>, +<0>, +<0>, +< GCC_DISP_AHB_CLK>, +< GCC_DISP_GPLL0_DIV_CLK_SRC>; + clock-names = "bi_tcxo", + "dsi0_phy_pll_out_byteclk", + "dsi0_phy_pll_out_dsiclk", + "dsi1_phy_pll_out_dsiclk", + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div_clk", + "cfg_ahb_clk", + "gcc_disp_gpll0_div_clk_src"; + + required-opps = <_opp_ret>; + power-domains = < SM6125_VDDCX>; + + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + apps_smmu: iommu@c60 { compatible = "qcom,sm6125-smmu-500", "qcom,smmu-500", "arm,mmu-500"; reg = <0x0c60 0x8>; -- 2.41.0
[PATCH v4 17/17] arm64: dts: qcom: sm6125-seine: Configure MDSS, DSI and panel
Enable MDSS and DSI, and configure the Samsung SOFEF01-M ams597ut01 6.0" 1080x2520 panel. Reviewed-by: Konrad Dybcio Signed-off-by: Marijn Suijten --- .../dts/qcom/sm6125-sony-xperia-seine-pdx201.dts | 59 ++ 1 file changed, 59 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts index 82b0da5bb794..62c3e6d8147c 100644 --- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts +++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts @@ -179,6 +179,43 @@ { /* Cirrus Logic CS35L41 boosted audio amplifier @ 40 */ }; + { + status = "okay"; +}; + +_dsi0 { + vdda-supply = <_l18>; + status = "okay"; + + panel@0 { + compatible = "samsung,sofef01-m-ams597ut01"; + reg = <0>; + + reset-gpios = < 90 GPIO_ACTIVE_LOW>; + + vddio-supply = <_l12>; + + pinctrl-0 = <_dsi_active _te_active_sleep>; + pinctrl-1 = <_dsi_sleep _te_active_sleep>; + pinctrl-names = "default", "sleep"; + + port { + panel_in: endpoint { + remote-endpoint = <_dsi0_out>; + }; + }; + }; +}; + +_dsi0_out { + remote-endpoint = <_in>; + data-lanes = <0 1 2 3>; +}; + +_dsi0_phy { + status = "okay"; +}; + _adc { pinctrl-names = "default"; pinctrl-0 = <_flash_therm _ufs_therm _pa1_therm>; @@ -469,6 +506,28 @@ vol_down_n: vol-down-n-state { drive-strength = <2>; bias-disable; }; + + mdss_te_active_sleep: mdss-te-active-sleep-state { + pins = "gpio89"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + mdss_dsi_active: mdss-dsi-active-state { + pins = "gpio90"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + mdss_dsi_sleep: mdss-dsi-sleep-state { + pins = "gpio90"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; { -- 2.41.0
[PATCH v4 14/17] arm64: dts: qcom: sm6125: Switch fixed xo_board clock to RPM XO clock
We have a working RPM XO clock; no other driver except rpmcc should be parenting directly to the fixed-factor xo_board clock nor should it be reachable by that global name. Remove the name to that effect, so that every clock relation is explicitly defined in DTS. Reviewed-by: Konrad Dybcio Signed-off-by: Marijn Suijten --- arch/arm64/boot/dts/qcom/sm6125.dtsi | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index cfd0901d4555..90e242ad7943 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -23,7 +23,6 @@ xo_board: xo-board { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <1920>; - clock-output-names = "xo_board"; }; sleep_clk: sleep-clk { @@ -199,6 +198,8 @@ rpm_requests: rpm-requests { rpmcc: clock-controller { compatible = "qcom,rpmcc-sm6125", "qcom,rpmcc"; #clock-cells = <1>; + clocks = <_board>; + clock-names = "xo"; }; rpmpd: power-controller { @@ -718,7 +719,7 @@ sdhc_1: mmc@4744000 { clocks = < GCC_SDCC1_AHB_CLK>, < GCC_SDCC1_APPS_CLK>, -<_board>; +< RPM_SMD_XO_CLK_SRC>; clock-names = "iface", "core", "xo"; iommus = <_smmu 0x160 0x0>; @@ -745,7 +746,7 @@ sdhc_2: mmc@4784000 { clocks = < GCC_SDCC2_AHB_CLK>, < GCC_SDCC2_APPS_CLK>, -<_board>; +< RPM_SMD_XO_CLK_SRC>; clock-names = "iface", "core", "xo"; iommus = <_smmu 0x180 0x0>; -- 2.41.0
[PATCH v4 13/17] drm/msm/dsi: Reuse QCM2290 14nm DSI PHY configuration for SM6125
SM6125 features only a single PHY (despite a secondary PHY PLL source being available to the disp_cc_mdss_pclk0_clk_src clock), and downstream sources for this "trinket" SoC do not define the typical "vcca" regulator to be available nor used. This, including the register offset is identical to QCM2290, whose config struct can trivially be reused. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 323498237ef4..f59cf2a47b4c 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -561,6 +561,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { .data = _phy_14nm_660_cfgs }, { .compatible = "qcom,dsi-phy-14nm-8953", .data = _phy_14nm_8953_cfgs }, + { .compatible = "qcom,sm6125-dsi-phy-14nm", + .data = _phy_14nm_2290_cfgs }, #endif #ifdef CONFIG_DRM_MSM_DSI_10NM_PHY { .compatible = "qcom,dsi-phy-10nm", -- 2.41.0
[PATCH v4 12/17] dt-bindings: msm: dsi-phy-14nm: Document SM6125 variant
Document availability of the 14nm DSI PHY on SM6125. Note that this compatible uses the SoC-suffix variant, intead of postfixing an arbitrary number without the sm/sdm portion. The PHY is not powered by a vcca regulator like on most SoCs, but by the MX power domain that is provided via the power-domains property and a single corresponding required-opps. Acked-by: Krzysztof Kozlowski Signed-off-by: Marijn Suijten --- .../devicetree/bindings/display/msm/dsi-phy-14nm.yaml | 11 +++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml index a43e11d3b00d..2361da5f6736 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml @@ -19,6 +19,7 @@ properties: - qcom,dsi-phy-14nm-2290 - qcom,dsi-phy-14nm-660 - qcom,dsi-phy-14nm-8953 + - qcom,sm6125-dsi-phy-14nm reg: items: @@ -35,6 +36,16 @@ properties: vcca-supply: description: Phandle to vcca regulator device node. + power-domains: +description: + A phandle and PM domain specifier for an optional power domain. +maxItems: 1 + + required-opps: +description: + A phandle to an OPP node describing the power domain's performance point. +maxItems: 1 + required: - compatible - reg -- 2.41.0
[PATCH v4 11/17] drm/msm/mdss: Add SM6125 support
SM6125 has an UBWC 3.0 decoder but only an UBWC 1.0 encoder. Reviewed-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/msm_mdss.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index dd22d0bd1201..ad66ccf0b6e1 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -568,6 +568,13 @@ static const struct msm_mdss_data sm6115_data = { .ubwc_static = 0x11f, }; +static const struct msm_mdss_data sm6125_data = { + .ubwc_version = UBWC_1_0, + .ubwc_dec_version = UBWC_3_0, + .ubwc_swizzle = 1, + .highest_bank_bit = 1, +}; + static const struct msm_mdss_data sm8250_data = { .ubwc_version = UBWC_4_0, .ubwc_dec_version = UBWC_4_0, @@ -589,6 +596,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sc8180x-mdss", .data = _data }, { .compatible = "qcom,sc8280xp-mdss", .data = _data }, { .compatible = "qcom,sm6115-mdss", .data = _data }, + { .compatible = "qcom,sm6125-mdss", .data = _data }, { .compatible = "qcom,sm6350-mdss", .data = _data }, { .compatible = "qcom,sm6375-mdss", .data = _data }, { .compatible = "qcom,sm8150-mdss", .data = _data }, -- 2.41.0
[PATCH v4 10/17] drm/msm/dpu: Add SM6125 support
Add definitions for the display hardware used on the Qualcomm SM6125 platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h | 236 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 7 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 1 + 4 files changed, 245 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h new file mode 100644 index ..5fddfcce6288 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023 Marijn Suijten . All rights reserved. + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_5_4_SM6125_H +#define _DPU_5_4_SM6125_H + +static const struct dpu_caps sm6125_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x6, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2160, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_ubwc_cfg sm6125_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_10, + .highest_bank_bit = 0x1, + .ubwc_swizzle = 0x1, +}; + +static const struct dpu_mdp_cfg sm6125_mdp = { + .name = "top_0", + .base = 0x0, .len = 0x45c, + .features = 0, + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + }, +}; + +static const struct dpu_ctl_cfg sm6125_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a00, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sm6125_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x1f0, + .features = VIG_SM6125_MASK, + .sblk = _vig_sblk_0, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x1f0, + .features = DMA_SDM845_MASK, + .sblk = _dma_sblk_0, + .xin_id = 1, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, { + .name = "sspp_9", .id = SSPP_DMA1, + .base = 0x26000, .len = 0x1f0, + .features = DMA_SDM845_MASK, + .sblk = _dma_sblk_1, + .xin_id = 5, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA1, + }, +}; + +static const struct dpu_lm_cfg sm6125_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .features = MIXER_QCM2290_MASK, + .sblk = _lm_sblk, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + .lm_pair = LM_1, + }, { + .name = "lm_1", .id = LM_1, + .base = 0x45000, .len = 0x320, + .features =
[PATCH v4 07/17] dt-bindings: display/msm: dsi-controller-main: Document SM6125
Document general compatibility of the DSI controller on SM6125. Reviewed-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten --- Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index 76270992305a..b8d1f2b7d541 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -27,6 +27,7 @@ properties: - qcom,sdm660-dsi-ctrl - qcom,sdm845-dsi-ctrl - qcom,sm6115-dsi-ctrl + - qcom,sm6125-dsi-ctrl - qcom,sm6350-dsi-ctrl - qcom,sm6375-dsi-ctrl - qcom,sm8150-dsi-ctrl @@ -305,6 +306,7 @@ allOf: contains: enum: - qcom,msm8998-dsi-ctrl + - qcom,sm6125-dsi-ctrl - qcom,sm6350-dsi-ctrl then: properties: -- 2.41.0
[PATCH v4 08/17] dt-bindings: display/msm: sc7180-dpu: Describe SM6125
SM6125 is identical to SM6375 including the throttle clock that is also provided to the MDP node downstream. Note that any SoC other than SM6375 (currently SC7180 and SM6350) has an unconstrained maximum number of clocks and could either pass or leave out this "throttle" clock. Signed-off-by: Marijn Suijten --- Documentation/devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml index 630b11480496..ea75f0f95d5c 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml @@ -15,6 +15,7 @@ properties: compatible: enum: - qcom,sc7180-dpu + - qcom,sm6125-dpu - qcom,sm6350-dpu - qcom,sm6375-dpu @@ -63,7 +64,9 @@ allOf: - if: properties: compatible: - const: qcom,sm6375-dpu + enum: +- qcom,sm6375-dpu +- qcom,sm6125-dpu then: properties: -- 2.41.0
[PATCH v4 09/17] dt-bindings: display/msm: Add SM6125 MDSS
Document the SM6125 MDSS. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Marijn Suijten --- .../bindings/display/msm/qcom,sm6125-mdss.yaml | 213 + 1 file changed, 213 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml new file mode 100644 index ..57f0e3647711 --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml @@ -0,0 +1,213 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,sm6125-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SM6125 Display MDSS + +maintainers: + - Marijn Suijten + +description: + SM6125 MSM Mobile Display Subsystem (MDSS), which encapsulates sub-blocks + like DPU display controller, DSI and DP interfaces etc. + +$ref: /schemas/display/msm/mdss-common.yaml# + +properties: + compatible: +const: qcom,sm6125-mdss + + clocks: +items: + - description: Display AHB clock from gcc + - description: Display AHB clock + - description: Display core clock + + clock-names: +items: + - const: iface + - const: ahb + - const: core + + iommus: +maxItems: 1 + + interconnects: +maxItems: 2 + + interconnect-names: +maxItems: 2 + +patternProperties: + "^display-controller@[0-9a-f]+$": +type: object +properties: + compatible: +const: qcom,sm6125-dpu + + "^dsi@[0-9a-f]+$": +type: object +properties: + compatible: +items: + - const: qcom,sm6125-dsi-ctrl + - const: qcom,mdss-dsi-ctrl + + "^phy@[0-9a-f]+$": +type: object +properties: + compatible: +const: qcom,sm6125-dsi-phy-14nm + +unevaluatedProperties: false + +examples: + - | +#include +#include +#include +#include +#include + +display-subsystem@5e0 { +compatible = "qcom,sm6125-mdss"; +reg = <0x05e0 0x1000>; +reg-names = "mdss"; + +interrupts = ; +interrupt-controller; +#interrupt-cells = <1>; + +clocks = < GCC_DISP_AHB_CLK>, + < DISP_CC_MDSS_AHB_CLK>, + < DISP_CC_MDSS_MDP_CLK>; +clock-names = "iface", + "ahb", + "core"; + +power-domains = < MDSS_GDSC>; + +iommus = <_smmu 0x400 0x0>; + +#address-cells = <1>; +#size-cells = <1>; +ranges; + +display-controller@5e01000 { +compatible = "qcom,sm6125-dpu"; +reg = <0x05e01000 0x83208>, + <0x05eb 0x2008>; +reg-names = "mdp", "vbif"; + +interrupt-parent = <>; +interrupts = <0>; + +clocks = < GCC_DISP_HF_AXI_CLK>, + < DISP_CC_MDSS_AHB_CLK>, + < DISP_CC_MDSS_ROT_CLK>, + < DISP_CC_MDSS_MDP_LUT_CLK>, + < DISP_CC_MDSS_MDP_CLK>, + < DISP_CC_MDSS_VSYNC_CLK>, + < GCC_DISP_THROTTLE_CORE_CLK>; +clock-names = "bus", + "iface", + "rot", + "lut", + "core", + "vsync", + "throttle"; +assigned-clocks = < DISP_CC_MDSS_VSYNC_CLK>; +assigned-clock-rates = <1920>; + +operating-points-v2 = <_opp_table>; +power-domains = < SM6125_VDDCX>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +dpu_intf1_out: endpoint { +remote-endpoint = <_dsi0_in>; +}; +}; +}; +}; + +dsi@5e94000 { +compatible = "qcom,sm6125-dsi-ctrl", "qcom,mdss-dsi-ctrl"; +reg = <0x05e94000 0x400>; +reg-names = "dsi_ctrl"; + +interrupt-parent = <>; +interrupts = <4>; + +clocks = < DISP_CC_MDSS_BYTE0_CLK>, + < DISP_CC_MDSS_BYTE0_INTF_CLK>, + < DISP_CC_MDSS_PCLK0_CLK>, + < DISP_CC_MDSS_ESC0_CLK>, + < DISP_CC_MDSS_AHB_CLK>, + < GCC_DISP_HF_AXI_CLK>; +clock-names = "byte
[PATCH v4 05/17] dt-bindings: clock: qcom,dispcc-sm6125: Require GCC PLL0 DIV clock
The "gcc_disp_gpll0_div_clk_src" clock is consumed by the driver, will be passed from DT, and should be required by the bindings. Fixes: 8397c9c0c26b ("dt-bindings: clock: add QCOM SM6125 display clock bindings") Reviewed-by: Rob Herring Signed-off-by: Marijn Suijten --- Documentation/devicetree/bindings/clock/qcom,dispcc-sm6125.yaml | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm6125.yaml b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm6125.yaml index 8a210c4c5f82..8fd29915bf2c 100644 --- a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm6125.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm6125.yaml @@ -29,6 +29,7 @@ properties: - description: Link clock from DP PHY - description: VCO DIV clock from DP PHY - description: AHB config clock from GCC + - description: GPLL0 div source from GCC clock-names: items: @@ -39,6 +40,7 @@ properties: - const: dp_phy_pll_link_clk - const: dp_phy_pll_vco_div_clk - const: cfg_ahb_clk + - const: gcc_disp_gpll0_div_clk_src '#clock-cells': const: 1 @@ -72,14 +74,16 @@ examples: <_phy 1>, <_phy 0>, <_phy 1>, - < GCC_DISP_AHB_CLK>; + < GCC_DISP_AHB_CLK>, + < GCC_DISP_GPLL0_DIV_CLK_SRC>; clock-names = "bi_tcxo", "dsi0_phy_pll_out_byteclk", "dsi0_phy_pll_out_dsiclk", "dsi1_phy_pll_out_dsiclk", "dp_phy_pll_link_clk", "dp_phy_pll_vco_div_clk", -"cfg_ahb_clk"; +"cfg_ahb_clk", +"gcc_disp_gpll0_div_clk_src"; #clock-cells = <1>; #power-domain-cells = <1>; }; -- 2.41.0
[PATCH v4 03/17] arm64: dts: qcom: sm6125: Sort spmi_bus node numerically by reg
This node has always resided in the wrong spot, making it somewhat harder to contribute new node entries while maintaining proper sorting around it. Move the node up to sit after hsusb_phy1 where it maintains proper numerical sorting on the (first of its many) reg address property. Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125") Reviewed-by: Konrad Dybcio Signed-off-by: Marijn Suijten --- arch/arm64/boot/dts/qcom/sm6125.dtsi | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index 7feb6feffa40..cfd0901d4555 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -684,6 +684,24 @@ hsusb_phy1: phy@1613000 { status = "disabled"; }; + spmi_bus: spmi@1c4 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x01c4 0x1100>, + <0x01e0 0x200>, + <0x03e0 0x10>, + <0x03f0 0xa>, + <0x01c0a000 0x26000>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + rpm_msg_ram: sram@45f { compatible = "qcom,rpm-msg-ram"; reg = <0x045f 0x7000>; @@ -1189,24 +1207,6 @@ sram@469 { reg = <0x0469 0x1>; }; - spmi_bus: spmi@1c4 { - compatible = "qcom,spmi-pmic-arb"; - reg = <0x01c4 0x1100>, - <0x01e0 0x200>, - <0x03e0 0x10>, - <0x03f0 0xa>, - <0x01c0a000 0x26000>; - reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; - interrupt-names = "periph_irq"; - interrupts = ; - qcom,ee = <0>; - qcom,channel = <0>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-controller; - #interrupt-cells = <4>; - }; - apps_smmu: iommu@c60 { compatible = "qcom,sm6125-smmu-500", "qcom,smmu-500", "arm,mmu-500"; reg = <0x0c60 0x8>; -- 2.41.0