Re: [PATCH 5/7] drm/msm/dpu: Correct dual-ctl -> dual-intf typo in comment

2024-04-28 Thread Marijn Suijten
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

2024-04-19 Thread Marijn Suijten
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

2024-04-19 Thread Marijn Suijten
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

2024-04-17 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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

2024-04-16 Thread Marijn Suijten
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()

2024-04-13 Thread Marijn Suijten
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)

2024-04-08 Thread Marijn Suijten
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

2024-04-08 Thread Marijn Suijten
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

2024-04-03 Thread Marijn Suijten
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

2024-04-02 Thread Marijn Suijten
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()

2024-04-02 Thread Marijn Suijten
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

2024-04-02 Thread Marijn Suijten
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

2024-04-02 Thread Marijn Suijten
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

2024-04-02 Thread Marijn Suijten
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()

2024-04-01 Thread Marijn Suijten
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

2024-04-01 Thread Marijn Suijten
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

2024-03-30 Thread Marijn Suijten
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

2024-03-30 Thread Marijn Suijten
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

2024-03-30 Thread Marijn Suijten
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

2024-03-30 Thread Marijn Suijten
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

2024-02-04 Thread Marijn Suijten
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

2024-02-04 Thread Marijn Suijten
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

2024-01-21 Thread Marijn Suijten
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

2023-12-21 Thread Marijn Suijten
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

2023-12-11 Thread Marijn Suijten
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

2023-12-04 Thread Marijn Suijten
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

2023-11-15 Thread Marijn Suijten
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

2023-11-14 Thread Marijn Suijten
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

2023-10-10 Thread Marijn Suijten
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

2023-09-05 Thread Marijn Suijten
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

2023-09-03 Thread Marijn Suijten
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

2023-08-06 Thread Marijn Suijten
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

2023-08-06 Thread Marijn Suijten
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

2023-08-03 Thread Marijn Suijten
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

2023-08-03 Thread Marijn Suijten
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

2023-08-02 Thread Marijn Suijten
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

2023-08-02 Thread Marijn Suijten
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

2023-08-02 Thread Marijn Suijten
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

2023-08-02 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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()

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-30 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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

2023-07-29 Thread Marijn Suijten
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()

2023-07-29 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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()

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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()

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-27 Thread Marijn Suijten
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

2023-07-26 Thread Marijn Suijten
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

2023-07-25 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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

2023-07-23 Thread Marijn Suijten
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



  1   2   3   4   5   6   7   8   9   10   >