Re: [PATCH v2 0/3] Move blender setup from individual planes to crtc commit in sun4i-drm

2024-04-21 Thread Jernej Škrabec
Dne petek, 19. april 2024 ob 15:36:17 GMT +2 je Ondřej Jirman napisal(a):
> Hi,
> 
> On Sat, Feb 24, 2024 at 04:05:57PM GMT, megi xff wrote:
> > From: Ondrej Jirman 
> > 
> > This series refactors blender setup from individual planes to a common
> > place where it can be performed at once and is easier to reason about.
> > 
> > In the process this fixes a few bugs that allowed blender pipes to be
> > disabled while corresponding DRM planes were requested to be enabled.
> > 
> > Please take a look. :)
> > 
> > v2:
> > - use regmap_write where possible
> > - add review tags
> 
> It would be nice to have this applied.

Maxime,

do you mind applying?

Best regards,
Jernej

> 
> Kind regards,
>   o.
> 
> > Thank you very much,
> > Ondřej Jirman
> > 
> > Ondrej Jirman (3):
> >   drm/sun4i: Unify sun8i_*_layer structs
> >   drm/sun4i: Add more parameters to sunxi_engine commit callback
> >   drm/sun4i: Fix layer zpos change/atomic modesetting
> > 
> >  drivers/gpu/drm/sun4i/sun4i_backend.c  |  4 +-
> >  drivers/gpu/drm/sun4i/sun4i_crtc.c |  2 +-
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c| 70 -
> >  drivers/gpu/drm/sun4i/sun8i_mixer.h| 20 ++
> >  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 85 +++--
> >  drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 86 +++---
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++
> >  drivers/gpu/drm/sun4i/sunxi_engine.h   | 13 +++-
> >  9 files changed, 125 insertions(+), 195 deletions(-)
> > 
> 






Re: [PATCH 5/7] ARM: configs: sunxi: Enable DRM_DW_HDMI

2024-04-15 Thread Jernej Škrabec
Dne sreda, 3. april 2024 ob 12:56:23 GMT +2 je Maxime Ripard napisal(a):
> Commit 4fc8cb47fcfd ("drm/display: Move HDMI helpers into display-helper
> module") turned the DRM_DW_HDMI dependency of DRM_SUN8I_DW_HDMI into a
> depends on which ended up disabling the driver in the defconfig. Make
> sure it's still enabled.
> 
> Fixes: 4fc8cb47fcfd ("drm/display: Move HDMI helpers into display-helper 
> module")
> Reported-by: Mark Brown 
> Reported-by: Alexander Stein 
> Signed-off-by: Maxime Ripard 

Applied, thanks!

Best regards,
Jernej




Re: [PATCH v4 0/5] Pinephone video out fixes (flipping between two frames)

2024-04-15 Thread Jernej Škrabec
Dne sreda, 3. april 2024 ob 17:31:47 GMT +2 je Frank Oltmanns napisal(a):
> Dear clk and sunxi-ng maintainers,
> 
> Patches 1-4 have been reviewed and there are no pending issues. If there
> is something else you need me to do to get this applied, please let me
> know.

Sorry for late patch merge. Patch 1-2 are applied as a fix to 6.9, the rest
will go to 6.10.

Best regards,
Jernej

> 
> Thanks,
>   Frank
> 
> On 2024-03-10 at 14:21:10 +0100, Frank Oltmanns  wrote:
> > On some pinephones the video output sometimes freezes (flips between two
> > frames) [1]. It seems to be that the reason for this behaviour is that
> > PLL-MIPI is outside its limits, and the GPU is not running at a fixed
> > rate.
> >
> > In this patch series I propose the following changes:
> >   1. sunxi-ng: Adhere to the following constraints given in the
> >  Allwinner A64 Manual regarding PLL-MIPI:
> >   * M/N <= 3
> >   * (PLL_VIDEO0)/M >= 24MHz
> >   * 500MHz <= clockrate <= 1400MHz
> >
> >   2. Remove two operating points from the A64 DTS OPPs, so that the GPU
> >  runs at a fixed rate of 432 MHz.
> >
> > Note, that when pinning the GPU to 432 MHz the issue [1] completely
> > disappears for me. I've searched the BSP and could not find any
> > indication that supports the idea of having the three OPPs. The only
> > frequency I found in the BPSs for A64 is 432 MHz, which has also proven
> > stable for me.
> >
> > I very much appreciate your feedback!
> >
> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
> >
> > Signed-off-by: Frank Oltmanns 
> > ---
> > Changes in v4:
> > - sunxi-ng: common: Address review comments.
> > - Link to v3: 
> > https://lore.kernel.org/r/20240304-pinephone-pll-fixes-v3-0-94ab828f2...@oltmanns.dev
> >
> > Changes in v3:
> > - dts: Pin GPU to 432 MHz.
> > - nkm and a64: Move minimum and maximum rate handling to the common part
> >   of the sunxi-ng driver.
> > - Removed st7703 patch from series.
> > - Link to v2: 
> > https://lore.kernel.org/r/20240205-pinephone-pll-fixes-v2-0-96a46a2d8...@oltmanns.dev
> >
> > Changes in v2:
> > - dts: Increase minimum GPU frequency to 192 MHz.
> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
> > - nkm: Use the same approach for skipping invalid rates in
> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
> > - nkm: Improve names for ratio struct members and hence get rid of
> >   describing comments.
> > - nkm and a64: Correct description in the commit messages: M/N <= 3
> > - Remove patches for nm as they were not needed.
> > - st7703: Rework the commit message to cover more background for the
> >   change.
> > - Link to v1: 
> > https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6...@oltmanns.dev
> >
> > ---
> > Frank Oltmanns (5):
> >   clk: sunxi-ng: common: Support minimum and maximum rate
> >   clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
> >   clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
> >   clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and 
> > parent rate
> >   arm64: dts: allwinner: a64: Run GPU at 432 MHz
> >
> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  8 
> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +-
> >  drivers/clk/sunxi-ng/ccu_common.c | 19 +++
> >  drivers/clk/sunxi-ng/ccu_common.h |  3 +++
> >  drivers/clk/sunxi-ng/ccu_nkm.c| 21 +
> >  drivers/clk/sunxi-ng/ccu_nkm.h|  2 ++
> >  6 files changed, 54 insertions(+), 13 deletions(-)
> > ---
> > base-commit: dcb6c8ee6acc6c347caec1e73fb900c0f4ff9806
> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
> >
> > Best regards,
> 






Re: [PATCH 5/7] ARM: configs: sunxi: Enable DRM_DW_HDMI

2024-04-14 Thread Jernej Škrabec
Dne sreda, 3. april 2024 ob 12:56:23 CEST je Maxime Ripard napisal(a):
> Commit 4fc8cb47fcfd ("drm/display: Move HDMI helpers into display-helper
> module") turned the DRM_DW_HDMI dependency of DRM_SUN8I_DW_HDMI into a
> depends on which ended up disabling the driver in the defconfig. Make
> sure it's still enabled.
> 
> Fixes: 4fc8cb47fcfd ("drm/display: Move HDMI helpers into display-helper 
> module")
> Reported-by: Mark Brown 
> Reported-by: Alexander Stein 
> Signed-off-by: Maxime Ripard 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  arch/arm/configs/sunxi_defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/configs/sunxi_defconfig 
> b/arch/arm/configs/sunxi_defconfig
> index bddc82f78942..a83d29fed175 100644
> --- a/arch/arm/configs/sunxi_defconfig
> +++ b/arch/arm/configs/sunxi_defconfig
> @@ -108,10 +108,11 @@ CONFIG_DRM_SUN4I_HDMI_CEC=y
>  CONFIG_DRM_SUN8I_DW_HDMI=y
>  CONFIG_DRM_PANEL_LVDS=y
>  CONFIG_DRM_PANEL_SIMPLE=y
>  CONFIG_DRM_PANEL_EDP=y
>  CONFIG_DRM_SIMPLE_BRIDGE=y
> +CONFIG_DRM_DW_HDMI=y
>  CONFIG_DRM_LIMA=y
>  CONFIG_FB_SIMPLE=y
>  CONFIG_BACKLIGHT_CLASS_DEVICE=y
>  CONFIG_BACKLIGHT_PWM=y
>  CONFIG_SOUND=y
> 
> 






Re: [PATCH] drm/sun4i: tcon: Support keeping dclk rate upon ancestor clock changes

2024-03-14 Thread Jernej Škrabec
Dne četrtek, 14. marec 2024 ob 15:42:24 CET je Maxime Ripard napisal(a):
> Hi,
> 
> On Sun, Mar 10, 2024 at 02:32:29PM +0100, Frank Oltmanns wrote:
> > Allow the dclk to reset its rate when a rate change is initiated from an
> > ancestor clock. This makes it possible to no longer to get an exclusive
> > lock. As a consequence, it is now possible to set new rates if
> > necessary, e.g. when an external display is connected.
> > 
> > The first user of this functionality is the A64 because PLL-VIDEO0 is an
> > ancestor for both HDMI and TCON0. This allows to select an optimal rate
> > for TCON0 as long as there is no external HDMI connection. Once a change
> > in PLL-VIDEO0 is performed when an HDMI connection is established, TCON0
> > can react gracefully and select an optimal rate based on this the new
> > constraint.
> > 
> > Signed-off-by: Frank Oltmanns 
> > ---
> > I would like to make the Allwinner A64's data-clock keep its rate
> > when its ancestor's (pll-video0) rate changes. Keeping data-clock's rate
> > is required, to let the A64 drive both an LCD and HDMI display at the
> > same time, because both have pll-video0 as an ancestor.
> > 
> > TCONs that use this flag store the ideal rate for their data-clock and
> > subscribe to be notified when data-clock changes. When rate setting has
> > finished (indicated by a POST_RATE_CHANGE event) the call back function
> > schedules delayed work to set the data-clock's rate to the initial value
> > after 100 ms. Using delayed work maks sure that the clock setting is
> > finished.
> > 
> > I've implemented this functionality as a quirk, so that it is possible
> > to use it only for the A64.
> > 
> > This patch supersedes [1].
> > 
> > This work is inspired by an out-of-tree patchset [2] [3] [4].
> > Unfortunately, the patchset uses clk_set_rate() directly in a notifier
> > callback, which the following comment on clk_notifier_register()
> > forbids: "The callbacks associated with the notifier must not re-enter
> > into the clk framework by calling any top-level clk APIs." [5]
> > Furthermore, that out-of-tree patchset no longer works since 6.6,
> > because setting pll-mipi is now also resetting pll-video0 and therefore
> > causes a race condition.
> 
> Workqueues don't have an upper boundary on when they execute. As we
> discussed multiple times, this should be solved in the clock framework
> itself, not bypassing it.

I think TCON code still needs to be touched due to clk_rate_exclusive_get()
calls which effectively lock whole chain. You can't have both TCONs locking
rate on A64 for this to work correctly.

What was original reason for clk_rate_exclusive_get()? I forgot already.

Best regards,
Jernej

> 
> Maxime
> 






Re: [PATCH v4 5/5] arm64: dts: allwinner: a64: Run GPU at 432 MHz

2024-03-13 Thread Jernej Škrabec
Dne nedelja, 10. marec 2024 ob 14:21:15 CET je Frank Oltmanns napisal(a):
> The Allwinner A64's GPU has currently three operating points. However,
> the BSP runs the GPU fixed at 432 MHz. In addition, at least one of the
> devices using that SoC - the pinephone - shows unstabilities (see link)
> that can be circumvented by running the GPU at a fixed rate.
> 
> Therefore, remove the other two operating points from the GPU OPP table,
> so that the GPU runs at a fixed rate of 432 MHz.
> 
> Link: https://gitlab.com/postmarketOS/pmaports/-/issues/805
> Acked-by: Erico Nunes 
> Signed-off-by: Frank Oltmanns 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 
>  1 file changed, 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
> b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 57ac18738c99..c810380aab6d 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -107,14 +107,6 @@ de: display-engine {
>   gpu_opp_table: opp-table-gpu {
>   compatible = "operating-points-v2";
>  
> - opp-12000 {
> - opp-hz = /bits/ 64 <12000>;
> - };
> -
> - opp-31200 {
> - opp-hz = /bits/ 64 <31200>;
> - };
> -
>   opp-43200 {
>   opp-hz = /bits/ 64 <43200>;
>   };
> 
> 






Re: [PATCH v4 2/5] clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI

2024-03-13 Thread Jernej Škrabec
Dne nedelja, 10. marec 2024 ob 14:21:12 CET je Frank Oltmanns napisal(a):
> When the Allwinner A64's TCON0 searches the ideal rate for the connected
> panel, it may happen that it requests a rate from its parent PLL-MIPI
> which PLL-MIPI does not support.
> 
> This happens for example on the Olimex TERES-I laptop where TCON0
> requests PLL-MIPI to change to a rate of several GHz which causes the
> panel to stay blank. It also happens on the pinephone where a rate of
> less than 500 MHz is requested which causes instabilities on some
> phones.
> 
> Set the minimum and maximum rate of Allwinner A64's PLL-MIPI according
> to the Allwinner User Manual.
> 
> Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> Reported-by: Diego Roversi 
> Closes: https://groups.google.com/g/linux-sunxi/c/Rh-Uqqa66bw
> Tested-by: Diego Roversi 
> Cc: sta...@vger.kernel.org
> Reviewed-by: Maxime Ripard 
> Signed-off-by: Frank Oltmanns 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index 8951ffc14ff5..6a4b2b9ef30a 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
> _nkm_ops,
> CLK_SET_RATE_UNGATE | 
> CLK_SET_RATE_PARENT),
>   .features   = CCU_FEATURE_CLOSEST_RATE,
> + .min_rate   = 5,
> + .max_rate   = 14,
>   },
>  };
>  
> 
> 






Re: [PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate

2024-03-13 Thread Jernej Škrabec
Dne nedelja, 10. marec 2024 ob 14:21:11 CET je Frank Oltmanns napisal(a):
> The Allwinner SoC's typically have an upper and lower limit for their
> clocks' rates. Up until now, support for that has been implemented
> separately for each clock type.
> 
> Implement that functionality in the sunxi-ng's common part making use of
> the CCF rate liming capabilities, so that it is available for all clock
> types.
> 
> Suggested-by: Maxime Ripard 
> Signed-off-by: Frank Oltmanns 
> Cc: sta...@vger.kernel.org

This looks pretty nice now.

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/clk/sunxi-ng/ccu_common.c | 19 +++
>  drivers/clk/sunxi-ng/ccu_common.h |  3 +++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_common.c 
> b/drivers/clk/sunxi-ng/ccu_common.c
> index 8babce55302f..ac0091b4ce24 100644
> --- a/drivers/clk/sunxi-ng/ccu_common.c
> +++ b/drivers/clk/sunxi-ng/ccu_common.c
> @@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
>   unsigned long current_rate,
>   unsigned long best_rate)
>  {
> + unsigned long min_rate, max_rate;
> +
> + clk_hw_get_rate_range(>hw, _rate, _rate);
> +
> + if (current_rate > max_rate)
> + return false;
> +
> + if (current_rate < min_rate)
> + return false;
> +
>   if (common->features & CCU_FEATURE_CLOSEST_RATE)
>   return abs(current_rate - target_rate) < abs(best_rate - 
> target_rate);
>  
> @@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct 
> device *dev,
>  
>   for (i = 0; i < desc->hw_clks->num ; i++) {
>   struct clk_hw *hw = desc->hw_clks->hws[i];
> + struct ccu_common *common = hw_to_ccu_common(hw);
>   const char *name;
>  
>   if (!hw)
> @@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct 
> device *dev,
>   pr_err("Couldn't register clock %d - %s\n", i, name);
>   goto err_clk_unreg;
>   }
> +
> + if (common->max_rate)
> + clk_hw_set_rate_range(hw, common->min_rate,
> +   common->max_rate);
> + else
> + WARN(common->min_rate,
> +  "No max_rate, ignoring min_rate of clock %d - 
> %s\n",
> +  i, name);
>   }
>  
>   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
> diff --git a/drivers/clk/sunxi-ng/ccu_common.h 
> b/drivers/clk/sunxi-ng/ccu_common.h
> index 942a72c09437..329734f8cf42 100644
> --- a/drivers/clk/sunxi-ng/ccu_common.h
> +++ b/drivers/clk/sunxi-ng/ccu_common.h
> @@ -31,6 +31,9 @@ struct ccu_common {
>   u16 lock_reg;
>   u32 prediv;
>  
> + unsigned long   min_rate;
> + unsigned long   max_rate;
> +
>   unsigned long   features;
>   spinlock_t  *lock;
>   struct clk_hw   hw;
> 
> 






Re: [PATCH] drm/sun4i: tcon: Support keeping dclk rate upon ancestor clock changes

2024-03-13 Thread Jernej Škrabec
Hi Frank!

Thanks on tackling this issue.

Dne nedelja, 10. marec 2024 ob 14:32:29 CET je Frank Oltmanns napisal(a):
> Allow the dclk to reset its rate when a rate change is initiated from an
> ancestor clock. This makes it possible to no longer to get an exclusive
> lock. As a consequence, it is now possible to set new rates if
> necessary, e.g. when an external display is connected.
> 
> The first user of this functionality is the A64 because PLL-VIDEO0 is an
> ancestor for both HDMI and TCON0. This allows to select an optimal rate
> for TCON0 as long as there is no external HDMI connection. Once a change
> in PLL-VIDEO0 is performed when an HDMI connection is established, TCON0
> can react gracefully and select an optimal rate based on this the new
> constraint.
> 
> Signed-off-by: Frank Oltmanns 
> ---
> I would like to make the Allwinner A64's data-clock keep its rate
> when its ancestor's (pll-video0) rate changes. Keeping data-clock's rate
> is required, to let the A64 drive both an LCD and HDMI display at the
> same time, because both have pll-video0 as an ancestor.
> 
> TCONs that use this flag store the ideal rate for their data-clock and
> subscribe to be notified when data-clock changes. When rate setting has
> finished (indicated by a POST_RATE_CHANGE event) the call back function
> schedules delayed work to set the data-clock's rate to the initial value
> after 100 ms. Using delayed work maks sure that the clock setting is
> finished.
> 
> I've implemented this functionality as a quirk, so that it is possible
> to use it only for the A64.
> 
> This patch supersedes [1].
> 
> This work is inspired by an out-of-tree patchset [2] [3] [4].
> Unfortunately, the patchset uses clk_set_rate() directly in a notifier
> callback, which the following comment on clk_notifier_register()
> forbids: "The callbacks associated with the notifier must not re-enter
> into the clk framework by calling any top-level clk APIs." [5]
> Furthermore, that out-of-tree patchset no longer works since 6.6,
> because setting pll-mipi is now also resetting pll-video0 and therefore
> causes a race condition.
> 
> Thank you for considering this contribution,
>   Frank
> 
> [1] 
> https://lore.kernel.org/lkml/20230825-pll-mipi_keep_rate-v1-0-35bc43570...@oltmanns.dev/
> [2] 
> https://codeberg.org/megi/linux/commit/a37cda2fff41a67a2bacf82b1594e10335d0bd8a
> [3] 
> https://codeberg.org/megi/linux/commit/24dc09128d2c8efc6ddf19249420e9798e967a46
> [4] 
> https://codeberg.org/megi/linux/commit/728a93d46f99f0eb231ed6fa8971a45f97c7182c
> [5] https://elixir.bootlin.com/linux/v6.7.9/source/drivers/clk/clk.c#L4669
> ---
>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 70 
> ++
>  drivers/gpu/drm/sun4i/sun4i_tcon.h | 12 +++
>  2 files changed, 76 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
> b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index a1a2c845ade0..b880bd44049a 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -108,9 +108,11 @@ static void sun4i_tcon_channel_set_status(struct 
> sun4i_tcon *tcon, int channel,
>  
>   if (enabled) {
>   clk_prepare_enable(clk);
> - clk_rate_exclusive_get(clk);
> + if (!tcon->quirks->restores_rate)
> + clk_rate_exclusive_get(clk);
>   } else {
> - clk_rate_exclusive_put(clk);
> + if (!tcon->quirks->restores_rate)
> + clk_rate_exclusive_put(clk);
>   clk_disable_unprepare(clk);
>   }
>  }
> @@ -343,6 +345,53 @@ static void sun4i_tcon0_mode_set_dithering(struct 
> sun4i_tcon *tcon,
>   regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val);
>  }
>  
> +static void sun4i_rate_reset_notifier_delayed_update(struct work_struct 
> *work)
> +{
> + struct sun4i_rate_reset_nb *rate_reset = container_of(work, struct 
> sun4i_rate_reset_nb,
> + 
> reset_rate_work.work);
> +
> + clk_set_rate(rate_reset->target_clk, rate_reset->saved_rate);
> +}
> +
> +static int sun4i_rate_reset_notifier_cb(struct notifier_block *nb,
> +   unsigned long event, void *data)
> +{
> + struct sun4i_rate_reset_nb *rate_reset = to_sun4i_rate_reset_nb(nb);
> +
> + if (event == POST_RATE_CHANGE)
> + schedule_delayed_work(_reset->reset_rate_work, 
> msecs_to_jiffies(100));

Do we need that delay though? Since clock is set exclusive on TV TCONs, then
it shouldn't be changed. Alternative, simpler variation would be something
like this:
https://elixir.bootlin.com/linux/v6.8/source/drivers/tty/serial/8250/8250_dw.c#L333

> +
> + return NOTIFY_DONE;
> +}
> +
> +static void sun4i_rate_reset_notifier_register(struct sun4i_rate_reset_nb 
> *rate_reset_nb)
> +{
> + if (rate_reset_nb->is_registered)
> + return;
> +
> + rate_reset_nb->clk_nb.notifier_call = 

Re: [PATCH v2 0/6] Pinephone video out fixes (flipping between two frames)

2024-02-26 Thread Jernej Škrabec
Dne ponedeljek, 26. februar 2024 ob 08:13:42 CET je Frank Oltmanns napisal(a):
> Hi Jernej,
> hi Maxime,
> hi Ondřej,
> 
> On 2024-02-19 at 10:41:19 +0100, Frank Oltmanns  wrote:
> > Hi Ondřej,
> >
> > On 2024-02-11 at 20:25:29 +0100, Ondřej Jirman  wrote:
> >> Hi Frank,
> >>
> >> On Sun, Feb 11, 2024 at 04:09:16PM +0100, Frank Oltmanns wrote:
> >>> Hi Ondřej,
> >>>
> >>> On 2024-02-05 at 17:02:00 +0100, Ondřej Jirman  wrote:
> >>> > On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ondřej Jirman wrote:
> >>> >> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
> >>> >>
> >>> >> [...]
> >>> >>
> >>> >> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU 
> >>> >> clock,
> >>> >> which can cause sudden frequency increase beyond intended output 
> >>> >> frequency,
> >>> >> because division is applied immediately while multiplication is 
> >>> >> reflected
> >>> >> slowly.
> >>> >>
> >>> >> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x 
> >>> >> output
> >>> >> frequency spike, before PLL VCO manages to lower the frequency through 
> >>> >> N clk
> >>> >> divider feedback loop and lock on again. This can mess up whatever's 
> >>> >> connected
> >>> >> to the output quite badly.
> >>> >>
> >>> >> You'd have to put logging on kernel writes to PLL_GPU register to see 
> >>> >> what
> >>> >> is written in there and if divider is lowered significantly on some GPU
> >>> >> devfreq frequency transitions.
> >>>
> >>> By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
> >>> always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
> >>> This is further underlined by the fact, that none of the rates can be
> >>> achieved by integer dividing one of the other rates. sunxi-ng would
> >>> only favor a different rate for pll-gpu than the one that is requested
> >>> for the gpu, if pll-gpu is already running at a rate such that there
> >>> exists an M ∈ {1, 2, 3, 4, 5, 6, 7, 8}, where
> >>>   rate of pll-gpu / M = requested gpu rate
> >>> or if the requested rate could not be reached directly by pll-gpu. Both
> >>> is not the case for the rates in question (120, 192, 312, and 432 MHz).
> >>>
> >>> This means that the following divisor/multipliers are used by sunxi-ng's
> >>> ccu_nm:
> >>> N =  5, M = 1 for 120 MHz (min value without PATCH 6)
> >>> N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
> >>> N = 13, M = 1 for 312 MHz
> >>> N = 18, M = 1 for 432 MHz
> >>>
> >>> So, with or without PATCH 6, the divider stays constant and it's only
> >>> the multiplier that changes. This means, there should be no unexpected
> >>> frequency spikes, right?
> >>
> >> Maybe. Thanks for giving it a try. There may still be other kinds of 
> >> glitches
> >> even if the divisor stays the same. It all depends how the register update 
> >> is
> >> implemented in the PLL block. It's hard to say. I guess, unless Allwinner
> >> guarantees glitchless output from a given PLL when changing its parameters,
> >> you can't rely on the output being clean during changes.
> >>
> >>> >> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL 
> >>> >> changes.
> >>>
> >>> Those are not changed once the clock is initialized. The bug however
> >>> occurs hours or days after booting. IMO, this makes it unlikely that this
> >>> could be the culprit.
> >>>
> >>> >> Maybe not much because M is supposed to be set to 1, but you still 
> >>> >> need to
> >>> >> care when enabling fractional mode, and setting M to 1 because that's 
> >>> >> exactly
> >>> >> the bad scenario if M was previously higher than 1.
> >>> >>
> >>> >> It's tricky.
> >>> >>
> >>> >> Having GPU module clock gated during PLL config changes may help! You 
> >>> >> can
> >>> >> do that without locking yourself out, unlike with the CPU PLL.
> >>> >>
> >>> >> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
> >>>
> >>> The GPU should already be properly gated:
> >>> https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599
> >>
> >> How so? That's just clock declaration. How does it guarantee the clock to 
> >> the
> >> module is gated during parent PLL configuration changes?
> >>
> >
> > You're of course right.
> >
> > I now tried using a similar approach like the one for changes for on
> > PLL-CPU. It's using a notifier to connect the CPU to the 24 MHz
> > oscillator and, after PLL-CPU is at its new rate, connecting it back to
> > PLL-CPU.
> >
> > For the GPU my approach was to disable the GPU prior to changing
> > PLL-GPU's rate and then re-enabling it, once the rate change is
> > complete. I think, that's what you were proposing, right?
> >
> > Unfortunately, this results in a frozen phone even more quickly.
> >
> > Below is my code. Again, it doesn't solve the problem, but maybe
> > somebody can spot what I'm doing wrong.
> 
> It seems to me that all options for changing the GPU's rate in a stable
> manner have been exhausted. There seems to 

Re: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting

2024-02-23 Thread Jernej Škrabec
On Saturday, February 24, 2024 3:20:43 AM CET Ondřej Jirman wrote:
> On Thu, Feb 22, 2024 at 09:02:53PM +0100, Jernej Škrabec wrote:
> > Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> > > Hi,
> > > 
> > > On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ondřej Jirman wrote:
> > > > From: Ondrej Jirman 
> > > > 
> > > > Identical configurations of planes can lead to different (and wrong)
> > > > layer -> pipe routing at HW level, depending on the order of atomic
> > > > plane changes.
> > > > 
> > > > For example:
> > > > 
> > > > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> > > >   is enabled. This is a typical situation at boot.
> > > > 
> > > > - When a compositor takes over and layer 3 is enabled,
> > > >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> > > >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > > > 
> > > > What happens is that sun8i_ui_layer_enable() function may disable
> > > > blender pipes even if it is no longer assigned to its layer.
> > > > 
> > > > To correct this, move the routing setup out of individual plane's
> > > > atomic_update into crtc's atomic_update, where it can be calculated
> > > > and updated all at once.
> > > > 
> > > > Remove the atomic_disable callback because it is no longer needed.
> > > > 
> > > > Signed-off-by: Ondrej Jirman 
> > > 
> > > I don't have enough knowledge about the mixers code to comment on your
> > > patch, so I'll let Jernej review it. However, this feels to me like the
> > > pipe assignment is typically the sort of things that should be dealt
> > > with device-wide, and in atomic_check.
> > 
> > In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because 
> > each
> > one is hardwired to specific mixer. Movable planes are the feature of DE3.3
> > and one of the pain points for upstreaming the code. Anyway, this commit 
> > only
> > addresses current issue of enabling and disabling planes and handling zpos.
> > 
> > In atomic check you can only precalculate final register values, but I don't
> > see any benefit doing that. I think that this code elegantly solves current
> > issue of enabling or disabling wrong plane in certain situations, so:
> > 
> > Reviewed-by: Jernej Skrabec 
> > 
> > Note, if there is new revision, please rewrite blender regmap_update_bits()
> > to regmap_write(). Since there is HW issue with reads, I would like to
> > get rid of regmap_update_bits() calls eventually.
> 
> I've looked into it and I can probably rewrite these quite readily:
> 
> + regmap_update_bits(mixer->engine.regs,
> +SUN8I_MIXER_BLEND_ROUTE(bld_base),
> +SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(0) |
> +SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(1) |
> +SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(2) |
> +SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(3),
> +route);
> 
> The mask here covers all implemented bits in the register.
> 
> + regmap_update_bits(mixer->engine.regs,
> +SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
> +SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) |
> +SUN8I_MIXER_BLEND_PIPE_CTL_EN(1) |
> +SUN8I_MIXER_BLEND_PIPE_CTL_EN(2) |
> +SUN8I_MIXER_BLEND_PIPE_CTL_EN(3),
> +pipe_en);
> +
> 
> The mask here doesn't cover BLD_FILL_COLOR_CTL.Px_FCEN bits that implement 
> solid
> color filling. But those can be 0 anyway except for pipe0 which is hardcoded 
> by
> the driver to 1, I think:
> 
> 631 /*
> 632  * Set fill color of bottom plane to black. Generally not needed
> 633  * except when VI plane is at bottom (zpos = 0) and enabled.
> 634  */
> 635 regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
> 636  SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));

Correct on all counts. That's what I've meant.

> 
> I will not be able to get rid of regmap_update_bits in sun8i_layer_enable
> because that register there has other important things in it like framebuffer
> pixel format, etc.

Yeah, this rework would certainly be more involved, so it's out of the scope of
this series.

Best regards,
Jernej

> 
> kind regards,
>   o.
> 
> > Best regards,
> > Jernej
> > 
> > > 
> > > If I'm talking non-sense, it would be great to mention at least why that
> > > can't be an option in the commit log.
> > > 
> > > Maxime
> > > 
> > 
> > 
> > 
> > 
> 






Re: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting

2024-02-22 Thread Jernej Škrabec
Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> Hi,
> 
> On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ondřej Jirman wrote:
> > From: Ondrej Jirman 
> > 
> > Identical configurations of planes can lead to different (and wrong)
> > layer -> pipe routing at HW level, depending on the order of atomic
> > plane changes.
> > 
> > For example:
> > 
> > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> >   is enabled. This is a typical situation at boot.
> > 
> > - When a compositor takes over and layer 3 is enabled,
> >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > 
> > What happens is that sun8i_ui_layer_enable() function may disable
> > blender pipes even if it is no longer assigned to its layer.
> > 
> > To correct this, move the routing setup out of individual plane's
> > atomic_update into crtc's atomic_update, where it can be calculated
> > and updated all at once.
> > 
> > Remove the atomic_disable callback because it is no longer needed.
> > 
> > Signed-off-by: Ondrej Jirman 
> 
> I don't have enough knowledge about the mixers code to comment on your
> patch, so I'll let Jernej review it. However, this feels to me like the
> pipe assignment is typically the sort of things that should be dealt
> with device-wide, and in atomic_check.

In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because each
one is hardwired to specific mixer. Movable planes are the feature of DE3.3
and one of the pain points for upstreaming the code. Anyway, this commit only
addresses current issue of enabling and disabling planes and handling zpos.

In atomic check you can only precalculate final register values, but I don't
see any benefit doing that. I think that this code elegantly solves current
issue of enabling or disabling wrong plane in certain situations, so:

Reviewed-by: Jernej Skrabec 

Note, if there is new revision, please rewrite blender regmap_update_bits()
to regmap_write(). Since there is HW issue with reads, I would like to
get rid of regmap_update_bits() calls eventually.

Best regards,
Jernej

> 
> If I'm talking non-sense, it would be great to mention at least why that
> can't be an option in the commit log.
> 
> Maxime
> 






Re: [PATCH 2/3] drm/sun4i: Add more parameters to sunxi_engine commit callback

2024-02-22 Thread Jernej Škrabec
Dne petek, 16. februar 2024 ob 20:04:25 CET je Ondřej Jirman napisal(a):
> From: Ondrej Jirman 
> 
> These will be needed later on when we move layer configuration to
> crtc update.
> 
> Signed-off-by: Ondrej Jirman 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_backend.c |  4 +++-
>  drivers/gpu/drm/sun4i/sun4i_crtc.c|  2 +-
>  drivers/gpu/drm/sun4i/sun8i_mixer.c   |  5 -
>  drivers/gpu/drm/sun4i/sunxi_engine.h  | 13 ++---
>  4 files changed, 18 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c 
> b/drivers/gpu/drm/sun4i/sun4i_backend.c
> index 335fd0edb904..e89eb96d3131 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> @@ -69,7 +69,9 @@ static void sun4i_backend_disable_color_correction(struct 
> sunxi_engine *engine)
>  SUN4I_BACKEND_OCCTL_ENABLE, 0);
>  }
>  
> -static void sun4i_backend_commit(struct sunxi_engine *engine)
> +static void sun4i_backend_commit(struct sunxi_engine *engine,
> +  struct drm_crtc *crtc,
> +  struct drm_atomic_state *state)
>  {
>   DRM_DEBUG_DRIVER("Committing changes\n");
>  
> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c 
> b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> index c06d7cd45388..18e74047b0f5 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> @@ -91,7 +91,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
>  
>   DRM_DEBUG_DRIVER("Committing plane changes\n");
>  
> - sunxi_engine_commit(scrtc->engine);
> + sunxi_engine_commit(scrtc->engine, crtc, state);
>  
>   if (event) {
>   crtc->state->event = NULL;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c 
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index 1e681314e379..bdeb9b80e038 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -249,7 +250,9 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 
> *hw_format)
>   return -EINVAL;
>  }
>  
> -static void sun8i_mixer_commit(struct sunxi_engine *engine)
> +static void sun8i_mixer_commit(struct sunxi_engine *engine,
> +struct drm_crtc *crtc,
> +struct drm_atomic_state *state)
>  {
>   DRM_DEBUG_DRIVER("Committing changes\n");
>  
> diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h 
> b/drivers/gpu/drm/sun4i/sunxi_engine.h
> index ec8cf9b2bda4..ec0c4932f15c 100644
> --- a/drivers/gpu/drm/sun4i/sunxi_engine.h
> +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
> @@ -7,6 +7,7 @@
>  #define _SUNXI_ENGINE_H_
>  
>  struct drm_plane;
> +struct drm_crtc;
>  struct drm_device;
>  struct drm_crtc_state;
>  struct drm_display_mode;
> @@ -59,7 +60,9 @@ struct sunxi_engine_ops {
>*
>* This function is optional.
>*/
> - void (*commit)(struct sunxi_engine *engine);
> + void (*commit)(struct sunxi_engine *engine,
> +struct drm_crtc *crtc,
> +struct drm_atomic_state *state);
>  
>   /**
>* @layers_init:
> @@ -144,12 +147,16 @@ struct sunxi_engine {
>  /**
>   * sunxi_engine_commit() - commit all changes of the engine
>   * @engine:  pointer to the engine
> + * @crtc:pointer to crtc the engine is associated with
> + * @state:   atomic state
>   */
>  static inline void
> -sunxi_engine_commit(struct sunxi_engine *engine)
> +sunxi_engine_commit(struct sunxi_engine *engine,
> + struct drm_crtc *crtc,
> + struct drm_atomic_state *state)
>  {
>   if (engine->ops && engine->ops->commit)
> - engine->ops->commit(engine);
> + engine->ops->commit(engine, crtc, state);
>  }
>  
>  /**
> 






Re: [PATCH 1/3] drm/sun4i: Unify sun8i_*_layer structs

2024-02-22 Thread Jernej Škrabec
Dne petek, 16. februar 2024 ob 20:04:24 CET je Ondřej Jirman napisal(a):
> From: Ondrej Jirman 
> 
> These structs are identical, use a single struct to represent private
> data for the DRM plane. This is a preparation for configuring layer
> routing from the CRTC (mixer) instead of current approach of setting
> up routing from individual layer's atomic_update callback.
> 
> Signed-off-by: Ondrej Jirman 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c|  4 ++--
>  drivers/gpu/drm/sun4i/sun8i_mixer.h| 14 ++
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 14 +++---
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 14 +++---
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 
>  6 files changed, 38 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c 
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index 01382860aaee..1e681314e379 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -271,7 +271,7 @@ static struct drm_plane **sun8i_layers_init(struct 
> drm_device *drm,
>   return ERR_PTR(-ENOMEM);
>  
>   for (i = 0; i < mixer->cfg->vi_num; i++) {
> - struct sun8i_vi_layer *layer;
> + struct sun8i_layer *layer;
>  
>   layer = sun8i_vi_layer_init_one(drm, mixer, i);
>   if (IS_ERR(layer)) {
> @@ -284,7 +284,7 @@ static struct drm_plane **sun8i_layers_init(struct 
> drm_device *drm,
>   }
>  
>   for (i = 0; i < mixer->cfg->ui_num; i++) {
> - struct sun8i_ui_layer *layer;
> + struct sun8i_layer *layer;
>  
>   layer = sun8i_ui_layer_init_one(drm, mixer, i);
>   if (IS_ERR(layer)) {
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h 
> b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> index 85c94884fb9a..5a610ee30301 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -9,6 +9,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "sunxi_engine.h"
>  
> @@ -185,6 +186,19 @@ struct sun8i_mixer {
>   struct clk  *mod_clk;
>  };
>  
> +struct sun8i_layer {
> + struct drm_planeplane;
> + struct sun8i_mixer  *mixer;
> + int channel;
> + int overlay;
> +};
> +
> +static inline struct sun8i_layer *
> +plane_to_sun8i_layer(struct drm_plane *plane)
> +{
> + return container_of(plane, struct sun8i_layer, plane);
> +}
> +
>  static inline struct sun8i_mixer *
>  engine_to_sun8i_mixer(struct sunxi_engine *engine)
>  {
> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c 
> b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> index ca75ca0835a6..248fbb606ede 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> @@ -232,7 +232,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane 
> *plane,
>  {
>   struct drm_plane_state *new_plane_state = 
> drm_atomic_get_new_plane_state(state,
>   
>  plane);
> - struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> + struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>   struct drm_crtc *crtc = new_plane_state->crtc;
>   struct drm_crtc_state *crtc_state;
>   int min_scale, max_scale;
> @@ -264,7 +264,7 @@ static void sun8i_ui_layer_atomic_disable(struct 
> drm_plane *plane,
>  {
>   struct drm_plane_state *old_state = 
> drm_atomic_get_old_plane_state(state,
>  
> plane);
> - struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> + struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>   unsigned int old_zpos = old_state->normalized_zpos;
>   struct sun8i_mixer *mixer = layer->mixer;
>  
> @@ -279,7 +279,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane 
> *plane,
>  
> plane);
>   struct drm_plane_state *new_state = 
> drm_atomic_get_new_plane_state(state,
>  
> plane);
> - struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> + struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>   unsigned int zpos = new_state->normalized_zpos;
>   unsigned int old_zpos = old_state->normalized_zpos;
>   struct sun8i_mixer *mixer = layer->mixer;
> @@ -345,13 +345,13 @@ static const uint64_t sun8i_layer_modifiers[] = {
>   DRM_FORMAT_MOD_INVALID
>  };
>  
> -struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
> -struct sun8i_mixer *mixer,
> -  

Re: [PATCH v7 36/36] drm/sun4i: hdmi: Switch to HDMI connector

2024-02-22 Thread Jernej Škrabec
Dne četrtek, 22. februar 2024 ob 19:14:22 CET je Maxime Ripard napisal(a):
> The new HDMI connector infrastructure allows to remove some boilerplate,
> especially to generate infoframes. Let's switch to it.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 
> ++
>  1 file changed, 51 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index b7cf369b1906..8a9106a39f23 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -36,30 +36,24 @@
>  #define drm_connector_to_sun4i_hdmi(c)   \
>   container_of_const(c, struct sun4i_hdmi, connector)
>  
> -static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
> -struct drm_display_mode *mode)
> +static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
> +   enum hdmi_infoframe_type type,
> +   const u8 *buffer, size_t len)
>  {
> - struct hdmi_avi_infoframe frame;
> - u8 buffer[17];
> - int i, ret;
> + struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> + int i;
>  
> - ret = drm_hdmi_avi_infoframe_from_display_mode(,
> ->connector, mode);
> - if (ret < 0) {
> - DRM_ERROR("Failed to get infoframes from mode\n");
> - return ret;
> + if (type != HDMI_INFOFRAME_TYPE_AVI) {
> + drm_err(connector->dev,
> + "Unsupported infoframe type: %u\n", type);
> + return 0;
>   }
>  
> - ret = hdmi_avi_infoframe_pack(, buffer, sizeof(buffer));
> - if (ret < 0) {
> - DRM_ERROR("Failed to pack infoframes\n");
> - return ret;
> - }
> -
> - for (i = 0; i < sizeof(buffer); i++)
> + for (i = 0; i < len; i++)
>   writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
>  
>   return 0;
> +
>  }
>  
>  static void sun4i_hdmi_disable(struct drm_encoder *encoder,
> @@ -82,14 +76,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  {
>   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
>   struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> - struct drm_display_info *display = >connector.display_info;
> + struct drm_connector *connector = >connector;
> + struct drm_display_info *display = >display_info;
> + struct drm_connector_state *conn_state =
> + drm_atomic_get_new_connector_state(state, connector);
> + unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
>   unsigned int x, y;
>   u32 val = 0;
>  
>   DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
>  
> - clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
> - clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
> + clk_set_rate(hdmi->mod_clk, tmds_rate);
> + clk_set_rate(hdmi->tmds_clk, tmds_rate);
>  
>   /* Set input sync enable */
>   writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
> @@ -142,7 +140,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  
>   clk_prepare_enable(hdmi->tmds_clk);
>  
> - sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
> +
>   val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
>   val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
>   writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> @@ -195,7 +194,7 @@ static int sun4i_hdmi_connector_atomic_check(struct 
> drm_connector *connector,
>   enum drm_mode_status status;
>  
>   status = sun4i_hdmi_connector_clock_valid(connector, mode,
> -   mode->clock * 1000);
> +   
> conn_state->hdmi.tmds_char_rate);
>   if (status != MODE_OK)
>   return -EINVAL;
>  
> @@ -206,8 +205,11 @@ static enum drm_mode_status
>  sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
>   struct drm_display_mode *mode)
>  {
> - return sun4i_hdmi_connector_clock_valid(connector, mode,
> - mode->clock * 1000);
> + unsigned long long rate =
> + drm_connector_hdmi_compute_mode_clock(mode, 8,
> +   HDMI_COLORSPACE_RGB);
> +
> + return sun4i_hdmi_connector_clock_valid(connector, mode, rate);
>  }
>  
>  static int sun4i_hdmi_get_modes(struct drm_connector *connector)
> @@ -253,6 +255,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct 
> device *dev)
>   return ddc;
>  }
>  
> +static const struct drm_connector_hdmi_funcs 

Re: [PATCH v7 35/36] drm/sun4i: hdmi: Consolidate atomic_check and mode_valid

2024-02-22 Thread Jernej Škrabec
Dne četrtek, 22. februar 2024 ob 19:14:21 CET je Maxime Ripard napisal(a):
> atomic_check and mode_valid do not check for the same things which can
> lead to surprising result if the userspace commits a mode that didn't go
> through mode_valid. Let's merge the two implementations into a function
> called by both.
> 
> Acked-by: Sui Jingfeng 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 74 
> +-
>  1 file changed, 47 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index c276d984da6b..b7cf369b1906 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -62,18 +62,6 @@ static int sun4i_hdmi_setup_avi_infoframes(struct 
> sun4i_hdmi *hdmi,
>   return 0;
>  }
>  
> -static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
> -struct drm_crtc_state *crtc_state,
> -struct drm_connector_state *conn_state)
> -{
> - struct drm_display_mode *mode = _state->mode;
> -
> - if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> - return -EINVAL;
> -
> - return 0;
> -}
> -
>  static void sun4i_hdmi_disable(struct drm_encoder *encoder,
>  struct drm_atomic_state *state)
>  {
> @@ -166,31 +154,61 @@ static void sun4i_hdmi_enable(struct drm_encoder 
> *encoder,
>   writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
>  }
>  
> -static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder 
> *encoder,
> - const struct drm_display_mode *mode)
> +static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
> + .atomic_disable = sun4i_hdmi_disable,
> + .atomic_enable  = sun4i_hdmi_enable,
> +};
> +
> +static enum drm_mode_status
> +sun4i_hdmi_connector_clock_valid(const struct drm_connector *connector,
> +  const struct drm_display_mode *mode,
> +  unsigned long long clock)
>  {
> - struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> - unsigned long rate = mode->clock * 1000;
> - unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */
> + const struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> + unsigned long diff = clock / 200; /* +-0.5% allowed by HDMI spec */
>   long rounded_rate;
>  
> + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> + return MODE_BAD;
> +
>   /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
> - if (rate > 16500)
> + if (clock > 16500)
>   return MODE_CLOCK_HIGH;
> - rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
> +
> + rounded_rate = clk_round_rate(hdmi->tmds_clk, clock);
>   if (rounded_rate > 0 &&
> - max_t(unsigned long, rounded_rate, rate) -
> - min_t(unsigned long, rounded_rate, rate) < diff)
> + max_t(unsigned long, rounded_rate, clock) -
> + min_t(unsigned long, rounded_rate, clock) < diff)
>   return MODE_OK;
> +
>   return MODE_NOCLOCK;
>  }
>  
> -static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
> - .atomic_check   = sun4i_hdmi_atomic_check,
> - .atomic_disable = sun4i_hdmi_disable,
> - .atomic_enable  = sun4i_hdmi_enable,
> - .mode_valid = sun4i_hdmi_mode_valid,
> -};
> +static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
> +  struct drm_atomic_state *state)
> +{
> + struct drm_connector_state *conn_state =
> + drm_atomic_get_new_connector_state(state, connector);
> + struct drm_crtc *crtc = conn_state->crtc;
> + struct drm_crtc_state *crtc_state = crtc->state;
> + struct drm_display_mode *mode = _state->adjusted_mode;
> + enum drm_mode_status status;
> +
> + status = sun4i_hdmi_connector_clock_valid(connector, mode,
> +   mode->clock * 1000);
> + if (status != MODE_OK)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static enum drm_mode_status
> +sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
> + struct drm_display_mode *mode)
> +{
> + return sun4i_hdmi_connector_clock_valid(connector, mode,
> + mode->clock * 1000);
> +}
>  
>  static int sun4i_hdmi_get_modes(struct drm_connector *connector)
>  {
> @@ -236,6 +254,8 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct 
> device *dev)
>  }
>  
>  static const struct drm_connector_helper_funcs 
> sun4i_hdmi_connector_helper_funcs = {
> + .atomic_check   = sun4i_hdmi_connector_atomic_check,
> + .mode_valid = sun4i_hdmi_connector_mode_valid,
>   

Re: [PATCH v7 34/36] drm/sun4i: hdmi: Switch to container_of_const

2024-02-22 Thread Jernej Škrabec
Dne četrtek, 22. februar 2024 ob 19:14:20 CET je Maxime Ripard napisal(a):
> container_of_const() allows to preserve the pointer constness and is
> thus more flexible than inline functions.
> 
> Let's switch all our instances of container_of() to container_of_const().
> 
> Reviewed-by: Sui Jingfeng 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 16 
>  1 file changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index bae69d696765..c276d984da6b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -30,19 +30,11 @@
>  #include "sun4i_drv.h"
>  #include "sun4i_hdmi.h"
>  
> -static inline struct sun4i_hdmi *
> -drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
> -{
> - return container_of(encoder, struct sun4i_hdmi,
> - encoder);
> -}
> +#define drm_encoder_to_sun4i_hdmi(e) \
> + container_of_const(e, struct sun4i_hdmi, encoder)
>  
> -static inline struct sun4i_hdmi *
> -drm_connector_to_sun4i_hdmi(struct drm_connector *connector)
> -{
> - return container_of(connector, struct sun4i_hdmi,
> - connector);
> -}
> +#define drm_connector_to_sun4i_hdmi(c)   \
> + container_of_const(c, struct sun4i_hdmi, connector)
>  
>  static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
>  struct drm_display_mode *mode)
> 
> 






Re: [PATCH v7 33/36] drm/sun4i: hdmi: Move mode_set into enable

2024-02-22 Thread Jernej Škrabec
Dne četrtek, 22. februar 2024 ob 19:14:19 CET je Maxime Ripard napisal(a):
> We're not doing anything special in atomic_mode_set so we can simply
> merge it into atomic_enable.
> 
> Acked-by: Sui Jingfeng 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 38 
> +-
>  1 file changed, 14 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 799a26215cc2..bae69d696765 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -103,33 +103,11 @@ static void sun4i_hdmi_enable(struct drm_encoder 
> *encoder,
>   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
>   struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>   struct drm_display_info *display = >connector.display_info;
> + unsigned int x, y;
>   u32 val = 0;
>  
>   DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
>  
> - clk_prepare_enable(hdmi->tmds_clk);
> -
> - sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> - val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
> - val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
> - writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> -
> - val = SUN4I_HDMI_VID_CTRL_ENABLE;
> - if (display->is_hdmi)
> - val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
> -
> - writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
> -}
> -
> -static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
> - struct drm_crtc_state *crtc_state,
> - struct drm_connector_state *conn_state)
> -{
> - const struct drm_display_mode *mode = _state->mode;
> - struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> - unsigned int x, y;
> - u32 val;
> -
>   clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
>   clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
>  
> @@ -181,6 +159,19 @@ static void sun4i_hdmi_mode_set(struct drm_encoder 
> *encoder,
>   val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
>  
>   writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
> +
> + clk_prepare_enable(hdmi->tmds_clk);
> +
> + sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> + val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
> + val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
> + writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> +
> + val = SUN4I_HDMI_VID_CTRL_ENABLE;
> + if (display->is_hdmi)
> + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
> +
> + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
>  }
>  
>  static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder 
> *encoder,
> @@ -206,7 +197,6 @@ static const struct drm_encoder_helper_funcs 
> sun4i_hdmi_helper_funcs = {
>   .atomic_check   = sun4i_hdmi_atomic_check,
>   .atomic_disable = sun4i_hdmi_disable,
>   .atomic_enable  = sun4i_hdmi_enable,
> - .atomic_mode_set= sun4i_hdmi_mode_set,
>   .mode_valid = sun4i_hdmi_mode_valid,
>  };
>  
> 
> 






Re: [PATCH v7 32/36] drm/sun4i: hdmi: Convert encoder to atomic

2024-02-22 Thread Jernej Škrabec
Dne četrtek, 22. februar 2024 ob 19:14:18 CET je Maxime Ripard napisal(a):
> The sun4i_hdmi driver still uses the non-atomic variants of the encoder
> hooks, so let's convert to their atomic equivalents.
> 
> Acked-by: Sui Jingfeng 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 17 ++---
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 152375f3de2e..799a26215cc2 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -82,7 +82,8 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder 
> *encoder,
>   return 0;
>  }
>  
> -static void sun4i_hdmi_disable(struct drm_encoder *encoder)
> +static void sun4i_hdmi_disable(struct drm_encoder *encoder,
> +struct drm_atomic_state *state)
>  {
>   struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>   u32 val;
> @@ -96,7 +97,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder)
>   clk_disable_unprepare(hdmi->tmds_clk);
>  }
>  
> -static void sun4i_hdmi_enable(struct drm_encoder *encoder)
> +static void sun4i_hdmi_enable(struct drm_encoder *encoder,
> +   struct drm_atomic_state *state)
>  {
>   struct drm_display_mode *mode = >crtc->state->adjusted_mode;
>   struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> @@ -120,9 +122,10 @@ static void sun4i_hdmi_enable(struct drm_encoder 
> *encoder)
>  }
>  
>  static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
> - struct drm_display_mode *mode,
> - struct drm_display_mode *adjusted_mode)
> + struct drm_crtc_state *crtc_state,
> + struct drm_connector_state *conn_state)
>  {
> + const struct drm_display_mode *mode = _state->mode;
>   struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>   unsigned int x, y;
>   u32 val;
> @@ -201,9 +204,9 @@ static enum drm_mode_status sun4i_hdmi_mode_valid(struct 
> drm_encoder *encoder,
>  
>  static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
>   .atomic_check   = sun4i_hdmi_atomic_check,
> - .disable= sun4i_hdmi_disable,
> - .enable = sun4i_hdmi_enable,
> - .mode_set   = sun4i_hdmi_mode_set,
> + .atomic_disable = sun4i_hdmi_disable,
> + .atomic_enable  = sun4i_hdmi_enable,
> + .atomic_mode_set= sun4i_hdmi_mode_set,
>   .mode_valid = sun4i_hdmi_mode_valid,
>  };
>  
> 
> 






Re: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum rate

2024-02-06 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 21:34:04 CET je Frank Oltmanns napisal(a):
> 
> On 2024-02-05 at 18:56:09 +0100, Jernej Škrabec  
> wrote:
> > Dne ponedeljek, 05. februar 2024 ob 16:22:26 CET je Frank Oltmanns 
> > napisal(a):
> >> According to the Allwinner User Manual, the Allwinner A64 requires
> >> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
> >>  2 files changed, 15 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index 1168d894d636..7d135908d6e0 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct 
> >> ccu_mux_internal *mux,
> >>if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> >>rate *= nkm->fixed_post_div;
> >>
> >> +  if (nkm->min_rate && rate < nkm->min_rate)
> >> +  rate = nkm->min_rate;
> >> +
> >> +  if (nkm->max_rate && rate > nkm->max_rate)
> >> +  rate = nkm->max_rate;
> >
> > Please take a look at ccu_nm_round_rate() code. You need to consider postdiv
> > and you can return immediately.
> 
> There is a difference here insofar that ccu_nm is always connected to a
> fixed rate parent (at least that's my understanding). Therefore, in
> ccu_nm_round_rate() we can be sure that the min or max rate can really
> be set. In ccu_nkm we don't have that luxury, we actually have to find a
> rate that is approximately equal to the min and max rate, based on the
> parent rate. Therefore, we can't return immediately.

Good point.

> 
> Also, I'm not sure what you mean about me needing to consider postdiv.
> That's what I did. The check is after multiplying with the postdiv. It's
> the same as in ccu_nm_round_rate() (just minus the immediate return).

Nevermind, this applies only for immediate return.

Best regards,
Jernej

> 
> >
> >> +
> >>if (!clk_hw_can_set_rate_parent(>common.hw))
> >>rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, 
> >> >common);
> >>else
> >> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, 
> >> unsigned long rate,
> >>_nkm.min_m = 1;
> >>_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
> >>
> >> +
> >> +  if (nkm->min_rate && rate < nkm->min_rate)
> >> +  rate = nkm->min_rate;
> >> +
> >> +  if (nkm->max_rate && rate > nkm->max_rate)
> >> +  rate = nkm->max_rate;
> >> +
> >
> > No need for this, clk subsystem calls round rate before setting actual clock
> > rate.
> 
> I'll remove the checks in V3.
> 
> Best regards,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >>ccu_nkm_find_best(parent_rate, rate, &_nkm, >common);
> >>
> >>spin_lock_irqsave(nkm->common.lock, flags);
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> index c409212ee40e..358a9df6b6a0 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> @@ -27,6 +27,8 @@ struct ccu_nkm {
> >>struct ccu_mux_internal mux;
> >>
> >>unsigned intfixed_post_div;
> >> +  unsigned long   min_rate;
> >> +  unsigned long   max_rate;
> >>unsigned long   max_m_n_ratio;
> >>unsigned long   min_parent_m_ratio;
> >>
> >>
> >>
> 






Re: [PATCH v2 2/6] clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate

2024-02-06 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 16:22:25 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N <= 3
>  - (PLL_VIDEO0)/M >= 24MHz
> 
> Use these constraints.
> 
> Signed-off-by: Frank Oltmanns 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate

2024-02-06 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 18:50:27 CET je Frank Oltmanns napisal(a):
> Hi Jernej,
> 
> On 2024-02-05 at 18:45:27 +0100, Jernej Škrabec  
> wrote:
> > Dne ponedeljek, 05. februar 2024 ob 16:22:24 CET je Frank Oltmanns 
> > napisal(a):
> >> The Allwinner A64 manual lists the following constraints for the
> >> PLL-MIPI clock:
> >>  - M/N <= 3
> >>  - (PLL_VIDEO0)/M >= 24MHz
> >>
> >> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> >> these constraints.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >
> > Haven't we discussed that this patch is unnecessary because same effect can
> > be reached by limiting minimum frequency?
> 
> The patch for ccu_nm was unnecessary:
> https://lore.kernel.org/all/87jzoug2jz@oltmanns.dev/
> 
> Unfortunately, we still need this one.

Ok, then:
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> 
> Best regards,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 21 +
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
> >>  2 files changed, 23 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index 853f84398e2b..1168d894d636 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -16,6 +16,20 @@ struct _ccu_nkm {
> >>unsigned long   m, min_m, max_m;
> >>  };
> >>
> >> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned 
> >> long parent,
> >> +unsigned long n, unsigned long m)
> >> +{
> >> +  struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> >> +
> >> +  if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
> >> +  return false;
> >> +
> >> +  if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
> >> +  return false;
> >> +
> >> +  return true;
> >> +}
> >> +
> >>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common 
> >> *common,
> >>   struct clk_hw *parent_hw,
> >>   unsigned long *parent, 
> >> unsigned long rate,
> >> @@ -31,6 +45,10 @@ static unsigned long 
> >> ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
> >>unsigned long tmp_rate, tmp_parent;
> >>
> >>tmp_parent = clk_hw_round_rate(parent_hw, rate 
> >> * _m / (_n * _k));
> >> +
> >> +  if (!ccu_nkm_is_valid_rate(common, tmp_parent, 
> >> _n, _m))
> >> +  continue;
> >> +
> >>tmp_rate = tmp_parent * _n * _k / _m;
> >>
> >>if (ccu_is_better_rate(common, rate, tmp_rate, 
> >> best_rate) ||
> >> @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long 
> >> parent, unsigned long rate,
> >>for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
> >>for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
> >>for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> >> +  if (!ccu_nkm_is_valid_rate(common, parent, _n, 
> >> _m))
> >> +  continue;
> >> +
> >>unsigned long tmp_rate;
> >>
> >>tmp_rate = parent * _n * _k / _m;
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> index 6601defb3f38..c409212ee40e 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> @@ -27,6 +27,8 @@ struct ccu_nkm {
> >>struct ccu_mux_internal mux;
> >>
> >>unsigned intfixed_post_div;
> >> +  unsigned long   max_m_n_ratio;
> >> +  unsigned long   min_parent_m_ratio;
> >>
> >>struct ccu_common   common;
> >>  };
> >>
> >>
> 






Re: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2024-02-05 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 16:22:28 CET je Frank Oltmanns napisal(a):
> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> The SOC requires pll-mipi to run at more than 500 MHz.
> 
> This is the relevant clock tree:
>  pll-mipi
> tcon0
>tcon-data-clock
> 
> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
> has 24 bpp and 4 lanes. Therefore, the resulting requested
> tcon-data-clock rate is:
> crtc_clock * 1000 * (24 / 4) / 4
> 
> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
> parent rate of
> 4 * (crtc_clock * 1000 * (24 / 4) / 4)
> 
> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
> 
> pll-mipi's constraint to run at 500MHz or higher forces us to have a
> crtc_clock >= 8 kHz if we want a 60 Hz vertical refresh rate.
> 
> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
> so that it is high enough to align with pll-pipi limits.

Typo: pll-pipi -> pll-mipi

Best regards,
Jernej

> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
> b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> index b55bafd1a8be..6886fd7f765e 100644
> --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> @@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
>  
>  static const struct drm_display_mode xbd599_mode = {
>   .hdisplay= 720,
> - .hsync_start = 720 + 40,
> - .hsync_end   = 720 + 40 + 40,
> - .htotal  = 720 + 40 + 40 + 40,
> + .hsync_start = 720 + 65,
> + .hsync_end   = 720 + 65 + 65,
> + .htotal  = 720 + 65 + 65 + 65,
>   .vdisplay= 1440,
> - .vsync_start = 1440 + 18,
> - .vsync_end   = 1440 + 18 + 10,
> - .vtotal  = 1440 + 18 + 10 + 17,
> - .clock   = 69000,
> + .vsync_start = 1440 + 30,
> + .vsync_end   = 1440 + 30 + 22,
> + .vtotal  = 1440 + 30 + 22 + 29,
> + .clock   = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
>   .flags   = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
>   .width_mm= 68,
>   .height_mm   = 136,
> 
> 






Re: [PATCH v2 4/6] clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI

2024-02-05 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 16:22:27 CET je Frank Oltmanns napisal(a):
> Set the minimum and maximum rate of Allwinner A64's PLL-MIPI according
> to the Allwinner User Manual.
> 
> Signed-off-by: Frank Oltmanns 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej





Re: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum rate

2024-02-05 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 16:22:26 CET je Frank Oltmanns napisal(a):
> According to the Allwinner User Manual, the Allwinner A64 requires
> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 1168d894d636..7d135908d6e0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct 
> ccu_mux_internal *mux,
>   if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>   rate *= nkm->fixed_post_div;
>  
> + if (nkm->min_rate && rate < nkm->min_rate)
> + rate = nkm->min_rate;
> +
> + if (nkm->max_rate && rate > nkm->max_rate)
> + rate = nkm->max_rate;

Please take a look at ccu_nm_round_rate() code. You need to consider postdiv
and you can return immediately.

> +
>   if (!clk_hw_can_set_rate_parent(>common.hw))
>   rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, 
> >common);
>   else
> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned 
> long rate,
>   _nkm.min_m = 1;
>   _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>  
> +
> + if (nkm->min_rate && rate < nkm->min_rate)
> + rate = nkm->min_rate;
> +
> + if (nkm->max_rate && rate > nkm->max_rate)
> + rate = nkm->max_rate;
> +

No need for this, clk subsystem calls round rate before setting actual clock
rate.

Best regards,
Jernej

>   ccu_nkm_find_best(parent_rate, rate, &_nkm, >common);
>  
>   spin_lock_irqsave(nkm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index c409212ee40e..358a9df6b6a0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -27,6 +27,8 @@ struct ccu_nkm {
>   struct ccu_mux_internal mux;
>  
>   unsigned intfixed_post_div;
> + unsigned long   min_rate;
> + unsigned long   max_rate;
>   unsigned long   max_m_n_ratio;
>   unsigned long   min_parent_m_ratio;
>  
> 
> 






Re: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate

2024-02-05 Thread Jernej Škrabec
Dne ponedeljek, 05. februar 2024 ob 16:22:24 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N <= 3
>  - (PLL_VIDEO0)/M >= 24MHz
> 
> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> these constraints.
> 
> Signed-off-by: Frank Oltmanns 

Haven't we discussed that this patch is unnecessary because same effect can
be reached by limiting minimum frequency?

Best regards,
Jernej

> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 21 +
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 853f84398e2b..1168d894d636 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -16,6 +16,20 @@ struct _ccu_nkm {
>   unsigned long   m, min_m, max_m;
>  };
>  
> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long 
> parent,
> +   unsigned long n, unsigned long m)
> +{
> + struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> +
> + if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
> + return false;
> +
> + if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
> + return false;
> +
> + return true;
> +}
> +
>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common 
> *common,
>  struct clk_hw *parent_hw,
>  unsigned long *parent, 
> unsigned long rate,
> @@ -31,6 +45,10 @@ static unsigned long 
> ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
>   unsigned long tmp_rate, tmp_parent;
>  
>   tmp_parent = clk_hw_round_rate(parent_hw, rate 
> * _m / (_n * _k));
> +
> + if (!ccu_nkm_is_valid_rate(common, tmp_parent, 
> _n, _m))
> + continue;
> +
>   tmp_rate = tmp_parent * _n * _k / _m;
>  
>   if (ccu_is_better_rate(common, rate, tmp_rate, 
> best_rate) ||
> @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long 
> parent, unsigned long rate,
>   for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
>   for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
>   for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> + if (!ccu_nkm_is_valid_rate(common, parent, _n, 
> _m))
> + continue;
> +
>   unsigned long tmp_rate;
>  
>   tmp_rate = parent * _n * _k / _m;
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index 6601defb3f38..c409212ee40e 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -27,6 +27,8 @@ struct ccu_nkm {
>   struct ccu_mux_internal mux;
>  
>   unsigned intfixed_post_div;
> + unsigned long   max_m_n_ratio;
> + unsigned long   min_parent_m_ratio;
>  
>   struct ccu_common   common;
>  };
> 
> 






Re: [PATCH 4/5] clk: sunxi-ng: a64: Add constraints on PLL-VIDEO0's n/m ratio

2024-01-09 Thread Jernej Škrabec
Dne nedelja, 31. december 2023 ob 10:10:40 CET je Frank Oltmanns napisal(a):
> 
> On 2023-12-19 at 17:54:19 +0100, Jernej Škrabec  
> wrote:
> > Dne ponedeljek, 18. december 2023 ob 14:35:22 CET je Frank Oltmanns 
> > napisal(a):
> >> The Allwinner A64 manual lists the following constraint for the
> >> PLL-VIDEO0 clock: 8 <= N/M <= 25
> >>
> >> Use this constraint.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >> ---
> >>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 8 ++--
> >>  1 file changed, 6 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
> >> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> index c034ac027d1c..75d839da446c 100644
> >> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> @@ -68,7 +68,8 @@ static 
> >> SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
> >>   BIT(28), /* lock */
> >>   CLK_SET_RATE_UNGATE);
> >>
> >> -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, 
> >> "pll-video0",
> >> +static 
> >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO(pll_video0_clk,
> >> +  "pll-video0",
> >>"osc24M", 0x010,
> >>19200,  /* Minimum rate 
> >> */
> >>100800, /* Maximum rate 
> >> */
> 
> I just realized that adding the whole ratio limits for ccu_nm is
> superfluous as you could just as well express them in for of a minimum
> and maximum range:
> Since 8 <= N/M <= 25 and parent_rate = 24 MHz, therefore
>   192 MHz <= rate <= 600 MHz.

Good point!

> 
> These absolute limits are also listed in Allwinner's A64 manual.
> 
> BUT, here the upper limit was raised to 1008 MHz:
> 5de39acaf34604bd04834f092479cf4dcc946dd "clk: sunxi-ng: a64: Add max.
> rate constraint to video PLL"
> 
> With this upper limit the ratio limitation is effectively:
> 8 <= N/M <= 42
> 
> Icenowy Zheng (added to CC) had the reasonable explanation that this was
> used in the BSP kernel, so we should probably stick to that and ditch
> the two PLL-VIDEO0 related patches. What are your thoughts on that?

Ok, it seems that these patches are really superfluous. Remove them for v2.

Best regards,
Jernej

> 
> >> @@ -80,7 +81,10 @@ static 
> >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-vid
> >>29700,  /* frac rate 1 
> >> */
> >>BIT(31),/* gate */
> >>BIT(28),/* lock */
> >> -  CLK_SET_RATE_UNGATE);
> >> +  CLK_SET_RATE_UNGATE,
> >> +  CCU_FEATURE_FRACTIONAL |
> >> +  CCU_FEATURE_CLOSEST_RATE,
> >
> > Above flags are unrelated change, put them in new patch if needed.
> >
> > Best regards,
> > Jernej
> >
> >> +  8, 25); /* min/max nm 
> >> ratio */
> >>
> >>  static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
> >>"osc24M", 0x018,
> >>
> >>
> 






Re: [PATCH 5/5] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2023-12-22 Thread Jernej Škrabec
Dne petek, 22. december 2023 ob 10:10:25 CET je Frank Oltmanns napisal(a):
> 
> On 2023-12-20 at 19:57:06 +0100, Frank Oltmanns  wrote:
> > Ok, I've done more detailed testing, and it seems this patch results in
> > lots of dropped frames. I'm sorry for not being more thorough earlier.
> > I'll do some more testing without this patch and might have to either
> > remove it from V2 of this series.
> >
> > I need to see if the same stability can be achieved when running
> > PLL-MIPI outside its specied range.
> 
> I've done some more (load) testing and observing the panel for dropped
> frames.
> 
> The conclusion I draw from those results is that this patch isn't
> necessary for the pinephone. It would be enough to use the correct clock
> rate based on the existing values [*]:
> - .clock   = 69000,
> + .clock   = (720 + 40 + 40 + 40) * (1440 + 18 + 10 + 17) * 60 / 1000,
> 
> I've asked in the postmarketOS community for a bit more testing. They
> already have a merge request that contains these changes [2].

This patch sounds reasonable and IMO should be merged.

Best regards,
Jernej

> 
> This means that we would continue to drive PLL-MIPI outside it's
> specified range. I have, so far, not experienced any downside of doing
> so. It seems enough to fix the ratios that are part of the first four
> patches in this series without introducing a min and max rate.
> 
> In conclusion, I'll soon (after some more feedback from the fine folks
> at postmarketOS) submit a V2 that addresses the fixes requested in the
> first four patches of this series. I'll drop the existing PATCH 5 and
> replace it with the one I sent in February [1] instead.
> 
> After that, just for fun, I'll probably look into min_rate and max_rate
> for nkm clocks and which consequences it has on the pinephone. I might
> or might not send a follow up series for that. However, if the pinephone
> runs stable without it, it's not a high priority for me.
> 
> Best regards,
>   Frank
> 
> [*] I've already submitted a patch in February '23 [1]. It was of little
> use back then because the A64's PLL-MIPI clock was not able to run
> close to that rate. But since kernel 6.6 PLL-MIPI is able to set
> it's parent rate, so that it can come quite close to the required
> rate:
>  + Panel requires 74.844 MHz with the current timings.
>  +-> tcon-data-clock rate should be 112.266 MHz (panel*24/4/4).
>   +-> PLL-MIPI rate should be 449.064 MHz (TCON0 * 4)
> 
> The 6.6 kernel the following rates are possible:
>  + PLL-MIPI: ~448.984615 MHz
>  +-> tcon-data-clock: ~112.246153
>   +-> panel: ~74.830768 MHz
> 
> Which leaves us with a vertical refresh rate of ~59.989 Hz,
> deviating less then 0.2% from the ideal 60Hz. That's probably closer
> than the accumulated accuracy of all involved components can
> reliably achieve. I'd say, let's leave it at that.
> 
> [1]: https://lore.kernel.org/lkml/20230219114553.288057-2-fr...@oltmanns.dev/
> [2]: https://gitlab.com/postmarketOS/pmaports/-/merge_requests/4645
> >
> > Best regards,
> >   Frank
> >
> > On 2023-12-20 at 16:18:49 +0100, Jernej Škrabec  
> > wrote:
> >> Dne sreda, 20. december 2023 ob 08:14:27 CET je Frank Oltmanns napisal(a):
> >>>
> >>> On 2023-12-19 at 18:04:29 +0100, Jernej Škrabec 
> >>>  wrote:
> >>> > Dne ponedeljek, 18. december 2023 ob 14:35:23 CET je Frank Oltmanns 
> >>> > napisal(a):
> >>> >> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> >>> >> Acoording to it's datasheet, the SOC requires PLL-MIPI to run at more
> >>> >> than 500 MHz.
> >>> >>
> >>> >> Therefore, change [hv]sync_(start|end) so that we reach a clock rate
> >>> >> that is high enough to drive PLL-MIPI within its limits.
> >>> >>
> >>> >> Signed-off-by: Frank Oltmanns 
> >>> >
> >>> > I'm not too sure about this patch. I see that PLL_MIPI doesn't have set
> >>> > minimum frequency limit in clock driver. If you add it, clock framework
> >>> > should find rate that is high enough and divisible with target rate.
> >>>
> >>> This one is really a tough nut. Unfortunately, the PLL_MIPI clock for
> >>> this panel has to run exactly at 6 * panel clock. Let me start by
> >>> showing the relevant part of the clock tree (this is on the pinephone
> >>> after applying the patches):
> >>> pll-video0 39360
> >>>  

Re: [PATCH 5/5] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2023-12-20 Thread Jernej Škrabec
Dne sreda, 20. december 2023 ob 08:14:27 CET je Frank Oltmanns napisal(a):
> 
> On 2023-12-19 at 18:04:29 +0100, Jernej Škrabec  
> wrote:
> > Dne ponedeljek, 18. december 2023 ob 14:35:23 CET je Frank Oltmanns 
> > napisal(a):
> >> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> >> Acoording to it's datasheet, the SOC requires PLL-MIPI to run at more
> >> than 500 MHz.
> >>
> >> Therefore, change [hv]sync_(start|end) so that we reach a clock rate
> >> that is high enough to drive PLL-MIPI within its limits.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >
> > I'm not too sure about this patch. I see that PLL_MIPI doesn't have set
> > minimum frequency limit in clock driver. If you add it, clock framework
> > should find rate that is high enough and divisible with target rate.
> 
> This one is really a tough nut. Unfortunately, the PLL_MIPI clock for
> this panel has to run exactly at 6 * panel clock. Let me start by
> showing the relevant part of the clock tree (this is on the pinephone
> after applying the patches):
> pll-video0 39360
>pll-mipi500945454
>   tcon0500945454
>  tcon-data-clock   125236363
> 
> To elaborate, tcon-data-clock has to run at 1/4 the DSI per-lane bit
> rate [1]. It's a fixed divisor
> 
> The panel I'm proposing to change is defined as this:
> 
> static const struct st7703_panel_desc xbd599_desc = {
>   .mode = _mode,
>   .lanes = 4,
>   .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
>   .format = MIPI_DSI_FMT_RGB888,
>   .init_sequence = xbd599_init_sequence,
> };
> 
> So, we have 24 bpp and 4 lanes. Therefore, the resulting requested
> tcon-data-clock rate is
> crtc_clock * 1000 * (24 / 4) / 4
> 
> tcon-data-clock therefore requests a parent rate of
> 4 * (crtc_clock * 1000 * (24 / 4) / 4)
> 
> The initial 4 is the fixed divisor between tcon0 and tcon-data-clock.
> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
> 
> Since PLL-MIPI has to run at at least at 500MHz this forces us to have a
> crtc_clock >= 83.333 MHz. The mode I'm prorposing results in a rate of
> 83.502 MHz.

This is much better explanation why this change is needed. Still, I think
adding min and max rate to PLL_MIPI would make sense, so proper rates
are guaranteed.

Anyway, do you know where are all those old values come from? And how did
you come up with new ones? I guess you can't just simply change timings,
there are probably some HW limitations? Do you know if BSP kernel support
this panel and how this situation is solved there?

> 
> If we only changed the constraints on the PLL_MIPI without changing the
> panel mode, we end up with a mismatch. This, in turn, would result in
> dropped frames, right?

From what I read, I think frame rate would be higher than 60 fps. What
exactly would happen depends on the panel.

Best regards,
Jernej

> 
> Best regards,
>   Frank
> 
> [1] Source:
> https://elixir.bootlin.com/linux/v6.6.7/source/drivers/gpu/drm/sun4i/sun4i_tcon.c#L346
> 
> >
> > Best regards,
> > Jernej
> >
> >> ---
> >>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++---
> >>  1 file changed, 7 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
> >> b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> >> index b55bafd1a8be..6886fd7f765e 100644
> >> --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> >> +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> >> @@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
> >>
> >>  static const struct drm_display_mode xbd599_mode = {
> >>.hdisplay= 720,
> >> -  .hsync_start = 720 + 40,
> >> -  .hsync_end   = 720 + 40 + 40,
> >> -  .htotal  = 720 + 40 + 40 + 40,
> >> +  .hsync_start = 720 + 65,
> >> +  .hsync_end   = 720 + 65 + 65,
> >> +  .htotal  = 720 + 65 + 65 + 65,
> >>.vdisplay= 1440,
> >> -  .vsync_start = 1440 + 18,
> >> -  .vsync_end   = 1440 + 18 + 10,
> >> -  .vtotal  = 1440 + 18 + 10 + 17,
> >> -  .clock   = 69000,
> >> +  .vsync_start = 1440 + 30,
> >> +  .vsync_end   = 1440 + 30 + 22,
> >> +  .vtotal  = 1440 + 30 + 22 + 29,
> >> +  .clock   = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
> >>.flags   = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> >>.width_mm= 68,
> >>.height_mm   = 136,
> >>
> >>
> 






Re: [PATCH 4/5] clk: sunxi-ng: a64: Add constraints on PLL-VIDEO0's n/m ratio

2023-12-20 Thread Jernej Škrabec
Dne sreda, 20. december 2023 ob 08:09:28 CET je Frank Oltmanns napisal(a):
> 
> On 2023-12-19 at 17:54:19 +0100, Jernej Škrabec  
> wrote:
> > Dne ponedeljek, 18. december 2023 ob 14:35:22 CET je Frank Oltmanns 
> > napisal(a):
> >> The Allwinner A64 manual lists the following constraint for the
> >> PLL-VIDEO0 clock: 8 <= N/M <= 25
> >>
> >> Use this constraint.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >> ---
> >>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 8 ++--
> >>  1 file changed, 6 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
> >> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> index c034ac027d1c..75d839da446c 100644
> >> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> >> @@ -68,7 +68,8 @@ static 
> >> SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
> >>   BIT(28), /* lock */
> >>   CLK_SET_RATE_UNGATE);
> >>
> >> -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, 
> >> "pll-video0",
> >> +static 
> >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO(pll_video0_clk,
> >> +  "pll-video0",
> >>"osc24M", 0x010,
> >>19200,  /* Minimum rate 
> >> */
> >>100800, /* Maximum rate 
> >> */
> >> @@ -80,7 +81,10 @@ static 
> >> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-vid
> >>29700,  /* frac rate 1 
> >> */
> >>BIT(31),/* gate */
> >>BIT(28),/* lock */
> >> -  CLK_SET_RATE_UNGATE);
> >> +  CLK_SET_RATE_UNGATE,
> >> +  CCU_FEATURE_FRACTIONAL |
> >> +  CCU_FEATURE_CLOSEST_RATE,
> >
> > Above flags are unrelated change, put them in new patch if needed.
> 
> You might notice that I am using a new macro for initializing the
> pll_video0_clk struct:
> New: SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO
> Old: SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST
> 
> Setting the two CCU_FEATURE flags is part of the old initialization
> macro.
> 
> I'll add SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_NM_RATIO_CLOSEST which
> hopefully resolves the confusion.

I'm in doubt if we need so many macros. How many users of these macro we'll 
have?
I see that R40 SoC would also need same ratio limits, but other that that, none?

Best regards,
Jernej

> 
> Thanks,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >> +  8, 25); /* min/max nm 
> >> ratio */
> >>
> >>  static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
> >>"osc24M", 0x018,
> >>
> >>
> 






Re: [PATCH 1/5] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate

2023-12-20 Thread Jernej Škrabec
Dne sreda, 20. december 2023 ob 07:58:07 CET je Frank Oltmanns napisal(a):
> Hi Jernej!
> 
> On 2023-12-19 at 17:46:08 +0100, Jernej Škrabec  
> wrote:
> > Hi Frank!
> >
> > Dne ponedeljek, 18. december 2023 ob 14:35:19 CET je Frank Oltmanns 
> > napisal(a):
> >> The Allwinner A64 manual lists the following constraints for the
> >> PLL-MIPI clock:
> >>  - M/N >= 3
> >
> > This should be "<="
> 
> Yes, good catch! I will fix it in V2.
> 
> >
> >>  - (PLL_VIDEO0)/M >= 24MHz
> >>
> >> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> >> these constraints.
> >>
> >> Signed-off-by: Frank Oltmanns 
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 23 +++
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  8 
> >>  2 files changed, 31 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index eed64547ad42..2af5c1ebd527 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -16,6 +16,20 @@ struct _ccu_nkm {
> >>unsigned long   m, min_m, max_m;
> >>  };
> >>
> >> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned 
> >> long parent,
> >> +unsigned long n, unsigned long m)
> >> +{
> >> +  struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> >> +
> >> +  if (nkm->max_mn_ratio && (m > nkm->max_mn_ratio * n))
> >> +  return false;
> >> +
> >> +  if (nkm->parent_wo_nk && (parent < nkm->parent_wo_nk * m))
> >> +  return false;
> >> +
> >> +  return true;
> >> +}
> >> +
> >>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common 
> >> *common,
> >>   struct clk_hw *parent_hw,
> >>   unsigned long *parent, 
> >> unsigned long rate,
> >> @@ -32,6 +46,9 @@ static unsigned long 
> >> ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
> >>
> >>tmp_parent = clk_hw_round_rate(parent_hw, rate 
> >> * _m / (_n * _k));
> >>
> >> +  if (!ccu_nkm_is_valid_rate(common, tmp_parent, 
> >> _n, _m))
> >> +  continue;
> >> +
> >>tmp_rate = tmp_parent * _n * _k / _m;
> >>
> >>if (ccu_is_better_rate(common, rate, tmp_rate, 
> >> best_rate) ||
> >> @@ -65,6 +82,12 @@ static unsigned long ccu_nkm_find_best(unsigned long 
> >> parent, unsigned long rate,
> >>for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
> >>for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
> >>for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> >> +  if ((common->reg == 0x040) && (_m > 3 * _n))
> >> +  break;
> >> +
> >> +  if ((common->reg == 0x040) && (parent < 
> >> 2400 * _m))
> >> +  continue;
> >> +
> >
> > You already figured this part.
> >
> >>unsigned long tmp_rate;
> >>
> >>tmp_rate = parent * _n * _k / _m;
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h 
> >> b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> index 6601defb3f38..d3d3eaf55faf 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> @@ -16,6 +16,12 @@
> >>   * struct ccu_nkm - Definition of an N-K-M clock
> >>   *
> >>   * Clocks based on the formula parent * N * K / M
> >> + *
> >> + * @max_mn_ratio: Maximum value for M / N.
> >> + * @parent_wo_nk: The minimum rate the parent must provide after applying 
> >> the divisor,
> >> + *but without applying the multipliers, i.e. the 
> >> contstraint
> >> + *   (parent rate)/M >= parent_wo_nk
> >> + *must be fulfilled.
> >>   */
> >>  struct ccu_nkm {
> >>u32 enable;
> >> @@ -27,6 +33,8 @@ struct ccu_nkm {
> >>struct ccu_mux_internal mux;
> >>
> >>unsigned intfixed_post_div;
> >> +  unsigned long   max_mn_ratio;
> >> +  unsigned long   parent_wo_nk;
> >
> > What about max_m_n_ratio and max_parent_m_ratio, to be consistent? This
> > should also allow to simplify description.
> 
> Jernej, thank you so much! This is brilliant! I was racking my brain for
> a good name but failed. Now, that I see your proposal, I don't know why
> I hadn't come up with it. It's the obvious choice.
> 
> I'd say with the new names we should be able to get rid of the comments
> describing the new struct members (also in ccu_nm.h). What are your
> thoughts on that?

Ah, I missed that only new ones are documented. Yeah, you can skip it.

Best regards,
Jernej

> 
> Best regards,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >>
> >>struct ccu_common   common;
> >>  };
> >>
> >>
> 






Re: [PATCH 5/5] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2023-12-19 Thread Jernej Škrabec
Dne ponedeljek, 18. december 2023 ob 14:35:23 CET je Frank Oltmanns napisal(a):
> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> Acoording to it's datasheet, the SOC requires PLL-MIPI to run at more
> than 500 MHz.
> 
> Therefore, change [hv]sync_(start|end) so that we reach a clock rate
> that is high enough to drive PLL-MIPI within its limits.
> 
> Signed-off-by: Frank Oltmanns 

I'm not too sure about this patch. I see that PLL_MIPI doesn't have set
minimum frequency limit in clock driver. If you add it, clock framework
should find rate that is high enough and divisible with target rate.

Best regards,
Jernej  

> ---
>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
> b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> index b55bafd1a8be..6886fd7f765e 100644
> --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> @@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
>  
>  static const struct drm_display_mode xbd599_mode = {
>   .hdisplay= 720,
> - .hsync_start = 720 + 40,
> - .hsync_end   = 720 + 40 + 40,
> - .htotal  = 720 + 40 + 40 + 40,
> + .hsync_start = 720 + 65,
> + .hsync_end   = 720 + 65 + 65,
> + .htotal  = 720 + 65 + 65 + 65,
>   .vdisplay= 1440,
> - .vsync_start = 1440 + 18,
> - .vsync_end   = 1440 + 18 + 10,
> - .vtotal  = 1440 + 18 + 10 + 17,
> - .clock   = 69000,
> + .vsync_start = 1440 + 30,
> + .vsync_end   = 1440 + 30 + 22,
> + .vtotal  = 1440 + 30 + 22 + 29,
> + .clock   = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
>   .flags   = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
>   .width_mm= 68,
>   .height_mm   = 136,
> 
> 






Re: [PATCH 4/5] clk: sunxi-ng: a64: Add constraints on PLL-VIDEO0's n/m ratio

2023-12-19 Thread Jernej Škrabec
Dne ponedeljek, 18. december 2023 ob 14:35:22 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraint for the
> PLL-VIDEO0 clock: 8 <= N/M <= 25
> 
> Use this constraint.
> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index c034ac027d1c..75d839da446c 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -68,7 +68,8 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, 
> "pll-audio-base",
>  BIT(28), /* lock */
>  CLK_SET_RATE_UNGATE);
>  
> -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, 
> "pll-video0",
> +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO(pll_video0_clk,
> + "pll-video0",
>   "osc24M", 0x010,
>   19200,  /* Minimum rate 
> */
>   100800, /* Maximum rate 
> */
> @@ -80,7 +81,10 @@ static 
> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-vid
>   29700,  /* frac rate 1 
> */
>   BIT(31),/* gate */
>   BIT(28),/* lock */
> - CLK_SET_RATE_UNGATE);
> + CLK_SET_RATE_UNGATE,
> + CCU_FEATURE_FRACTIONAL |
> + CCU_FEATURE_CLOSEST_RATE,

Above flags are unrelated change, put them in new patch if needed.

Best regards,
Jernej

> + 8, 25); /* min/max nm 
> ratio */
>  
>  static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
>   "osc24M", 0x018,
> 
> 






Re: [PATCH 3/5] clk: sunxi-ng: nm: Support constraints on n/m ratio and parent rate

2023-12-19 Thread Jernej Škrabec
Dne ponedeljek, 18. december 2023 ob 14:35:21 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraint for the
> PLL-VIDEO0 clock: 8 <= N/M <= 25
> 
> The PLL-MIPI clock is implemented as ccu_nm. Therefore, add support for
> this constraint.
> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/clk/sunxi-ng/ccu_nm.c | 21 +++--
>  drivers/clk/sunxi-ng/ccu_nm.h | 34 --
>  2 files changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
> index ffac3deb89d6..cfc6981e398b 100644
> --- a/drivers/clk/sunxi-ng/ccu_nm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nm.c
> @@ -27,6 +27,19 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent,
>   return rate;
>  }
>  
> +static bool ccu_nm_is_valid_rate(struct ccu_common *common, unsigned long n, 
> unsigned long m)
> +{
> + struct ccu_nm *nm = container_of(common, struct ccu_nm, common);
> +
> + if (nm->max_nm_ratio && (n > nm->max_nm_ratio * m))
> + return false;
> +
> + if (nm->min_nm_ratio && (n < nm->min_nm_ratio * m))
> + return false;
> +
> + return true;
> +}
> +
>  static unsigned long ccu_nm_find_best(struct ccu_common *common, unsigned 
> long parent,
> unsigned long rate, struct _ccu_nm *nm)
>  {
> @@ -36,8 +49,12 @@ static unsigned long ccu_nm_find_best(struct ccu_common 
> *common, unsigned long p
>  
>   for (_n = nm->min_n; _n <= nm->max_n; _n++) {
>   for (_m = nm->min_m; _m <= nm->max_m; _m++) {
> - unsigned long tmp_rate = ccu_nm_calc_rate(parent,
> -   _n, _m);
> + unsigned long tmp_rate;
> +
> + if (!ccu_nm_is_valid_rate(common, _n, _m))
> + continue;
> +
> + tmp_rate = ccu_nm_calc_rate(parent, _n, _m);
>  
>   if (ccu_is_better_rate(common, rate, tmp_rate, 
> best_rate)) {
>   best_rate = tmp_rate;
> diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h
> index 93c11693574f..0075df6d9697 100644
> --- a/drivers/clk/sunxi-ng/ccu_nm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nm.h
> @@ -31,6 +31,8 @@ struct ccu_nm {
>   unsigned intfixed_post_div;
>   unsigned intmin_rate;
>   unsigned intmax_rate;
> + unsigned long   min_nm_ratio; /* minimum value for m/n */
> + unsigned long   max_nm_ratio; /* maximum value for m/n */

Comment is wrong, it should be "n/m". For consistency with nkm patch,
min_n_m_ratio and max_n_m_ratio.

Best regards,
Jernej

>  
>   struct ccu_common   common;
>  };
> @@ -108,7 +110,8 @@ struct ccu_nm {
>   },  \
>   }
>  
> -#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name,
> \
> +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO(  
> \
> +  _struct, _name,\
>_parent, _reg, \
>_min_rate, _max_rate,  \
>_nshift, _nwidth,  \
> @@ -117,7 +120,9 @@ struct ccu_nm {
>_frac_rate_0,  \
>_frac_rate_1,  \
>_gate, _lock, _flags,  \
> -  _features) \
> +  _features, \
> +  _min_nm_ratio, \
> +  _max_nm_ratio) \
>   struct ccu_nm _struct = {   \
>   .enable = _gate,\
>   .lock   = _lock,\
> @@ -128,6 +133,8 @@ struct ccu_nm {
> _frac_rate_1),\
>   .min_rate   = _min_rate,\
>   .max_rate   = _max_rate,\
> + .min_nm_ratio   = _min_nm_ratio,\
> + .max_nm_ratio   = _max_nm_ratio,\
>   .common = { \
>   .reg= _reg, \
>   .features   = _features,\
> @@ -138,6 +145,29 @@ struct ccu_nm {
>   },  \
>   }
>  
> +#define 

Re: [PATCH 2/5] clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate

2023-12-19 Thread Jernej Škrabec
Dne ponedeljek, 18. december 2023 ob 14:35:20 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N >= 3

Same as in previous patch, should be "<=".

Best regards,
Jernej

>  - (PLL_VIDEO0)/M >= 24MHz
> 
> Use these constraints.
> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index 8951ffc14ff5..c034ac027d1c 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -176,6 +176,8 @@ static struct ccu_nkm pll_mipi_clk = {
>   .n  = _SUNXI_CCU_MULT(8, 4),
>   .k  = _SUNXI_CCU_MULT_MIN(4, 2, 2),
>   .m  = _SUNXI_CCU_DIV(0, 4),
> + .max_mn_ratio   = 3,
> + .parent_wo_nk   = 2400,
>   .common = {
>   .reg= 0x040,
>   .hw.init= CLK_HW_INIT("pll-mipi", "pll-video0",
> 
> 






Re: [PATCH 1/5] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate

2023-12-19 Thread Jernej Škrabec
Hi Frank!

Dne ponedeljek, 18. december 2023 ob 14:35:19 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N >= 3

This should be "<="

>  - (PLL_VIDEO0)/M >= 24MHz
> 
> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> these constraints.
> 
> Signed-off-by: Frank Oltmanns 
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 23 +++
>  drivers/clk/sunxi-ng/ccu_nkm.h |  8 
>  2 files changed, 31 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index eed64547ad42..2af5c1ebd527 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -16,6 +16,20 @@ struct _ccu_nkm {
>   unsigned long   m, min_m, max_m;
>  };
>  
> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long 
> parent,
> +   unsigned long n, unsigned long m)
> +{
> + struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> +
> + if (nkm->max_mn_ratio && (m > nkm->max_mn_ratio * n))
> + return false;
> +
> + if (nkm->parent_wo_nk && (parent < nkm->parent_wo_nk * m))
> + return false;
> +
> + return true;
> +}
> +
>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common 
> *common,
>  struct clk_hw *parent_hw,
>  unsigned long *parent, 
> unsigned long rate,
> @@ -32,6 +46,9 @@ static unsigned long 
> ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
>  
>   tmp_parent = clk_hw_round_rate(parent_hw, rate 
> * _m / (_n * _k));
>  
> + if (!ccu_nkm_is_valid_rate(common, tmp_parent, 
> _n, _m))
> + continue;
> +
>   tmp_rate = tmp_parent * _n * _k / _m;
>  
>   if (ccu_is_better_rate(common, rate, tmp_rate, 
> best_rate) ||
> @@ -65,6 +82,12 @@ static unsigned long ccu_nkm_find_best(unsigned long 
> parent, unsigned long rate,
>   for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
>   for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
>   for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> + if ((common->reg == 0x040) && (_m > 3 * _n))
> + break;
> +
> + if ((common->reg == 0x040) && (parent < 
> 2400 * _m))
> + continue;
> +

You already figured this part.

>   unsigned long tmp_rate;
>  
>   tmp_rate = parent * _n * _k / _m;
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index 6601defb3f38..d3d3eaf55faf 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -16,6 +16,12 @@
>   * struct ccu_nkm - Definition of an N-K-M clock
>   *
>   * Clocks based on the formula parent * N * K / M
> + *
> + * @max_mn_ratio:Maximum value for M / N.
> + * @parent_wo_nk:The minimum rate the parent must provide after applying 
> the divisor,
> + *   but without applying the multipliers, i.e. the 
> contstraint
> + *  (parent rate)/M >= parent_wo_nk
> + *   must be fulfilled.
>   */
>  struct ccu_nkm {
>   u32 enable;
> @@ -27,6 +33,8 @@ struct ccu_nkm {
>   struct ccu_mux_internal mux;
>  
>   unsigned intfixed_post_div;
> + unsigned long   max_mn_ratio;
> + unsigned long   parent_wo_nk;

What about max_m_n_ratio and max_parent_m_ratio, to be consistent? This
should also allow to simplify description.

Best regards,
Jernej

>  
>   struct ccu_common   common;
>  };
> 
> 






Re: [PATCH v2 04/20] drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c: remove I2C_CLASS_DDC support

2023-11-18 Thread Jernej Škrabec
Dne sobota, 18. november 2023 ob 18:42:04 CET je Heiner Kallweit napisal(a):
> After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
> olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
> Class-based device auto-detection is a legacy mechanism and shouldn't
> be used in new code. So we can remove this class completely now.
> 
> Preferably this series should be applied via the i2c tree.
> 
> Signed-off-by: Heiner Kallweit 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> 
> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c |1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c 
> b/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
> index d1a65a921..f5f62eb0e 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
> @@ -302,7 +302,6 @@ int sun4i_hdmi_i2c_create(struct device *dev, struct 
> sun4i_hdmi *hdmi)
>   return -ENOMEM;
>  
>   adap->owner = THIS_MODULE;
> - adap->class = I2C_CLASS_DDC;
>   adap->algo = _hdmi_i2c_algorithm;
>   strscpy(adap->name, "sun4i_hdmi_i2c adapter", sizeof(adap->name));
>   i2c_set_adapdata(adap, hdmi);
> 
> 






Re: [PATCH 5/7] drm/sun4i: dw-hdmi: Split driver registration

2023-10-13 Thread Jernej Škrabec
Dne četrtek, 05. oktober 2023 ob 10:43:14 CEST je Maxime Ripard napisal(a):
> On Mon, Sep 25, 2023 at 05:07:45PM +0200, Jernej Škrabec wrote:
> > Dne ponedeljek, 25. september 2023 ob 09:47:15 CEST je Maxime Ripard 
> > napisal(a):
> > > On Sun, Sep 24, 2023 at 09:26:02PM +0200, Jernej Skrabec wrote:
> > > > There is no reason to register two drivers in same place. Using macro
> > > > lowers amount of boilerplate code.
> > > 
> > > There's one actually: you can't have several module_init functions in
> > > the some module, and both files are compiled into the same module.
> > 
> > Yeah, I figured as much. However, I think code clean up is good enough 
> > reason
> > to add hidden option in Kconfig and extra entry in Makefile (in v2).
> > 
> > Do you agree?
> 
> Yeah, I don't know. Adding more modules makes it more difficult to
> handle (especially autoloading) without a clear argument why.
> Module_init is simple enough as it is currently, maybe we should just
> add a comment to make it clearer?

I'll just drop this patch then. While I think autoloading works pretty good
these days and cleaner code is nice, it can certainly cause some issues while
packaging.

Best regards,
Jernej





Re: [PATCH 3/7] drm/sun4i: dw-hdmi: Switch to bridge functions

2023-09-25 Thread Jernej Škrabec
Dne ponedeljek, 25. september 2023 ob 09:57:22 CEST je Maxime Ripard napisal(a):
> Hi,
> 
> On Sun, Sep 24, 2023 at 09:26:00PM +0200, Jernej Skrabec wrote:
> > Since ddc-en property handling was moved from sun8i dw-hdmi driver to
> > display connector driver, probe order of drivers determines if EDID is
> > properly read at boot time or not.
> > 
> > In order to fix this, let's switch to bridge functions which allows us
> > to build proper chain and defer execution until all drivers are probed.
> > 
> > Fixes: 920169041baa ("drm/sun4i: dw-hdmi: Fix ddc-en GPIO consumer 
> > conflict")
> > Signed-off-by: Jernej Skrabec 
> > ---
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 114 +-
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |   5 ++
> >  2 files changed, 117 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c 
> > b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > index 8f8d3bdba5ce..93831cdf1917 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> > @@ -8,14 +8,82 @@
> >  #include 
> >  #include 
> >  
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> >  
> > +#include 
> > +
> >  #include "sun8i_dw_hdmi.h"
> >  #include "sun8i_tcon_top.h"
> >  
> > +#define bridge_to_sun8i_dw_hdmi(x) \
> > +   container_of(x, struct sun8i_dw_hdmi, enc_bridge)
> > +
> > +static int sun8i_hdmi_enc_attach(struct drm_bridge *bridge,
> > +enum drm_bridge_attach_flags flags)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +
> > +   return drm_bridge_attach(>encoder, hdmi->hdmi_bridge,
> > +>enc_bridge, flags);
> > +}
> > +
> > +static void sun8i_hdmi_enc_detach(struct drm_bridge *bridge)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +
> > +   cec_notifier_conn_unregister(hdmi->cec_notifier);
> > +   hdmi->cec_notifier = NULL;
> > +}
> > +
> > +static void sun8i_hdmi_enc_hpd_notify(struct drm_bridge *bridge,
> > + enum drm_connector_status status)
> > +{
> > +   struct sun8i_dw_hdmi *hdmi = bridge_to_sun8i_dw_hdmi(bridge);
> > +   struct edid *edid;
> > +
> > +   if (!hdmi->cec_notifier)
> > +   return;
> > +
> > +   if (status == connector_status_connected) {
> > +   edid = drm_bridge_get_edid(hdmi->hdmi_bridge, hdmi->connector);
> > +   if (edid)
> > +   cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier,
> > +edid);
> > +   } else {
> > +   cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> > +   }
> > +}
> > +
> > +static int sun8i_hdmi_enc_atomic_check(struct drm_bridge *bridge,
> > +  struct drm_bridge_state *bridge_state,
> > +  struct drm_crtc_state *crtc_state,
> > +  struct drm_connector_state *conn_state)
> > +{
> > +   struct drm_connector_state *old_conn_state =
> > +   drm_atomic_get_old_connector_state(conn_state->state,
> > +  conn_state->connector);
> > +
> > +   if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, 
> > conn_state))
> > +   crtc_state->mode_changed = true;
> > +
> > +   return 0;
> > +}
> > +
> > +static const struct drm_bridge_funcs sun8i_hdmi_enc_bridge_funcs = {
> > +   .attach = sun8i_hdmi_enc_attach,
> > +   .detach = sun8i_hdmi_enc_detach,
> > +   .hpd_notify = sun8i_hdmi_enc_hpd_notify,
> > +   .atomic_check = sun8i_hdmi_enc_atomic_check,
> > +   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> > +   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +   .atomic_reset = drm_atomic_helper_bridge_reset,
> > +};
> > +
> >  static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
> >struct drm_display_mode *mode,
> >struct drm_display_mode *adj_mode)
> > @@ -99,6 +167,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct 
> > device *master,
> >  {
> > struct platform_device *pdev = to_platform_device(dev);
> > struct dw_hdmi_plat_data *plat_data;
> > +   struct cec_connector_info conn_info;
> > +   struct drm_connector *connector;
> > struct drm_device *drm = data;
> > struct device_node *phy_node;
> > struct drm_encoder *encoder;
> > @@ -187,18 +257,57 @@ static int sun8i_dw_hdmi_bind(struct device *dev, 
> > struct device *master,
> >  
> > plat_data->mode_valid = hdmi->quirks->mode_valid;
> > plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe;
> > +   plat_data->output_port = 1;
> > sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
> >  
> > platform_set_drvdata(pdev, hdmi);
> >  
> > -   hdmi->hdmi = dw_hdmi_bind(pdev, encoder, 

Re: [PATCH 5/7] drm/sun4i: dw-hdmi: Split driver registration

2023-09-25 Thread Jernej Škrabec
Dne ponedeljek, 25. september 2023 ob 09:47:15 CEST je Maxime Ripard napisal(a):
> On Sun, Sep 24, 2023 at 09:26:02PM +0200, Jernej Skrabec wrote:
> > There is no reason to register two drivers in same place. Using macro
> > lowers amount of boilerplate code.
> 
> There's one actually: you can't have several module_init functions in
> the some module, and both files are compiled into the same module.

Yeah, I figured as much. However, I think code clean up is good enough reason
to add hidden option in Kconfig and extra entry in Makefile (in v2).

Do you agree?

Best regards,
Jernej 






Re: [PATCH] drm/sun4i: Add error handling in sun4i_layer_init_one()

2023-09-24 Thread Jernej Škrabec
Hi!

Dne nedelja, 24. september 2023 ob 09:42:16 CEST je liuhaoran napisal(a):
> This patch adds error-handling for the drm_plane_create_alpha_property()
> and drm_plane_create_zpos_property() inside the dw_hdmi_imx_probe().

dw_hdmi_imx_probe() is not from this driver.

Best regards,
Jernej

> 
> Signed-off-by: liuhaoran 
> ---
>  drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c 
> b/drivers/gpu/drm/sun4i/sun4i_layer.c
> index 98f3176366c0..a3343afb7935 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> @@ -224,9 +224,22 @@ static struct sun4i_layer *sun4i_layer_init_one(struct 
> drm_device *drm,
>   drm_plane_helper_add(>plane,
>_backend_layer_helper_funcs);
>  
> - drm_plane_create_alpha_property(>plane);
> - drm_plane_create_zpos_property(>plane, layer->id,
> -0, SUN4I_BACKEND_NUM_LAYERS - 1);
> + ret = drm_plane_create_alpha_property(>plane);
> +
> + if (ret) {
> + dev_err(drm->dev, "Failed to install alpha property,
> + rc = %d\n", ret);
> + return ERR_PTR(ret);
> + }
> +
> + ret = drm_plane_create_zpos_property(>plane, layer->id, 0,
> +  SUN4I_BACKEND_NUM_LAYERS - 1);
> +
> + if (ret) {
> + dev_err(drm->dev, "Failed to install zpos property,
> + rc = %d\n", ret);
> + return ERR_PTR(ret);
> + }
>  
>   return layer;
>  }
> 






Re: [PATCH RFC v2 07/37] drm/connector: hdmi: Add HDMI compute clock helper

2023-09-20 Thread Jernej Škrabec
Hi Maxime!

Dne sreda, 20. september 2023 ob 16:35:22 CEST je Maxime Ripard napisal(a):
> A lot of HDMI drivers have some variation of the formula to calculate
> the TMDS character rate from a mode, but few of them actually take all
> parameters into account.
> 
> Let's create a helper to provide that rate taking all parameters into
> account.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/drm_connector.c | 31 +++
>  include/drm/drm_connector.h |  5 +
>  2 files changed, 36 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index b01cb4783ea6..4c1af97971bb 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2944,6 +2944,37 @@ void drm_connector_update_privacy_screen(const struct 
> drm_connector_state *conne
>  }
>  EXPORT_SYMBOL(drm_connector_update_privacy_screen);
>  
> +/**
> + * drm_connector_hdmi_compute_mode_clock() - Computes the TMDS Character Rate
> + * @mode: Display mode to compute the clock for
> + * @bpc: Bits per character
> + * @fmt: Output Pixel Format used
> + *
> + * Returns the TMDS Character Rate for a given mode, bpc count and output 
> format.
> + *
> + * RETURNS:
> + * The TMDS Character Rate, in Hertz
> + */
> +unsigned long long
> +drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
> +   unsigned int bpc,
> +   enum hdmi_colorspace fmt)
> +{
> + unsigned long long clock = mode->clock * 1000ULL;
> +
> + if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> + clock = clock * 2;
> +
> + if (fmt == HDMI_COLORSPACE_YUV422)
> + bpc = 8;

I think you're missing YUV420 handling, which needs half of clock speed. But
this is a thing of HDMI2.

Best regards,
Jernej

> +
> + clock = clock * bpc;
> + do_div(clock, 8);
> +
> + return clock;
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_compute_mode_clock);
> +
>  int drm_connector_set_obj_prop(struct drm_mode_object *obj,
>   struct drm_property *property,
>   uint64_t value)
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a66cb4e35d7b..d74e9c64ee88 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -38,6 +38,7 @@ struct drm_connector_helper_funcs;
>  struct drm_modeset_acquire_ctx;
>  struct drm_device;
>  struct drm_crtc;
> +struct drm_display_mode;
>  struct drm_encoder;
>  struct drm_panel;
>  struct drm_property;
> @@ -2115,6 +2116,10 @@ void 
> drm_connector_attach_privacy_screen_properties(struct drm_connector *conn);
>  void drm_connector_attach_privacy_screen_provider(
>   struct drm_connector *connector, struct drm_privacy_screen *priv);
>  void drm_connector_update_privacy_screen(const struct drm_connector_state 
> *connector_state);
> +unsigned long long
> +drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
> +   unsigned int bpc,
> +   enum hdmi_colorspace fmt);
>  
>  /**
>   * struct drm_tile_group - Tile group metadata
> 
> 






Re: [PATCH RFC v2 11/37] drm/connector: hdmi: Add Infoframes generation

2023-09-20 Thread Jernej Škrabec
Dne sreda, 20. september 2023 ob 16:35:26 CEST je Maxime Ripard napisal(a):
> Infoframes in KMS is usually handled by a bunch of low-level helpers
> that require quite some boilerplate for drivers. This leads to
> discrepancies with how drivers generate them, and which are actually
> sent.
> 
> Now that we have everything needed to generate them in the HDMI
> connector state, we can generate them in our common logic so that
> drivers can simply reuse what we precomputed.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/Kconfig   |   1 +
>  drivers/gpu/drm/drm_atomic_state_helper.c | 327 
> ++
>  drivers/gpu/drm/drm_connector.c   |   9 +
>  include/drm/drm_atomic_state_helper.h |   6 +
>  include/drm/drm_connector.h   | 131 
>  5 files changed, 474 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index ab9ef1c20349..10caf2dcce93 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -99,6 +99,7 @@ config DRM_KUNIT_TEST
>  config DRM_KMS_HELPER
>   tristate
>   depends on DRM
> + select DRM_DISPLAY_HDMI_HELPER
>   help
> CRTC helpers for KMS drivers.
>  
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 2f85422cccd4..5bbdd2f7d306 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -38,6 +38,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include 
>  #include 
>  
> @@ -839,6 +841,142 @@ hdmi_compute_config(const struct drm_connector 
> *connector,
>   return -EINVAL;
>  }
>  
> +static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
> +struct drm_connector_state *state)
> +{
> + const struct drm_display_mode *mode =
> + connector_state_get_adjusted_mode(state);
> + struct drm_connector_hdmi_infoframe *infoframe =
> + >hdmi.infoframes.avi;
> + struct hdmi_avi_infoframe *frame =
> + >data.avi;
> + bool is_lim_range =
> + drm_atomic_helper_connector_hdmi_is_full_range(connector,
> +state);
> + enum hdmi_quantization_range rgb_quant_range =
> + is_lim_range ? HDMI_QUANTIZATION_RANGE_FULL : 
> HDMI_QUANTIZATION_RANGE_LIMITED;

While usage of is_lim_range is correct, its name is off. Replace lim with full.

Best regards,
Jernej

> + int ret;
> +
> + ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
> + if (ret)
> + return ret;
> +
> + frame->colorspace = state->hdmi.output_format;
> +
> + drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, 
> rgb_quant_range);
> + drm_hdmi_avi_infoframe_colorimetry(frame, state);
> + drm_hdmi_avi_infoframe_bars(frame, state);
> +
> + infoframe->set = true;
> +
> + return 0;
> +}
> +
> +static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
> +struct drm_connector_state *state)
> +{
> + struct drm_connector_hdmi_infoframe *infoframe =
> + >hdmi.infoframes.spd;
> + struct hdmi_spd_infoframe *frame =
> + >data.spd;
> + int ret;
> +
> + ret = hdmi_spd_infoframe_init(frame,
> +   connector->hdmi.vendor,
> +   connector->hdmi.product);
> + if (ret)
> + return ret;
> +
> + frame->sdi = HDMI_SPD_SDI_PC;
> +
> + infoframe->set = true;
> +
> + return 0;
> +}
> +
> +static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
> +struct drm_connector_state *state)
> +{
> + struct drm_connector_hdmi_infoframe *infoframe =
> + >hdmi.infoframes.drm;
> + struct hdmi_drm_infoframe *frame =
> + >data.drm;
> + int ret;
> +
> + if (connector->max_bpc < 10)
> + return 0;
> +
> + if (!state->hdr_output_metadata)
> + return 0;
> +
> + ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
> + if (ret)
> + return ret;
> +
> + infoframe->set = true;
> +
> + return 0;
> +}
> +
> +static int hdmi_generate_vendor_infoframe(const struct drm_connector 
> *connector,
> +   struct drm_connector_state *state)
> +{
> + const struct drm_display_mode *mode =
> + connector_state_get_adjusted_mode(state);
> + struct drm_connector_hdmi_infoframe *infoframe =
> + >hdmi.infoframes.vendor;
> + struct hdmi_vendor_infoframe *frame =
> + >data.vendor.hdmi;
> + int ret;
> +
> + ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, 
> mode);
> + if (ret == -EINVAL)
> + return 0;
> + else
> +   

Re: [RFT PATCH 2/6] drm: Call drm_atomic_helper_shutdown() at shutdown time for misc drivers

2023-09-05 Thread Jernej Škrabec
Dne sobota, 02. september 2023 ob 01:39:53 CEST je Douglas Anderson 
napisal(a):
> Based on grepping through the source code these drivers appear to be
> missing a call to drm_atomic_helper_shutdown() at system shutdown
> time. Among other things, this means that if a panel is in use that it
> won't be cleanly powered off at system shutdown time.
> 
> The fact that we should call drm_atomic_helper_shutdown() in the case
> of OS shutdown/restart comes straight out of the kernel doc "driver
> instance overview" in drm_drv.c.
> 
> All of the drivers in this patch were fairly straightforward to fix
> since they already had a call to drm_atomic_helper_shutdown() at
> remove/unbind time but were just lacking one at system shutdown. The
> only hitch is that some of these drivers use the component model to
> register/unregister their DRM devices. The shutdown callback is part
> of the original device. The typical solution here, based on how other
> DRM drivers do this, is to keep track of whether the device is bound
> based on drvdata. In most cases the drvdata is the drm_device, so we
> can just make sure it is NULL when the device is not bound. In some
> drivers, this required minor code changes. To make things simpler,
> drm_atomic_helper_shutdown() has been modified to consider a NULL
> drm_device as a noop in the patch ("drm/atomic-helper:
> drm_atomic_helper_shutdown(NULL) should be a noop").
> 
> Suggested-by: Maxime Ripard 
> Signed-off-by: Douglas Anderson 
> ---
> This commit is only compile-time tested.
> 
> Note that checkpatch yells that "drivers/gpu/drm/tiny/cirrus.c" is
> marked as 'obsolete', but it seems silly not to include the fix if
> it's already been written. If someone wants me to take that out,
> though, I can.
> 
>  drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 9 +
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 7 +++
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 1 +
>  drivers/gpu/drm/arm/hdlcd_drv.c | 6 ++
>  drivers/gpu/drm/arm/malidp_drv.c| 6 ++
>  drivers/gpu/drm/ast/ast_drv.c   | 6 ++
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c| 6 ++
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c   | 8 
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 6 ++
>  drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 6 ++
>  drivers/gpu/drm/logicvc/logicvc_drm.c   | 9 +
>  drivers/gpu/drm/loongson/lsdc_drv.c | 6 ++
>  drivers/gpu/drm/mcde/mcde_drv.c | 9 +
>  drivers/gpu/drm/omapdrm/omap_drv.c  | 8 
>  drivers/gpu/drm/qxl/qxl_drv.c   | 7 +++
>  drivers/gpu/drm/sti/sti_drv.c   | 7 +++
>  drivers/gpu/drm/sun4i/sun4i_drv.c   | 6 ++

For sun4i:
Tested-by: Jernej Skrabec 
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

>  drivers/gpu/drm/tiny/bochs.c| 6 ++
>  drivers/gpu/drm/tiny/cirrus.c   | 6 ++
>  19 files changed, 125 insertions(+)





Re: [PATCH v2 1/2] pwm: Manage owner assignment implicitly for drivers

2023-08-04 Thread Jernej Škrabec
Dne petek, 04. avgust 2023 ob 16:27:06 CEST je Uwe Kleine-König napisal(a):
> Instead of requiring each driver to care for assigning the owner member
> of struct pwm_ops, handle that implicitly using a macro. Note that the
> owner member has to be moved to struct pwm_chip, as the ops structure
> usually lives in read-only memory and so cannot be modified.
> 
> The upside is that new lowlevel drivers cannot forget the assignment and
> save one line each. The pwm-crc driver didn't assign .owner, that's not
> a problem in practise though as the driver cannot be compiled as a
> module.
> 
> Signed-off-by: Uwe Kleine-König 
> ---
>  drivers/gpio/gpio-mvebu.c |  1 -
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c |  1 -
>  drivers/leds/rgb/leds-qcom-lpg.c  |  1 -
>  drivers/pwm/core.c| 24 ++--
>  drivers/pwm/pwm-ab8500.c  |  1 -
>  drivers/pwm/pwm-apple.c   |  1 -
>  drivers/pwm/pwm-atmel-hlcdc.c |  1 -
>  drivers/pwm/pwm-atmel-tcb.c   |  1 -
>  drivers/pwm/pwm-atmel.c   |  1 -
>  drivers/pwm/pwm-bcm-iproc.c   |  1 -
>  drivers/pwm/pwm-bcm-kona.c|  1 -
>  drivers/pwm/pwm-bcm2835.c |  1 -
>  drivers/pwm/pwm-berlin.c  |  1 -
>  drivers/pwm/pwm-brcmstb.c |  1 -
>  drivers/pwm/pwm-clk.c |  1 -
>  drivers/pwm/pwm-clps711x.c|  1 -
>  drivers/pwm/pwm-cros-ec.c |  1 -
>  drivers/pwm/pwm-dwc.c |  1 -
>  drivers/pwm/pwm-ep93xx.c  |  1 -
>  drivers/pwm/pwm-fsl-ftm.c |  1 -
>  drivers/pwm/pwm-hibvt.c   |  1 -
>  drivers/pwm/pwm-img.c |  1 -
>  drivers/pwm/pwm-imx-tpm.c |  1 -
>  drivers/pwm/pwm-imx1.c|  1 -
>  drivers/pwm/pwm-imx27.c   |  1 -
>  drivers/pwm/pwm-intel-lgm.c   |  1 -
>  drivers/pwm/pwm-iqs620a.c |  1 -
>  drivers/pwm/pwm-jz4740.c  |  1 -
>  drivers/pwm/pwm-keembay.c |  1 -
>  drivers/pwm/pwm-lp3943.c  |  1 -
>  drivers/pwm/pwm-lpc18xx-sct.c |  1 -
>  drivers/pwm/pwm-lpc32xx.c |  1 -
>  drivers/pwm/pwm-lpss.c|  1 -
>  drivers/pwm/pwm-mediatek.c|  1 -
>  drivers/pwm/pwm-meson.c   |  1 -
>  drivers/pwm/pwm-microchip-core.c  |  1 -
>  drivers/pwm/pwm-mtk-disp.c|  1 -
>  drivers/pwm/pwm-mxs.c |  1 -
>  drivers/pwm/pwm-ntxec.c   |  1 -
>  drivers/pwm/pwm-omap-dmtimer.c|  1 -
>  drivers/pwm/pwm-pca9685.c |  1 -
>  drivers/pwm/pwm-pxa.c |  1 -
>  drivers/pwm/pwm-raspberrypi-poe.c |  1 -
>  drivers/pwm/pwm-rcar.c|  1 -
>  drivers/pwm/pwm-renesas-tpu.c |  1 -
>  drivers/pwm/pwm-rockchip.c|  1 -
>  drivers/pwm/pwm-rz-mtu3.c |  1 -
>  drivers/pwm/pwm-samsung.c |  1 -
>  drivers/pwm/pwm-sifive.c  |  1 -
>  drivers/pwm/pwm-sl28cpld.c|  1 -
>  drivers/pwm/pwm-spear.c   |  1 -
>  drivers/pwm/pwm-sprd.c|  1 -
>  drivers/pwm/pwm-sti.c |  1 -
>  drivers/pwm/pwm-stm32-lp.c|  1 -
>  drivers/pwm/pwm-stm32.c   |  1 -
>  drivers/pwm/pwm-stmpe.c   |  1 -
>  drivers/pwm/pwm-sun4i.c   |  1 -

For sun4i:
Acked-by: Jernej Skrabec 

Best regards,
Jernej

>  drivers/pwm/pwm-sunplus.c |  1 -
>  drivers/pwm/pwm-tegra.c   |  1 -
>  drivers/pwm/pwm-tiecap.c  |  1 -
>  drivers/pwm/pwm-tiehrpwm.c|  1 -
>  drivers/pwm/pwm-twl-led.c |  2 --
>  drivers/pwm/pwm-twl.c |  2 --
>  drivers/pwm/pwm-visconti.c|  1 -
>  drivers/pwm/pwm-vt8500.c  |  1 -
>  drivers/pwm/pwm-xilinx.c  |  1 -
>  drivers/staging/greybus/pwm.c |  1 -
>  include/linux/pwm.h   | 10 ++





Re: [PATCH v4 2/4] ARM: dts: sunxi: rename tcon's clock output

2023-05-18 Thread Jernej Škrabec
Dne petek, 05. maj 2023 ob 07:21:08 CEST je Roman Beranek napisal(a):
> While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
> outputs, this doesn't hold for DSI. According manuals from Allwinner,
> DCLK is an abbreviation of Data Clock, not dotclock, so go with that
> instead.
> 
> Signed-off-by: Roman Beranek 

Applied, thanks!

Best regards,
Jernej




Re: [PATCH v4 1/4] clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux

2023-05-18 Thread Jernej Škrabec
Dne petek, 05. maj 2023 ob 07:21:07 CEST je Roman Beranek napisal(a):
> TCON0's source clock can be fed from either PLL_MIPI, or PLL_VIDEO0(2X),
> however MIPI DSI output only seems to work when PLL_MIPI is selected and
> thus the choice must be hardcoded in.
> 
> Currently, this driver can't propagate rate change from N-K-M clocks
> (such as PLL_MIPI) upwards. This prevents PLL_VIDEO0 from participating
> in setting of the TCON0 data clock rate, limiting the precision with
> which a target pixel clock can be matched.
> 
> For outputs with fixed TCON0 divider, that is DSI and LVDS, the dotclock
> can deviate up to 8% off target.
> 
> Signed-off-by: Roman Beranek 

Applied, thanks!

Best regards,
Jernej




Re: [PATCH v4 2/4] ARM: dts: sunxi: rename tcon's clock output

2023-05-10 Thread Jernej Škrabec
Dne petek, 05. maj 2023 ob 07:21:08 CEST je Roman Beranek napisal(a):
> While the rate of TCON0's DCLK matches dotclock for parallel and LVDS
> outputs, this doesn't hold for DSI. According manuals from Allwinner,
> DCLK is an abbreviation of Data Clock, not dotclock, so go with that
> instead.
> 
> Signed-off-by: Roman Beranek 

Acked-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v4 1/4] clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux

2023-05-10 Thread Jernej Škrabec
Dne petek, 05. maj 2023 ob 07:21:07 CEST je Roman Beranek napisal(a):
> TCON0's source clock can be fed from either PLL_MIPI, or PLL_VIDEO0(2X),
> however MIPI DSI output only seems to work when PLL_MIPI is selected and
> thus the choice must be hardcoded in.
> 
> Currently, this driver can't propagate rate change from N-K-M clocks
> (such as PLL_MIPI) upwards. This prevents PLL_VIDEO0 from participating
> in setting of the TCON0 data clock rate, limiting the precision with
> which a target pixel clock can be matched.
> 
> For outputs with fixed TCON0 divider, that is DSI and LVDS, the dotclock
> can deviate up to 8% off target.
> 
> Signed-off-by: Roman Beranek 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v2 0/7] drm: sun4i: set proper TCON0 DCLK rate in DSI mode

2023-05-10 Thread Jernej Škrabec
Dne ponedeljek, 08. maj 2023 ob 16:08:32 CEST je Frank Oltmanns napisal(a):
> Hello again,
> 
> On 2023-05-08 at 08:54:28 +0200, Frank Oltmanns  wrote:
> > Hello Roman,
> > 
> > On 2023-05-03 at 16:22:32 +0200, "Roman Beranek"  wrote:
> >> Hello everyone,
> >> 
> >> I apologize for my absence from the discussion during past week, I got
> >> hit with tonsillitis.
> > 
> > I hope you feel better!
> > 
> >> On Mon May 1, 2023 at 3:40 PM CEST, Frank Oltmanns wrote:
> >>> Looking at ccu_nkm_determine_rate(), we've found our culprit because it
> >>> does not try parent clock rates other than the current one. The same
> >>> applies to all other ccu_nkm_* functions.
> >> 
> >> Yes, that's why I dropped CLK_SET_RATE_PARENT from pll-mipi in v3.
> >> 
> >>>  b. Add functionality to ccu_nkm_* to also update the parent clock rate.
> >>> 
> >>> I'm actually interested in tackling b, but I can't make any promises as
> >>> to if and when I'll be able to solve it. I'm not certain about any side
> >>> effects this might have.
> >> 
> >> It sounds like an interesting exercise. But what if HDMI is then added
> >> to the mix?
> > 
> > Thanks for interest in this discussion! I really appreciate it!
> > 
> > First of all, let me admit that I'm no expert on this. But nobody else
> > has replied so far, and I want to keep this conversation going, so let
> > me share my view.
> > 
> > My understanding is that pll-mipi being able to set pll-video0's rate
> > should not have an impact on HDMI, neither positive nor negative. If I'm
> > not mistaken those two things are orthogonal.
> > 
> > The relevant part of the clk_summary with your v4 [1] patch on top of
> > 
> > drm-next looks like this:
> >  enable  protect  hardware
> >
> >clock  countcountrateenable
> > 
> > --
> > 
> > pll-video011   29400 Y
> > 
> >hdmi   00   29400 N
> >tcon1  00   29400 N
> >pll-mipi   11   43120 Y
> >
> >   tcon0   21   43120 Y
> >   
> >  tcon-data-clock  11   10780 Y
> >
> >pll-video0-2x  00   58800 Y
> > 
> > Note, that pll-video0 is protected.
> > 
> > I don't own any boards that support HDMI in mainline. For the pinephone
> > this support is added e.g. in megi's kernel, where connecting an HDMI
> > output results in pll-video0's rate being set to 297MHz, even though it
> > is 294MHz after boot.
> > 
> > So, for reference, this is the same part of the clk_summary with megi's
> > 
> > 6.3.0 kernel, USB-C dock unplugged:
> >  enable  protect  hardware
> >
> >clock  countcountrateenable
> > 
> > --
> > 
> > pll-video030   29400 Y
> > 
> >hdmi-phy-clk   107350 Y
> >hdmi   10   29400 Y
> >tcon1  00   29400 N
> >pll-mipi   10   43120 Y
> >
> >   tcon0   20   43120 Y
> >   
> >  tcon-pixel-clock 10   10780 Y
> >
> >pll-video0-2x  00   58800 Y
> > 
> > pll-video0 is not protected. When plugging in the USB-C dock with an HDMI
> 
> > monitor connected, the situation looks like this:
> Just for reference, the protection count is disabled by this commit [1]
> in megi's kernel.
> 
> In the commit message Icenowy Zheng refers to "the ability to keep TCON0
> clock stable when HDMI changes its parent's clock." She implemented this
> in these two previous commits [2] [3]. None of this is in mainline.

Those commits are good follow up series to this, if anyone wants to improve 
things further.

Best regards,
Jernej

> 
> Best regards,
>   Frank
> 
> [1]:
> https://github.com/megous/linux/commit/039f7ee3f44adfbe4c6b7c2f1798b9a70c9f
> b9ee [2]:
> https://github.com/megous/linux/commit/a927843932f16e5a7f5ff57fbfd2d5f11c71
> 2b67 [3]:
> https://github.com/megous/linux/commit/0e305371eaa49128856acce9830e6af07944
> 2ad6
> >  enable  protect  hardware
> >
> >clock  countcountrateenable
> > 
> > --
> > 
> > pll-video04   

Re: [PATCH v3 4/7] arm64: dts: allwinner: a64: reset pll-video0 rate

2023-04-28 Thread Jernej Škrabec
Dne četrtek, 27. april 2023 ob 11:16:08 CEST je Roman Beranek napisal(a):
> With pll-mipi as its source clock, the exact rate to which TCON0's data
> clock can be set to is constrained by the current rate of pll-video0.
> Unless changed on a request of another consumer, the rate of pll-video0
> is left as inherited from the bootloader.
> 
> The default rate on reset is 297 MHz, a value preferable to what it is
> later set to in u-boot (294 MHz). This happens unintentionally though,
> as u-boot, for the sake of simplicity, rounds the rate requested by DE2
> driver (297 MHz) to 6 MHz steps.
> 
> Reset the PLL to its default rate of 297 MHz.

Why would that be preferable? You actually dropped "clk: sunxi-ng: a64: 
propagate rate change from pll-mipi" patch which would take care for adjusting 
parent rate to correct value.

Best regards,
Jernej

> 
> Signed-off-by: Roman Beranek 
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index
> e6a194db420d..cfc60dce80b0 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -667,6 +667,9 @@ ccu: clock@1c2 {
>   clock-names = "hosc", "losc";
>   #clock-cells = <1>;
>   #reset-cells = <1>;
> +
> + assigned-clocks = < CLK_PLL_VIDEO0>;
> + assigned-clock-rates = <29700>;
>   };
> 
>   pio: pinctrl@1c20800 {






Re: [PATCH v3 3/7] arm64: dts: allwinner: a64: assign PLL_MIPI to CLK_TCON0

2023-04-28 Thread Jernej Škrabec
Dne četrtek, 27. april 2023 ob 11:27:11 CEST je Maxime Ripard napisal(a):
> On Thu, Apr 27, 2023 at 11:16:07AM +0200, Roman Beranek wrote:
> > Assign pll-mipi parent to tcon0's source clock via 'assigned-clocks'.
> > 
> > Signed-off-by: Roman Beranek 
> 
> Again, you should be doing it in the driver, not the device tree.

Agreed, fixing this in driver instead of DT is better as it allows kernel to 
work with older DTs and still have proper DSI output.

Best regards,
Jernej

> 
> Maxime






Re: [PATCH 3/3] ARM: dts: sun8i: h3: beelink-x2: Disable DW-HDMI CEC

2023-04-16 Thread Jernej Škrabec
Dne nedelja, 16. april 2023 ob 15:25:31 CEST je Laurent Pinchart napisal(a):
> Hi Jernej,
> 
> Thank you for the patch.
> 
> On Sat, Apr 15, 2023 at 12:46:13PM +0200, Jernej Skrabec wrote:
> > Beelink X2 uses software implementation of CEC even though DW-HDMI has
> > working hardware implementation.
> 
> Why ? The reason should be explained in the commit message.

Maybe I should reword this differently. It uses software implementation through 
GPIO pin. Dedicated DW-HDMI CEC pin is left unconnected.

Best regards,
Jernej 

> 
> > Disable unused DW-HDMI CEC.
> > 
> > Signed-off-by: Jernej Skrabec 
> > ---
> > 
> >  arch/arm/boot/dts/sun8i-h3-beelink-x2.dts | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
> > b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts index
> > a6d38ecee141..38f40d69e5c5 100644
> > --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
> > +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
> > @@ -150,6 +150,7 @@  {
> > 
> >  };
> >  
> >   {
> > 
> > +   snps,disable-cec;
> > 
> > status = "okay";
> >  
> >  };






Re: [PATCH] drm/sun4i: uncouple DSI dotclock divider from TCON0_DCLK_REG

2023-04-08 Thread Jernej Škrabec
Dne sreda, 05. april 2023 ob 14:34:11 CEST je Roman Beranek napisal(a):
> Hello Maxime,
> 
> On Wed Mar 29, 2023 at 9:58 PM CEST, Maxime Ripard wrote:
> > > In order to preserve semantic correctness however, I propose to preface
> > > the change with a patch that renames sun4i_dotclock and tcon-pixel-clock
> > > such that dot/pixel is replaced with d/data. What do you think?
> > 
> > I don't think it's exposed to the userspace in any way so it makes sense
> > to me
> Here's a new series that includes those renames:
> 
> 
> It turns out however that the new dclk rates can't be set exactly as
> requested without touching pll-video0*, tcon0 now therefore gets
> reparented from pll-mipi to pll-video0-2x which, as it further turns
> out, breaks DSI. While simply forbidding the video0-2x mux option seems
> to me as the right way to go because there's not much use for it with
> non-DSI interfaces either besides the opportunity to power pll-mipi
> down, I'd like to run by you first.

It's been a long time since I looked at A64 HDMI clocks, but IIRC, pll-video0 
is the only useful source for HDMI PHY (as opposed to HDMI controller.)
So question remains how to properly support both displays at the same time.

Have you ever tried to make HDMI and DSI work at the same time? This is one of 
issues of the PinePhone IIUC.


> 
> Kind regards,
> Roman
> 
> * As pll-mipi doesn't have CLK_SET_RATE_PARENT flag set, pll-video0
>   retains its boot-time rate of 294 MHz set by sunxi-dw-hdmi driver
>   in u-boot. Why 294 MHz (as opposed to the default rate of 297 MHz)?
>   The driver actually asks for 297 MHz, clock_set_pll3 rounds it to
>   294 MHz though because it limits itself to 6 MHz steps.

Yeah, we added CLK_SET_RATE_PARENT flag to several clocks after initial driver 
was merged. Adding this flag sounds completely reasonable.

Best regards,
Jernej




Re: [PATCH] drm: Use of_property_present() for testing DT property presence

2023-03-14 Thread Jernej Škrabec
Dne petek, 10. marec 2023 ob 15:47:05 CET je Rob Herring napisal(a):
> It is preferred to use typed property access functions (i.e.
> of_property_read_ functions) rather than low-level
> of_get_property/of_find_property functions for reading properties. As
> part of this, convert of_get_property/of_find_property calls to the
> recently added of_property_present() helper when we just want to test
> for presence of a property and nothing more.
> 
> Signed-off-by: Rob Herring 
> ---
>  drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c | 2 +-
>  drivers/gpu/drm/drm_mipi_dsi.c  | 2 +-
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +-
>  drivers/gpu/drm/sun4i/sun4i_backend.c   | 2 +-
>  drivers/gpu/drm/sun4i/sun8i_mixer.c | 2 +-

For sun4i:
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

>  drivers/gpu/drm/vc4/vc4_hdmi.c  | 2 +-
>  6 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c index
> 9e5f2b4dc2e5..fab139b324af 100644
> --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
> @@ -313,7 +313,7 @@ imx8qxp_pixel_link_find_next_bridge(struct
> imx8qxp_pixel_link *pl) }
> 
>   /* specially select the next bridge with companion 
PXL2DPI */
> - if (of_find_property(remote, "fsl,companion-pxl2dpi", 
NULL))
> + if (of_property_present(remote, "fsl,companion-
pxl2dpi"))
>   bridge_sel = ep_cnt;
> 
>   ep_cnt++;
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index b41aaf2bb9f1..7900a4707d7c 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -329,7 +329,7 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
> 
>   for_each_available_child_of_node(host->dev->of_node, node) {
>   /* skip nodes without reg property */
> - if (!of_find_property(node, "reg", NULL))
> + if (!of_property_present(node, "reg"))
>   continue;
>   of_mipi_dsi_device_add(host, node);
>   }
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index ce6b76c45b6f..2359dca80492
> 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -964,7 +964,7 @@ static void adreno_get_pwrlevels(struct device *dev,
>   gpu->fast_rate = 0;
> 
>   /* You down with OPP? */
> - if (!of_find_property(dev->of_node, "operating-points-v2", NULL))
> + if (!of_property_present(dev->of_node, "operating-points-v2"))
>   ret = adreno_get_legacy_pwrlevels(dev);
>   else {
>   ret = devm_pm_opp_of_add_table(dev);
> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c
> b/drivers/gpu/drm/sun4i/sun4i_backend.c index 38070fc261f3..b11dbd50d73e
> 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> @@ -792,7 +792,7 @@ static int sun4i_backend_bind(struct device *dev, struct
> device *master, dev_set_drvdata(dev, backend);
>   spin_lock_init(>frontend_lock);
> 
> - if (of_find_property(dev->of_node, "interconnects", NULL)) {
> + if (of_property_present(dev->of_node, "interconnects")) {
>   /*
>* This assume we have the same DMA constraints for all 
our the
>* devices in our pipeline (all the backends, but also 
the
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c index bafee05f6b24..11d5244a5aa5
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -391,7 +391,7 @@ static int sun8i_mixer_bind(struct device *dev, struct
> device *master, mixer->engine.ops = _engine_ops;
>   mixer->engine.node = dev->of_node;
> 
> - if (of_find_property(dev->of_node, "iommus", NULL)) {
> + if (of_property_present(dev->of_node, "iommus")) {
>   /*
>* This assume we have the same DMA constraints for
>* all our the mixers in our pipeline. This sounds
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index ea22c9bf223a..bec1e0cdddb3 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -3018,7 +3018,7 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi
> *vc4_hdmi) struct device *dev = >dev;
>   int ret;
> 
> - if (!of_find_property(dev->of_node, "interrupts", NULL)) {
> + if (!of_property_present(dev->of_node, "interrupts")) {
>   dev_warn(dev, "'interrupts' DT property is missing, no 
CEC\n");
>   return 0;
>   }






Re: [PATCH v2 01/11] pwm: Make .get_state() callback return an error code

2022-12-05 Thread Jernej Škrabec
Dne sreda, 30. november 2022 ob 16:21:38 CET je Uwe Kleine-König napisal(a):
> .get_state() might fail in some cases. To make it possible that a driver
> signals such a failure change the prototype of .get_state() to return an
> error code.
> 
> This patch was created using coccinelle and the following semantic patch:
> 
> @p1@
> identifier getstatefunc;
> identifier driver;
> @@
>  struct pwm_ops driver = {
> ...,
> .get_state = getstatefunc
> ,...
>  };
> 
> @p2@
> identifier p1.getstatefunc;
> identifier chip, pwm, state;
> @@
> -void
> +int
>  getstatefunc(struct pwm_chip *chip, struct pwm_device *pwm, struct
> pwm_state *state) {
>...
> -  return;
> +  return 0;
>...
>  }
> 
> plus the actual change of the prototype in include/linux/pwm.h (plus some
> manual fixing of indentions and empty lines).
> 
> So for now all drivers return success unconditionally. They are adapted
> in the following patches to make the changes easier reviewable.
> 
> Signed-off-by: Uwe Kleine-König 
> ---
>  drivers/gpio/gpio-mvebu.c |  9 ++---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 14 --
>  drivers/leds/rgb/leds-qcom-lpg.c  | 14 --
>  drivers/pwm/pwm-atmel.c   |  6 --
>  drivers/pwm/pwm-bcm-iproc.c   |  8 +---
>  drivers/pwm/pwm-crc.c | 10 ++
>  drivers/pwm/pwm-cros-ec.c |  8 +---
>  drivers/pwm/pwm-dwc.c |  6 --
>  drivers/pwm/pwm-hibvt.c   |  6 --
>  drivers/pwm/pwm-imx-tpm.c |  8 +---
>  drivers/pwm/pwm-imx27.c   |  8 +---
>  drivers/pwm/pwm-intel-lgm.c   |  6 --
>  drivers/pwm/pwm-iqs620a.c |  6 --
>  drivers/pwm/pwm-keembay.c |  6 --
>  drivers/pwm/pwm-lpss.c|  6 --
>  drivers/pwm/pwm-meson.c   |  8 +---
>  drivers/pwm/pwm-mtk-disp.c| 12 +++-
>  drivers/pwm/pwm-pca9685.c |  8 +---
>  drivers/pwm/pwm-raspberrypi-poe.c |  8 +---
>  drivers/pwm/pwm-rockchip.c| 12 +++-
>  drivers/pwm/pwm-sifive.c  |  6 --
>  drivers/pwm/pwm-sl28cpld.c|  8 +---
>  drivers/pwm/pwm-sprd.c|  8 +---
>  drivers/pwm/pwm-stm32-lp.c|  8 +---
>  drivers/pwm/pwm-sun4i.c   | 12 +++-
>  drivers/pwm/pwm-sunplus.c |  6 --
>  drivers/pwm/pwm-visconti.c|  6 --
>  drivers/pwm/pwm-xilinx.c  |  8 +---
>  include/linux/pwm.h   |  4 ++--
>  29 files changed, 146 insertions(+), 89 deletions(-)
> 

> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index c8445b0a3339..37d75e252d4e 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -108,9 +108,9 @@ static inline void sun4i_pwm_writel(struct
> sun4i_pwm_chip *chip, writel(val, chip->base + offset);
>  }
> 
> -static void sun4i_pwm_get_state(struct pwm_chip *chip,
> - struct pwm_device *pwm,
> - struct pwm_state *state)
> +static int sun4i_pwm_get_state(struct pwm_chip *chip,
> +struct pwm_device *pwm,
> +struct pwm_state *state)
>  {
>   struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
>   u64 clk_rate, tmp;
> @@ -132,7 +132,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
>   state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
>   state->polarity = PWM_POLARITY_NORMAL;
>   state->enabled = true;
> - return;
> + return 0;
>   }
> 
>   if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
> @@ -142,7 +142,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
>   prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm-
>hwpwm)];
> 
>   if (prescaler == 0)
> - return;
> + return 0;
> 
>   if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
>   state->polarity = PWM_POLARITY_NORMAL;
> @@ -162,6 +162,8 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
> 
>   tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
>   state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
> +
> + return 0;
>  }
> 
>  static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,

For sun4i:

Acked-by: Jernej Skrabec 

Best regards,
Jernej




Re: Re: [PATCH v5 22/22] drm/sun4i: tv: Convert to the new TV mode property

2022-10-15 Thread Jernej Škrabec
Dne petek, 14. oktober 2022 ob 09:38:10 CEST je Maxime Ripard napisal(a):
> Hi Jernej,
> 
> On Thu, Oct 13, 2022 at 08:23:51PM +0200, Jernej Škrabec wrote:
> > Dne četrtek, 13. oktober 2022 ob 15:19:06 CEST je Maxime Ripard 
napisal(a):
> > > Now that the core can deal fine with analog TV modes, let's convert the
> > > sun4i TV driver to leverage those new features.
> > > 
> > > Acked-by: Noralf Trønnes 
> > > Signed-off-by: Maxime Ripard 
> > > 
> > > ---
> > > Changes in v5:
> > > - Removed the count variable in get_modes
> > > - Removed spurious vc4 change
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/sun4i_tv.c | 145
> > > 
> > > +-- 1 file changed, 48
> > > insertions(+),
> > > 97 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> > > b/drivers/gpu/drm/sun4i/sun4i_tv.c index c65f0a89b6b0..4f07aff11551
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> > > @@ -141,23 +141,14 @@ struct resync_parameters {
> > > 
> > >  struct tv_mode {
> > >  
> > >   char*name;
> > > 
> > > + unsigned inttv_mode;
> > > +
> > > 
> > >   u32 mode;
> > >   u32 chroma_freq;
> > >   u16 back_porch;
> > >   u16 front_porch;
> > > 
> > > - u16 line_number;
> > > 
> > >   u16 vblank_level;
> > 
> > isn't there a way to get or calculate back_porch, front_porch and
> > vblank_level from mode? From quick glance over removed values below, I
> > would say that at least back_porch can be removed too?
> 
> I tried actually, but I'm not sure what the front porch and back porch
> parameters actually are. They are called that way by Allwinner, but it
> doesn't match the PAL or NTSC timings at all.
> 
> For example, back_porch is 118 for NTSC and 138 for PAL. Actual back
> porches would be around 12 and 16, respectively. Actually, the entire
> blanking area are 138 and 144. This is close enough for PAL, but pretty
> far off for NTSC.
> 
> Allwinner has the habit of integrating the sync period into one of the
> porches, but still there's no obvious match.
> 
> front_porch is pretty much in the same case.

Ok then.

> 
> Since it affected the display output quite a lot, I chose to keep it for
> now unfortunately.
> 
> > Otherwise this patch looks ok.
> 
> Can I add your Acked-by/Reviewed-by then?

Sure.
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v5 22/22] drm/sun4i: tv: Convert to the new TV mode property

2022-10-13 Thread Jernej Škrabec
Hi Maxime,

Dne četrtek, 13. oktober 2022 ob 15:19:06 CEST je Maxime Ripard napisal(a):
> Now that the core can deal fine with analog TV modes, let's convert the
> sun4i TV driver to leverage those new features.
> 
> Acked-by: Noralf Trønnes 
> Signed-off-by: Maxime Ripard 
> 
> ---
> Changes in v5:
> - Removed the count variable in get_modes
> - Removed spurious vc4 change
> ---
>  drivers/gpu/drm/sun4i/sun4i_tv.c | 145
> +-- 1 file changed, 48 insertions(+),
> 97 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index c65f0a89b6b0..4f07aff11551 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -141,23 +141,14 @@ struct resync_parameters {
>  struct tv_mode {
>   char*name;
> 
> + unsigned inttv_mode;
> +
>   u32 mode;
>   u32 chroma_freq;
>   u16 back_porch;
>   u16 front_porch;
> - u16 line_number;
>   u16 vblank_level;

isn't there a way to get or calculate back_porch, front_porch and vblank_level 
from mode? From quick glance over removed values below, I would say that at 
least back_porch can be removed too?

Otherwise this patch looks ok.

Best regards,
Jernej

> 
> - u32 hdisplay;
> - u16 hfront_porch;
> - u16 hsync_len;
> - u16 hback_porch;
> -
> - u32 vdisplay;
> - u16 vfront_porch;
> - u16 vsync_len;
> - u16 vback_porch;
> -
>   boolyc_en;
>   booldac3_en;
>   booldac_bit25_en;
> @@ -213,7 +204,7 @@ static const struct resync_parameters
> pal_resync_parameters = {
> 
>  static const struct tv_mode tv_modes[] = {
>   {
> - .name   = "NTSC",
> + .tv_mode= DRM_MODE_TV_MODE_NTSC,
>   .mode   = SUN4I_TVE_CFG0_RES_480i,
>   .chroma_freq= 0x21f07c1f,
>   .yc_en  = true,
> @@ -222,17 +213,6 @@ static const struct tv_mode tv_modes[] = {
> 
>   .back_porch = 118,
>   .front_porch= 32,
> - .line_number= 525,
> -
> - .hdisplay   = 720,
> - .hfront_porch   = 18,
> - .hsync_len  = 2,
> - .hback_porch= 118,
> -
> - .vdisplay   = 480,
> - .vfront_porch   = 26,
> - .vsync_len  = 2,
> - .vback_porch= 17,
> 
>   .vblank_level   = 240,
> 
> @@ -242,23 +222,12 @@ static const struct tv_mode tv_modes[] = {
>   .resync_params  = _resync_parameters,
>   },
>   {
> - .name   = "PAL",
> + .tv_mode= DRM_MODE_TV_MODE_PAL,
>   .mode   = SUN4I_TVE_CFG0_RES_576i,
>   .chroma_freq= 0x2a098acb,
> 
>   .back_porch = 138,
>   .front_porch= 24,
> - .line_number= 625,
> -
> - .hdisplay   = 720,
> - .hfront_porch   = 3,
> - .hsync_len  = 2,
> - .hback_porch= 139,
> -
> - .vdisplay   = 576,
> - .vfront_porch   = 28,
> - .vsync_len  = 2,
> - .vback_porch= 19,
> 
>   .vblank_level   = 252,
> 
> @@ -276,63 +245,21 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
>   encoder);
>  }
> 
> -/*
> - * FIXME: If only the drm_display_mode private field was usable, this
> - * could go away...
> - *
> - * So far, it doesn't seem to be preserved when the mode is passed by
> - * to mode_set for some reason.
> - */
> -static const struct tv_mode *sun4i_tv_find_tv_by_mode(const struct
> drm_display_mode *mode) +static const struct tv_mode *
> +sun4i_tv_find_tv_by_mode(unsigned int mode)
>  {
>   int i;
> 
> - /* First try to identify the mode by name */
>   for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
>   const struct tv_mode *tv_mode = _modes[i];
> 
> - DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
> -  mode->name, tv_mode->name);
> -
> - if (!strcmp(mode->name, tv_mode->name))
> - return tv_mode;
> - }
> -
> - /* Then by number of lines */
> - for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
> - const struct tv_mode *tv_mode = _modes[i];
> -
> - DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs 
%d)",
> -  mode->name, tv_mode->name,
> -  mode->vdisplay, tv_mode-
>vdisplay);
> -
> - if (mode->vdisplay == tv_mode->vdisplay)
> + if (tv_mode->tv_mode == mode)
>   return tv_mode;
>   }
> 
>   return NULL;
>  }
> 
> -static 

Re: [PATCH v4 0/5] Allwinner H6 GPU devfreq

2022-09-08 Thread Jernej Škrabec
Dne torek, 06. september 2022 ob 17:30:29 CEST je Clément Péron napisal(a):
> Hi,
> 
> This is a refresh of previous patches sent to enable GPU Devfreq on H6
> Beelink GS1 but that wasn't stable at that time[0].
> 
> With the recent fix on GPU PLL from Roman Stratiienko I have retested
> and everything seems stable and works as expected[1].
> 
> Regards,
> Clement

All patches except patch 4 pushed to sunxi tree. Thanks!

Best regards,
Jernej

> 
> 0:
> https://lore.kernel.org/lkml/CAJiuCce58Gaxf_Qg2cnMwvOgUqYU__eKb3MDX1Fe_+47h
> tg...@mail.gmail.com/ 1:
> https://lore.kernel.org/linux-arm-kernel/2562485.k3LOHGUjKi@kista/T/
> 
> Changes since v3:
>  - Try to be more explicit for panfrost OPP patch
>  - Fix typo
> 
> Changes since v2:
>  - Fixes device-tree warnings
>  - Add panfrost fix to enable regulator
>  - Remove always-on regulator from device-tree
>  - Update cooling map from vendor kernel
> 
> 
> Clément Péron (5):
>   arm64: defconfig: Enable devfreq cooling device
>   arm64: dts: allwinner: h6: Add cooling map for GPU
>   arm64: dts: allwinner: h6: Add GPU OPP table
>   drm/panfrost: devfreq: set opp to the recommended one to configure
> regulator
>   arm64: dts: allwinner: beelink-gs1: Enable GPU OPP
> 
>  .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |  1 +
>  .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 51 ++-
>  arch/arm64/configs/defconfig  |  1 +
>  drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 11 +++
>  5 files changed, 149 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> 
> --
> 2.34.1




Re: Re: Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-08 Thread Jernej Škrabec
Dne četrtek, 08. september 2022 ob 18:26:31 CEST je Jernej Škrabec napisal(a):
> Dne torek, 06. september 2022 ob 21:26:34 CEST je Clément Péron napisal(a):
> > Hi Jernej,
> > 
> > On Tue, 6 Sept 2022 at 21:10, Jernej Škrabec 
> 
> wrote:
> > > Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron
> 
> napisal(a):
> > > > Add an Operating Performance Points table for the GPU to
> > > > enable Dynamic Voltage & Frequency Scaling on the H6.
> > > > 
> > > > The voltage range is set with minimal voltage set to the target
> > > > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > > > work properly on board with fixed regulator.
> > > > 
> > > > Signed-off-by: Clément Péron 
> > > > ---
> > > > 
> > > >  .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87
> > > >  +++
> > > >  1 file changed, 87 insertions(+)
> > > >  create mode 100644
> > > >  arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > > b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode
> > > > 100644
> > > > index ..b48049c4fc85
> > > > --- /dev/null
> > > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > > @@ -0,0 +1,87 @@
> > > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > > +// Copyright (C) 2022 Clément Péron 
> > > > +
> > > > +/ {
> > > > + gpu_opp_table: opp-table-gpu {
> > > > + compatible = "operating-points-v2";
> > > > +
> > > > + opp-21600 {
> > > > + opp-hz = /bits/ 64 <21600>;
> > > > + opp-microvolt = <81 81 120>;
> > > > + };
> > > > +
> > > > + opp-26400 {
> > > > + opp-hz = /bits/ 64 <26400>;
> > > > + opp-microvolt = <81 81 120>;
> > > > + };
> > > 
> > > As mentioned in clock patch review, rates below 288 MHz are deemed
> > > unstable on GPU PLL by vendor GPU kernel driver. At least in the BSP
> > > version that I have. Did you test these points? If not, better to drop
> > > them.
> > 
> > I changed the governor to userspace and set the freq to 216MHz / 264MHz
> > Run glmark2 and didn't observe any glitch nor issue.
> > 
> > I'm not sure if it's enough to say it's stable but I didn't observe
> > any strange behavior.
> 
> Ok then.
> 
> Forgot to ask, where did you get 1.2 V as an upper limit? H6 datasheet lists
> max. GPU voltage as 1.08 V.

To answer my own question, absolute max. voltage is 1.3 V, so 1.2 V is still 
somewhat acceptable and in practice, fixed regulator on Tanix TX6 board is 
around 1.12 V. Boards with PMIC can set lower voltage anyway.

All good.
Acked-by: Jernej Skrabec 
 
Best regards,
Jernej
 
> > Regards,
> > Clement
> > 
> > > Best regards,
> > > Jernej
> > > 
> > > > +
> > > > + opp-31200 {
> > > > + opp-hz = /bits/ 64 <31200>;
> > > > + opp-microvolt = <81 81 120>;
> > > > + };
> > > > +
> > > > + opp-33600 {
> > > > + opp-hz = /bits/ 64 <33600>;
> > > > + opp-microvolt = <81 81 120>;
> > > > + };
> > > > +
> > > > + opp-36000 {
> > > > + opp-hz = /bits/ 64 <36000>;
> > > > + opp-microvolt = <82 82 120>;
> > > > + };
> > > > +
> > > > + opp-38400 {
> > > > + opp-hz = /bits/ 64 <38400>;
> > > > + opp-microvolt = <83 83 120>;
> > > > + };
> > > > +
> > > > + opp-40800 {
> > > > + opp-hz = /bits/ 64 <40800>;
> > > > + opp-microvolt = <84 84 120>;
> > > > + };
> > > > +
>

Re: [PATCH v4 5/5] arm64: dts: allwinner: beelink-gs1: Enable GPU OPP

2022-09-08 Thread Jernej Škrabec
Dne torek, 06. september 2022 ob 17:30:34 CEST je Clément Péron napisal(a):
> Enable GPU OPP table for Beelink GS1.
> 
> Signed-off-by: Clément Péron 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts index
> 6249e9e02928..9ec49ac2f6fd 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> @@ -5,6 +5,7 @@
> 
>  #include "sun50i-h6.dtsi"
>  #include "sun50i-h6-cpu-opp.dtsi"
> +#include "sun50i-h6-gpu-opp.dtsi"
> 
>  #include 
> 
> --
> 2.34.1




Re: Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-08 Thread Jernej Škrabec
Dne torek, 06. september 2022 ob 21:26:34 CEST je Clément Péron napisal(a):
> Hi Jernej,
> 
> On Tue, 6 Sept 2022 at 21:10, Jernej Škrabec  
wrote:
> > Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron 
napisal(a):
> > > Add an Operating Performance Points table for the GPU to
> > > enable Dynamic Voltage & Frequency Scaling on the H6.
> > > 
> > > The voltage range is set with minimal voltage set to the target
> > > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > > work properly on board with fixed regulator.
> > > 
> > > Signed-off-by: Clément Péron 
> > > ---
> > > 
> > >  .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
> > >  1 file changed, 87 insertions(+)
> > >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode
> > > 100644
> > > index ..b48049c4fc85
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > > @@ -0,0 +1,87 @@
> > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > +// Copyright (C) 2022 Clément Péron 
> > > +
> > > +/ {
> > > + gpu_opp_table: opp-table-gpu {
> > > + compatible = "operating-points-v2";
> > > +
> > > + opp-21600 {
> > > + opp-hz = /bits/ 64 <21600>;
> > > + opp-microvolt = <81 81 120>;
> > > + };
> > > +
> > > + opp-26400 {
> > > + opp-hz = /bits/ 64 <26400>;
> > > + opp-microvolt = <81 81 120>;
> > > + };
> > 
> > As mentioned in clock patch review, rates below 288 MHz are deemed
> > unstable on GPU PLL by vendor GPU kernel driver. At least in the BSP
> > version that I have. Did you test these points? If not, better to drop
> > them.
> 
> I changed the governor to userspace and set the freq to 216MHz / 264MHz
> Run glmark2 and didn't observe any glitch nor issue.
> 
> I'm not sure if it's enough to say it's stable but I didn't observe
> any strange behavior.

Ok then.

Forgot to ask, where did you get 1.2 V as an upper limit? H6 datasheet lists 
max. GPU voltage as 1.08 V.

Best regards,
Jernej

> 
> Regards,
> Clement
> 
> > Best regards,
> > Jernej
> > 
> > > +
> > > + opp-31200 {
> > > + opp-hz = /bits/ 64 <31200>;
> > > + opp-microvolt = <81 81 120>;
> > > + };
> > > +
> > > + opp-33600 {
> > > + opp-hz = /bits/ 64 <33600>;
> > > + opp-microvolt = <81 81 120>;
> > > + };
> > > +
> > > + opp-36000 {
> > > + opp-hz = /bits/ 64 <36000>;
> > > + opp-microvolt = <82 82 120>;
> > > + };
> > > +
> > > + opp-38400 {
> > > + opp-hz = /bits/ 64 <38400>;
> > > + opp-microvolt = <83 83 120>;
> > > + };
> > > +
> > > + opp-40800 {
> > > + opp-hz = /bits/ 64 <40800>;
> > > + opp-microvolt = <84 84 120>;
> > > + };
> > > +
> > > + opp-42000 {
> > > + opp-hz = /bits/ 64 <42000>;
> > > + opp-microvolt = <85 85 120>;
> > > + };
> > > +
> > > + opp-43200 {
> > > + opp-hz = /bits/ 64 <43200>;
> > > + opp-microvolt = <86 86 120>;
> > > + };
> > > +
> > > + opp-45600 {
> > > + opp-hz = /bits/ 64 <45600>;
> > > + opp-microvolt = <87 87 120>;
> > > + };
> > > +
> > > +   

Re: [PATCH v4 2/5] arm64: dts: allwinner: h6: Add cooling map for GPU

2022-09-08 Thread Jernej Škrabec
Dne torek, 06. september 2022 ob 17:30:31 CEST je Clément Péron napisal(a):
> Add a simple cooling map for the GPU.
> 
> This cooling map come from the vendor kernel 4.9 with a
> 2°C hysteresis added.
> 
> Signed-off-by: Clément Péron 

Acked-by: Jernej Skrabec 

Best regards,
Jernej




Re: Re: [PATCH v2 36/41] drm/sun4i: tv: Merge mode_set into atomic_enable

2022-09-07 Thread Jernej Škrabec
Dne sreda, 07. september 2022 ob 09:41:34 CEST je Maxime Ripard napisal(a):
> On Tue, Sep 06, 2022 at 10:04:32PM +0200, Jernej Škrabec wrote:
> > Dne ponedeljek, 29. avgust 2022 ob 15:11:50 CEST je Maxime Ripard 
napisal(a):
> > > Our mode_set implementation can be merged into our atomic_enable
> > > implementation to simplify things, so let's do this.
> > 
> > Are you sure this is a good thing in long term? What if user wants to
> > change mode? Unlikely, but why not.
> 
> It doesn't change anything feature-wise: whenever the mode is changed on
> the CRTC, the encoder is going to be disabled and enabled.
> 
> It's disabled here:
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_atomic_he
> lper.c#L1064
> 
> And enabled here:
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_atomic_he
> lper.c#L1403
> 
> With drm_atomic_crtc_needs_modeset() being defined here:
> https://elixir.bootlin.com/linux/latest/source/include/drm/drm_atomic.h#L104
> 9

Right.

Acked-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v2 37/41] drm/sun4i: tv: Remove useless function

2022-09-06 Thread Jernej Škrabec
Dne ponedeljek, 29. avgust 2022 ob 15:11:51 CEST je Maxime Ripard napisal(a):
> The drm_connector_to_sun4i_tv() function isn't used anywhere in the driver,
> so let's remove it.
> 
> Signed-off-by: Maxime Ripard 

Acked-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v2 36/41] drm/sun4i: tv: Merge mode_set into atomic_enable

2022-09-06 Thread Jernej Škrabec
Dne ponedeljek, 29. avgust 2022 ob 15:11:50 CEST je Maxime Ripard napisal(a):
> Our mode_set implementation can be merged into our atomic_enable
> implementation to simplify things, so let's do this.

Are you sure this is a good thing in long term? What if user wants to change 
mode? Unlikely, but why not.

Best regards,
Jernej

> 
> Signed-off-by: Maxime Ripard 
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c
> index f7aad995ab5b..3944da9a3c34 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -359,23 +359,13 @@ static void sun4i_tv_enable(struct drm_encoder
> *encoder,
 {
>   struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
>   struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
> -
> - DRM_DEBUG_DRIVER("Enabling the TV Output\n");
> -
> - sunxi_engine_apply_color_correction(crtc->engine);
> -
> - regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
> -SUN4I_TVE_EN_ENABLE,
> -SUN4I_TVE_EN_ENABLE);
> -}
> -
> -static void sun4i_tv_mode_set(struct drm_encoder *encoder,
> -   struct drm_display_mode *mode,
> -   struct drm_display_mode 
*adjusted_mode)
> -{
> - struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
> + struct drm_crtc_state *crtc_state =
> + drm_atomic_get_new_crtc_state(state, encoder->crtc);
> + struct drm_display_mode *mode = _state->mode;
>   const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
>  
> + DRM_DEBUG_DRIVER("Enabling the TV Output\n");
> +
>   /* Enable and map the DAC to the output */
>   regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
>  SUN4I_TVE_EN_DAC_MAP_MASK,
> @@ -468,12 +458,17 @@ static void sun4i_tv_mode_set(struct drm_encoder
> *encoder,
> SUN4I_TVE_RESYNC_FIELD : 0));
>  
>   regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);
> +
> + sunxi_engine_apply_color_correction(crtc->engine);
> +
> + regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
> +SUN4I_TVE_EN_ENABLE,
> +SUN4I_TVE_EN_ENABLE);
>  }
>  
>  static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
>   .atomic_disable = sun4i_tv_disable,
>   .atomic_enable  = sun4i_tv_enable,
> - .mode_set   = sun4i_tv_mode_set,
>  };
>  
>  static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
> 
> -- 
> b4 0.10.0-dev-65ba7





Re: [PATCH v2 35/41] drm/sun4i: tv: Convert to atomic hooks

2022-09-06 Thread Jernej Škrabec
Dne ponedeljek, 29. avgust 2022 ob 15:11:49 CEST je Maxime Ripard napisal(a):
> The sun4i TV driver still uses legacy enable and disable hook
> implementation. Let's convert to the atomic variants.
> 
> Signed-off-by: Maxime Ripard 

Acked-by: Jernej Skrabec 

BTW, I suggest you merge fixes/cleanups, no need to drag them in this super 
long series.

Best regards,
Jernej




Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-06 Thread Jernej Škrabec
Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron napisal(a):
> Add an Operating Performance Points table for the GPU to
> enable Dynamic Voltage & Frequency Scaling on the H6.
> 
> The voltage range is set with minimal voltage set to the target
> and the maximal voltage set to 1.2V. This allow DVFS framework to
> work properly on board with fixed regulator.
> 
> Signed-off-by: Clément Péron 
> ---
>  .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
>  1 file changed, 87 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode 100644
> index ..b48049c4fc85
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> @@ -0,0 +1,87 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (C) 2022 Clément Péron 
> +
> +/ {
> + gpu_opp_table: opp-table-gpu {
> + compatible = "operating-points-v2";
> +
> + opp-21600 {
> + opp-hz = /bits/ 64 <21600>;
> + opp-microvolt = <81 81 120>;
> + };
> +
> + opp-26400 {
> + opp-hz = /bits/ 64 <26400>;
> + opp-microvolt = <81 81 120>;
> + };

As mentioned in clock patch review, rates below 288 MHz are deemed unstable on 
GPU PLL by vendor GPU kernel driver. At least in the BSP version that I have. 
Did you test these points? If not, better to drop them.

Best regards,
Jernej

> +
> + opp-31200 {
> + opp-hz = /bits/ 64 <31200>;
> + opp-microvolt = <81 81 120>;
> + };
> +
> + opp-33600 {
> + opp-hz = /bits/ 64 <33600>;
> + opp-microvolt = <81 81 120>;
> + };
> +
> + opp-36000 {
> + opp-hz = /bits/ 64 <36000>;
> + opp-microvolt = <82 82 120>;
> + };
> +
> + opp-38400 {
> + opp-hz = /bits/ 64 <38400>;
> + opp-microvolt = <83 83 120>;
> + };
> +
> + opp-40800 {
> + opp-hz = /bits/ 64 <40800>;
> + opp-microvolt = <84 84 120>;
> + };
> +
> + opp-42000 {
> + opp-hz = /bits/ 64 <42000>;
> + opp-microvolt = <85 85 120>;
> + };
> +
> + opp-43200 {
> + opp-hz = /bits/ 64 <43200>;
> + opp-microvolt = <86 86 120>;
> + };
> +
> + opp-45600 {
> + opp-hz = /bits/ 64 <45600>;
> + opp-microvolt = <87 87 120>;
> + };
> +
> + opp-50400 {
> + opp-hz = /bits/ 64 <50400>;
> + opp-microvolt = <89 89 120>;
> + };
> +
> + opp-54000 {
> + opp-hz = /bits/ 64 <54000>;
> + opp-microvolt = <91 91 120>;
> + };
> +
> + opp-57600 {
> + opp-hz = /bits/ 64 <57600>;
> + opp-microvolt = <93 93 120>;
> + };
> +
> + opp-62400 {
> + opp-hz = /bits/ 64 <62400>;
> + opp-microvolt = <95 95 120>;
> + };
> +
> + opp-75600 {
> + opp-hz = /bits/ 64 <75600>;
> + opp-microvolt = <104 104 120>;
> + };
> + };
> +};
> +
> + {
> + operating-points-v2 = <_opp_table>;
> +};
> --
> 2.34.1




Re: [PATCH v3 2/5] arm64: dts: allwinner: h6: Add cooling map for GPU

2022-09-05 Thread Jernej Škrabec
Dne ponedeljek, 05. september 2022 ob 19:15:58 CEST je Clément Péron 
napisal(a):
> Add a simple cooling map for the GPU.
> 
> This cooling map come from the vendor kernel 4.9 with a
> 2°C hysteresis added.
> 
> Signed-off-by: Clément Péron 
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 51 +++-
>  1 file changed, 49 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index
> 5a28303d3d4c..1259ab0c3956 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> @@ -186,6 +186,7 @@ gpu: gpu@180 {
>   clocks = < CLK_GPU>, < CLK_BUS_GPU>;
>   clock-names = "core", "bus";
>   resets = < RST_BUS_GPU>;
> + #cooling-cells = <2>;
>   status = "disabled";
>   };
> 
> @@ -1072,9 +1073,55 @@ map0 {
>   };
> 
>   gpu-thermal {
> - polling-delay-passive = <0>;
> - polling-delay = <0>;
> + polling-delay-passive = <1000>;
> + polling-delay = <2000>;
>   thermal-sensors = < 1>;
> +
> + trips {
> + gpu_alert0: gpu-alert-0 {
> + temperature = <95000>;
> + hysteresis = <2000>;
> + type = "passive";
> + };
> +
> + gpu_alert1: gpu-alert-1 {
> + temperature = 
> <10>;
> + hysteresis = <2000>;
> + type = "passive";
> + };
> +
> + gpu_alert2: gpu-alert-2 {
> + temperature = 
> <105000>;
> + hysteresis = <2000>;
> + type = "passive";
> + };
> +
> + gpu-crit {
> + temperature = 
> <115000>;
> + hysteresis = <0>;
> + type = "critical";
> + };
> + };
> +
> + cooling-maps {
> + // Fordid the GPU to go over 
756MHz

Typo: Fordid -> Forbid

Also next below.

Best regards,
Jernej

> + map0 {
> + trip = <_alert0>;
> + cooling-device = <
>  1 THERMAL_NO_LIMIT>;
> + };
> +
> + // Fordid the GPU to go over
> 624MHz
> + map1 {
> + trip = <_alert1>;
> + cooling-device = < 
> 2 THERMAL_NO_LIMIT>;
> + };
> +
> + // Fordid the GPU to go over 
> 576MHz
> + map2 {
> + trip = <_alert2>;
> + cooling-device = < 
> 3 THERMAL_NO_LIMIT>;
> + };
> + };
>   };
>   };
>  };
> --
> 2.34.1




Re: [PATCH] gpu: move from strlcpy with unused retval to strscpy

2022-08-25 Thread Jernej Škrabec
Dne četrtek, 18. avgust 2022 ob 23:00:07 CEST je Wolfram Sang napisal(a):
> Follow the advice of the below link and prefer 'strscpy' in this
> subsystem. Conversion is 1:1 because the return value is not used.
> Generated by a coccinelle script.
> 
> Link:
> https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmk
> n...@mail.gmail.com/ Signed-off-by: Wolfram Sang
> 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> ---
>  drivers/gpu/drm/amd/amdgpu/atom.c   | 2 +-
>  drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c  | 2 +-
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 6 +++---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 2 +-
>  drivers/gpu/drm/display/drm_dp_helper.c | 2 +-
>  drivers/gpu/drm/display/drm_dp_mst_topology.c   | 2 +-
>  drivers/gpu/drm/drm_mipi_dsi.c  | 2 +-
>  drivers/gpu/drm/i2c/tda998x_drv.c   | 2 +-
>  drivers/gpu/drm/i915/selftests/i915_perf.c  | 2 +-
>  drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c | 2 +-
>  drivers/gpu/drm/radeon/radeon_atombios.c| 4 ++--
>  drivers/gpu/drm/radeon/radeon_combios.c | 4 ++--
>  drivers/gpu/drm/rockchip/inno_hdmi.c| 2 +-
>  drivers/gpu/drm/rockchip/rk3066_hdmi.c  | 2 +-
>  drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c  | 2 +-
>  15 files changed, 19 insertions(+), 19 deletions(-)





Re: [PATCH] drm/sun4i: dsi: Prevent underflow when computing packet sizes

2022-08-14 Thread Jernej Škrabec
Dne petek, 12. avgust 2022 ob 05:16:23 CEST je Samuel Holland napisal(a):
> Currently, the packet overhead is subtracted using unsigned arithmetic.
> With a short sync pulse, this could underflow and wrap around to near
> the maximal u16 value. Fix this by using signed subtraction. The call to
> max() will correctly handle any negative numbers that are produced.
> 
> Apply the same fix to the other timings, even though those subtractions
> are less likely to underflow.
> 
> Fixes: 133add5b5ad4 ("drm/sun4i: Add Allwinner A31 MIPI-DSI controller
> support") Signed-off-by: Samuel Holland 
> ---
> 
>  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index b4dfa166eccd..34234a144e87
> 100644
> --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> @@ -522,77 +522,77 @@ static void sun6i_dsi_setup_format(struct sun6i_dsi
> *dsi, SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINE0(0x) |
>SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINEN(0x));
> 
>   regmap_write(dsi->regs, SUN6I_DSI_PIXEL_CTL0_REG,
>SUN6I_DSI_PIXEL_CTL0_PD_PLUG_DISABLE |
>SUN6I_DSI_PIXEL_CTL0_FORMAT(fmt));
>  }
> 
>  static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
>   struct drm_display_mode 
*mode)
>  {
>   struct mipi_dsi_device *device = dsi->device;
> - unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 
8;
> + int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;

Nit: mipi_dsi_pixel_format_to_bpp() can return -EINVAL in case of unsupported 
format. Would it make sense to check it?

In any case:
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

>   u16 hbp = 0, hfp = 0, hsa = 0, hblk = 0, vblk = 0;
>   u32 basic_ctl = 0;
>   size_t bytes;
>   u8 *buffer;
> 
>   /* Do all timing calculations up front to allocate buffer space */
> 
>   if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
>   hblk = mode->hdisplay * Bpp;
>   basic_ctl = SUN6I_DSI_BASIC_CTL_VIDEO_BURST |
>   SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS |
>   SUN6I_DSI_BASIC_CTL_HBP_DIS;
> 
>   if (device->lanes == 4)
>   basic_ctl |= SUN6I_DSI_BASIC_CTL_TRAIL_FILL 
|
>
SUN6I_DSI_BASIC_CTL_TRAIL_INV(0xc);
>   } else {
>   /*
>* A sync period is composed of a blanking packet (4
>* bytes + payload + 2 bytes) and a sync event packet
>* (4 bytes). Its minimal size is therefore 10 bytes
>*/
>  #define HSA_PACKET_OVERHEAD  10
> - hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
> + hsa = max(HSA_PACKET_OVERHEAD,
> (mode->hsync_end - mode->hsync_start) * 
Bpp - HSA_PACKET_OVERHEAD);
> 
>   /*
>* The backporch is set using a blanking packet (4
>* bytes + payload + 2 bytes). Its minimal size is
>* therefore 6 bytes
>*/
>  #define HBP_PACKET_OVERHEAD  6
> - hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
> + hbp = max(HBP_PACKET_OVERHEAD,
> (mode->htotal - mode->hsync_end) * Bpp - 
HBP_PACKET_OVERHEAD);
> 
>   /*
>* The frontporch is set using a sync event (4 bytes)
>* and two blanking packets (each one is 4 bytes +
>* payload + 2 bytes). Its minimal size is therefore
>* 16 bytes
>*/
>  #define HFP_PACKET_OVERHEAD  16
> - hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
> + hfp = max(HFP_PACKET_OVERHEAD,
> (mode->hsync_start - mode->hdisplay) * Bpp 
- HFP_PACKET_OVERHEAD);
> 
>   /*
>* The blanking is set using a sync event (4 bytes)
>* and a blanking packet (4 bytes + payload + 2
>* bytes). Its minimal size is therefore 10 bytes.
>*/
>  #define HBLK_PACKET_OVERHEAD 10
> - hblk = max((unsigned int)HBLK_PACKET_OVERHEAD,
> + hblk = max(HBLK_PACKET_OVERHEAD,
>  (mode->htotal - (mode->hsync_end - mode-
>hsync_start)) * Bpp -
>  HBLK_PACKET_OVERHEAD);
> 
>   /*
>* And I'm not entirely sure what vblk is about. The 
driver in
>* Allwinner BSP is using a rather convoluted 
calculation
>* there only for 4 lanes. However, using 0 (the !4 
lanes
>* case) even with a 4 lanes screen seems to work...
>*/
>   vblk = 0;
>   }






Re: [PATCH 4/4] drm/sun4i: dsi: Add the A100 variant

2022-08-14 Thread Jernej Škrabec
Dne petek, 12. avgust 2022 ob 09:42:56 CEST je Samuel Holland napisal(a):
> The A100 variant of the MIPI DSI controller now gets its module clock
> from the TCON via the TCON TOP, so the clock rate cannot be set to a
> fixed value. Otherwise, it appears to be the same as the A31 variant.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH 3/4] drm/sun4i: dsi: Add a variant structure

2022-08-14 Thread Jernej Škrabec
Dne petek, 12. avgust 2022 ob 09:42:55 CEST je Samuel Holland napisal(a):
> Replace the ad-hoc calls to of_device_is_compatible() with a structure
> describing the differences between variants. This is in preparation for
> adding more variants to the driver.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH v1 31/35] drm/sun4i: tv: Add missing reset assertion

2022-07-30 Thread Jernej Škrabec
Dne petek, 29. julij 2022 ob 18:35:14 CEST je Maxime Ripard napisal(a):
> The reset line is deasserted at bind, and asserted if we ever encounter an
> error there. However, it's never deasserted in unbind which will lead to a

s/deasserted/asserted/

Once fixed:
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> resource unbalance.
> 
> Signed-off-by: Maxime Ripard 
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index ad6a3739bfa9..74ff5ad6a8b9 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -605,6 +605,7 @@ static void sun4i_tv_unbind(struct device *dev, struct
> device *master, drm_connector_cleanup(>connector);
>   drm_encoder_cleanup(>encoder);
>   clk_disable_unprepare(tv->clk);
> + reset_control_assert(tv->reset);
>  }
> 
>  static const struct component_ops sun4i_tv_ops = {






Re: [PATCH v1 30/35] drm/sun4i: tv: Rename error label

2022-07-30 Thread Jernej Škrabec
Dne petek, 29. julij 2022 ob 18:35:13 CEST je Maxime Ripard napisal(a):
> The other error labels in sun4i_tv_bind() are named after the task they
> perform (err_disable_clk to call clk_disable_unprepare for example).
> 
> However, the err_cleanup_connector is named after the calling site
> (drm_connector_init failing) and will actually cleanup the encoder. Let's
> rename it to err_cleanup_encoder to be consistent.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index 6d7e1d51569a..ad6a3739bfa9 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -580,7 +580,7 @@ static int sun4i_tv_bind(struct device *dev, struct
> device *master, if (ret) {
>   dev_err(dev,
>   "Couldn't initialise the Composite 
connector\n");
> - goto err_cleanup_connector;
> + goto err_cleanup_encoder;
>   }
>   tv->connector.interlace_allowed = true;
> 
> @@ -588,7 +588,7 @@ static int sun4i_tv_bind(struct device *dev, struct
> device *master,
> 
>   return 0;
> 
> -err_cleanup_connector:
> +err_cleanup_encoder:
>   drm_encoder_cleanup(>encoder);
>  err_disable_clk:
>   clk_disable_unprepare(tv->clk);






Re: [PATCH v1 29/35] drm/sun4i: tv: Remove useless destroy function

2022-07-30 Thread Jernej Škrabec
Dne petek, 29. julij 2022 ob 18:35:12 CEST je Maxime Ripard napisal(a):
> Our destroy implementation is just calling the generic helper, so let's
> just remove our function and directly use the helper.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index 52bbba8f19dc..6d7e1d51569a 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -491,15 +491,9 @@ static const struct drm_connector_helper_funcs
> sun4i_tv_comp_connector_helper_fu .get_modes  = sun4i_tv_comp_get_modes,
>  };
> 
> -static void
> -sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
> -{
> - drm_connector_cleanup(connector);
> -}
> -
>  static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
>   .fill_modes = drm_helper_probe_single_connector_modes,
> - .destroy= sun4i_tv_comp_connector_destroy,
> + .destroy= drm_connector_cleanup,
>   .reset  = 
drm_atomic_helper_connector_reset,
>   .atomic_duplicate_state = 
drm_atomic_helper_connector_duplicate_state,
>   .atomic_destroy_state   = 
drm_atomic_helper_connector_destroy_state,






Re: [PATCH v1 25/35] drm/sun4i: tv: Remove unused mode_valid

2022-07-30 Thread Jernej Škrabec
Dne petek, 29. julij 2022 ob 18:35:08 CEST je Maxime Ripard napisal(a):
> The mode_valid implementation is pretty much a nop, let's remove it.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index 94883abe0dfd..53152d77c392 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -497,16 +497,8 @@ static int sun4i_tv_comp_get_modes(struct drm_connector
> *connector) return i;
>  }
> 
> -static int sun4i_tv_comp_mode_valid(struct drm_connector *connector,
> - struct drm_display_mode 
*mode)
> -{
> - /* TODO */
> - return MODE_OK;
> -}
> -
>  static const struct drm_connector_helper_funcs
> sun4i_tv_comp_connector_helper_funcs = { .get_modes   =
> sun4i_tv_comp_get_modes,
> - .mode_valid = sun4i_tv_comp_mode_valid,
>  };
> 
>  static void






Re: [PATCH v1 26/35] drm/sun4i: tv: Convert to atomic hooks

2022-07-30 Thread Jernej Škrabec
Dne petek, 29. julij 2022 ob 18:35:09 CEST je Maxime Ripard napisal(a):
> The VC4 VEC driver still uses legacy enable and disable hook

s/VC4 VEC/sun4i tv/

Best regards,
Jernej

> implementation. Let's convert to the atomic variants.
> 
> Signed-off-by: Maxime Ripard 
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index 53152d77c392..f7aad995ab5b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -339,7 +339,8 @@ static void sun4i_tv_mode_to_drm_mode(const struct
> tv_mode *tv_mode, mode->vtotal = mode->vsync_end  + tv_mode->vback_porch;
>  }
> 
> -static void sun4i_tv_disable(struct drm_encoder *encoder)
> +static void sun4i_tv_disable(struct drm_encoder *encoder,
> + struct drm_atomic_state *state)
>  {
>   struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
>   struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
> @@ -353,7 +354,8 @@ static void sun4i_tv_disable(struct drm_encoder
> *encoder) sunxi_engine_disable_color_correction(crtc->engine);
>  }
> 
> -static void sun4i_tv_enable(struct drm_encoder *encoder)
> +static void sun4i_tv_enable(struct drm_encoder *encoder,
> + struct drm_atomic_state *state)
>  {
>   struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
>   struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
> @@ -469,8 +471,8 @@ static void sun4i_tv_mode_set(struct drm_encoder
> *encoder, }
> 
>  static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
> - .disable= sun4i_tv_disable,
> - .enable = sun4i_tv_enable,
> + .atomic_disable = sun4i_tv_disable,
> + .atomic_enable  = sun4i_tv_enable,
>   .mode_set   = sun4i_tv_mode_set,
>  };






Re: Re: [PATCH] dt-bindings: display: sun4i: Fix D1 pipeline count

2022-07-04 Thread Jernej Škrabec
Dne sobota, 02. julij 2022 ob 21:06:07 CEST je Jernej Škrabec napisal(a):
> Dne sobota, 02. julij 2022 ob 05:29:21 CEST je Samuel Holland napisal(a):
> > When adding the bindings for the D1 display engine, I missed the
> > condition for the number of pipelines. D1 has two mixers, so it
> > will have two pipeline references.
> > 
> > Fixes: ae5a5d26c15c ("dt-bindings: display: Add D1 display engine
> > compatibles") Signed-off-by: Samuel Holland 
> 
> Reviewed-by: Jernej Skrabec 

Applied, thanks!

Best regards,
Jernej




Re: [PATCH] dt-bindings: display: sun4i: Fix D1 pipeline count

2022-07-04 Thread Jernej Škrabec
Dne sobota, 02. julij 2022 ob 05:29:21 CEST je Samuel Holland napisal(a):
> When adding the bindings for the D1 display engine, I missed the
> condition for the number of pipelines. D1 has two mixers, so it
> will have two pipeline references.
> 
> Fixes: ae5a5d26c15c ("dt-bindings: display: Add D1 display engine
> compatibles") Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH] drm/sun4i: Add DMA mask and segment size

2022-06-16 Thread Jernej Škrabec
Dne petek, 17. junij 2022 ob 05:03:11 CEST je Samuel Holland napisal(a):
> Hi Jernej,
> 
> On 6/16/22 4:32 PM, Jernej Skrabec wrote:
> > Kernel occasionally complains that there is mismatch in segment size
> > when trying to render HW decoded videos and rendering them directly with
> > sun4i DRM driver.
> > 
> > Fix that by setting DMA mask and segment size.
> > 
> > Signed-off-by: Jernej Skrabec 
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun4i_drv.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > b/drivers/gpu/drm/sun4i/sun4i_drv.c index 275f7e4a03ae..83f4e87f77f6
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> > @@ -7,6 +7,7 @@
> > 
> >   */
> >  
> >  #include 
> > 
> > +#include 
> > 
> >  #include 
> >  #include 
> >  #include 
> > 
> > @@ -367,6 +368,9 @@ static int sun4i_drv_probe(struct platform_device
> > *pdev)> 
> > INIT_KFIFO(list.fifo);
> > 
> > +   dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(32));
> 
> Isn't this already the default, from of_dma_configure_id or
> setup_pdev_dma_masks?

Not sure, I need to check.

> > +   dma_set_max_seg_size(>dev, DMA_BIT_MASK(32));
> 
> This looks like a good change. In fact, I think we need a similar change in
> some other drivers.

Should be DMA_BIT_MASK(25) as in your other patch?

Best regards,
Jernej

> 
> Regards,
> Samuel






Re: [PATCH] drm/sun4i: Fix crash during suspend after component bind failure

2022-06-15 Thread Jernej Škrabec
Dne sreda, 15. junij 2022 ob 07:42:53 CEST je Samuel Holland napisal(a):
> If the component driver fails to bind, or is unbound, the driver data
> for the top-level platform device points to a freed drm_device. If the
> system is then suspended, the driver passes this dangling pointer to
> drm_mode_config_helper_suspend(), which crashes.
> 
> Fix this by only setting the driver data while the platform driver holds
> a reference to the drm_device.
> 
> Fixes: 624b4b48d9d8 ("drm: sun4i: Add support for suspending the display 
driver")
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: [PATCH] drm/sun4i: dw-hdmi: Fix ddc-en GPIO consumer conflict

2022-06-14 Thread Jernej Škrabec
Dne torek, 14. junij 2022 ob 09:31:00 CEST je Samuel Holland napisal(a):
> commit 6de79dd3a920 ("drm/bridge: display-connector: add ddc-en gpio
> support") added a consumer for this GPIO in the HDMI connector device.
> This new consumer conflicts with the pre-existing GPIO consumer in the
> sun8i HDMI controller driver, which prevents the driver from probing:
> 
>   [4.983358] display-connector connector: GPIO lookup for consumer ddc-
en
>   [4.983364] display-connector connector: using device tree for GPIO 
lookup
>   [4.983392] gpio-226 (ddc-en): gpiod_request: status -16
>   [4.983399] sun8i-dw-hdmi 600.hdmi: Couldn't get ddc-en gpio
>   [4.983618] sun4i-drm display-engine: failed to bind 600.hdmi (ops 
sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -16
>   [4.984082] sun4i-drm display-engine: Couldn't bind all pipelines 
components
>   [4.984171] sun4i-drm display-engine: adev bind failed: -16
>   [4.984179] sun8i-dw-hdmi: probe of 600.hdmi failed with error -16
> 
> Both drivers have the same behavior: they leave the GPIO active for the
> life of the device. Let's take advantage of the new implementation, and
> drop the now-obsolete code from the HDMI controller driver.
> 
> Fixes: 6de79dd3a920 ("drm/bridge: display-connector: add ddc-en gpio 
support")
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej




Re: Re: [PATCH] drm/sun4i: sun8i: Add support for pixel blend mode property

2022-06-06 Thread Jernej Škrabec
Dne ponedeljek, 06. junij 2022 ob 10:17:20 CEST je Roman Stratiienko 
napisal(a):
> Hello Jernej,
> 
> Thank you for having a look.
> 
> вс, 5 июн. 2022 г. в 23:37, Jernej Škrabec :
> >
> > Dne nedelja, 05. junij 2022 ob 17:47:31 CEST je Roman Stratiienko 
napisal(a):
> > > Allwinner DE2 and DE3 hardware support 3 pixel blend modes:
> > > "None", "Pre-multiplied", "Coverage"
> > >
> > > Add the blend mode property and route it to the appropriate registers.
> > >
> > > Note:
> > > "force_premulti" parameter was added to handle multi-overlay channel
> > > cases in future changes. It must be set to true for cases when more
> > > than 1 overlay layer is used within a channel and at least one of the
> > > overlay layers within a group uses premultiplied blending mode.
> >
> > Please remove this parameter. It's nothing special, so it can be easily 
added
> > once it's actually needed. For now, it only complicates code.
> 
> I would prefer keeping it if you do not have any strong opinion against it.

Actually I do. Patch will be smaller and easier to follow if there is no extra 
variables with fixed values in it.

> 
> I am working now on exposing all overlays, so it will be needed soon anyway.

Well, it will just be one patch more there, if at all.

Regards,
Jernej

> 
> Also it helps to better understand the COV2PREMULT mode which has not
> the best description in the datasheet. Only after testing this
> register using devmem I became confident on its purpose.
> 
> >
> > >
> > > Test:
> > > Manually tested all the modes using kmsxx python wrapper with and
> > > without 'force_premulti' flag enabled.
> > >
> > > Signed-off-by: Roman Stratiienko 
> > > ---
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.h|  2 ++
> > >  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 48 -
> > >  drivers/gpu/drm/sun4i/sun8i_ui_layer.h |  5 +++
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 49 ++
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h |  5 +++
> > >  5 files changed, 94 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index ebfc276b2464..5c05907e26fb
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > @@ -65,6 +65,8 @@
> > >  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(n)  (0xf << ((n) << 2))
> > >  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(n)((n) << 2)
> > >
> > > +#define SUN8I_MIXER_BLEND_PREMULTIPLY_EN(pipe)   BIT(pipe)
> > > +
> > >  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED  BIT(1)
> > >
> > >  #define SUN50I_MIXER_BLEND_CSC_CTL_EN(ch)BIT(ch)
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> > > b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 6ccbbca3176d..
29c0d9cca19a
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> > > @@ -58,24 +58,46 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer
> > > *mixer, int channel, }
> > >
> > >  static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int
> > > channel, -int overlay, struct
> > drm_plane *plane)
> > > + int overlay, struct
> > drm_plane *plane,
> > > + unsigned int zpos,
> > bool force_premulti)
> > >  {
> > > - u32 mask, val, ch_base;
> > > + u32 mask, val, ch_base, bld_base;
> > > + bool in_premulti, out_premulti;
> > >
> > > + bld_base = sun8i_blender_base(mixer);
> > >   ch_base = sun8i_channel_base(mixer, channel);
> > >
> > > + in_premulti = plane->state->pixel_blend_mode ==
> > DRM_MODE_BLEND_PREMULTI;
> > > + out_premulti = force_premulti || in_premulti;
> > > +
> > >   mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK |
> > > - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK;
> > > +SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK |
> > > +SUN8I_MIXER_CHAN_UI_LAYER_ATTR_BLEND_MASK;
> > >
> > >   val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA(plane->state->alpha >>
> > 8);
> > >
> > > -

Re: [PATCH] drm/sun4i: sun8i: Add support for pixel blend mode property

2022-06-05 Thread Jernej Škrabec
Dne nedelja, 05. junij 2022 ob 17:47:31 CEST je Roman Stratiienko napisal(a):
> Allwinner DE2 and DE3 hardware support 3 pixel blend modes:
> "None", "Pre-multiplied", "Coverage"
> 
> Add the blend mode property and route it to the appropriate registers.
> 
> Note:
> "force_premulti" parameter was added to handle multi-overlay channel
> cases in future changes. It must be set to true for cases when more
> than 1 overlay layer is used within a channel and at least one of the
> overlay layers within a group uses premultiplied blending mode.

Please remove this parameter. It's nothing special, so it can be easily added 
once it's actually needed. For now, it only complicates code.

> 
> Test:
> Manually tested all the modes using kmsxx python wrapper with and
> without 'force_premulti' flag enabled.
> 
> Signed-off-by: Roman Stratiienko 
> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.h|  2 ++
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 48 -
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.h |  5 +++
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 49 ++
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.h |  5 +++
>  5 files changed, 94 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> b/drivers/gpu/drm/sun4i/sun8i_mixer.h index ebfc276b2464..5c05907e26fb
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -65,6 +65,8 @@
>  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(n)  (0xf << ((n) << 2))
>  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(n)((n) << 2)
> 
> +#define SUN8I_MIXER_BLEND_PREMULTIPLY_EN(pipe)   BIT(pipe)
> +
>  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED  BIT(1)
> 
>  #define SUN50I_MIXER_BLEND_CSC_CTL_EN(ch)BIT(ch)
> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 6ccbbca3176d..29c0d9cca19a
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> @@ -58,24 +58,46 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer
> *mixer, int channel, }
> 
>  static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int
> channel, -int overlay, struct 
drm_plane *plane)
> + int overlay, struct 
drm_plane *plane,
> + unsigned int zpos, 
bool force_premulti)
>  {
> - u32 mask, val, ch_base;
> + u32 mask, val, ch_base, bld_base;
> + bool in_premulti, out_premulti;
> 
> + bld_base = sun8i_blender_base(mixer);
>   ch_base = sun8i_channel_base(mixer, channel);
> 
> + in_premulti = plane->state->pixel_blend_mode == 
DRM_MODE_BLEND_PREMULTI;
> + out_premulti = force_premulti || in_premulti;
> +
>   mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK |
> - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK;
> +SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK |
> +SUN8I_MIXER_CHAN_UI_LAYER_ATTR_BLEND_MASK;
> 
>   val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA(plane->state->alpha >> 
8);
> 
> - val |= (plane->state->alpha == DRM_BLEND_ALPHA_OPAQUE) ?
> - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_PIXEL :
> - SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED;
> + if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE) {
> + val |= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_LAYER;
> + } else {
> + val |= (plane->state->alpha == DRM_BLEND_ALPHA_OPAQUE) 
?
> +
SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_PIXEL :
> +
SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED;
> +
> + if (in_premulti)
> + val |= 
SUN8I_MIXER_CHAN_UI_LAYER_ATTR_BLEND_PREMULTI;
> + }
> +
> + if (!in_premulti && out_premulti)
> + val |= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_BLEND_COV2PREM;
> 
>   regmap_update_bits(mixer->engine.regs,
>  SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, 
overlay),
>  mask, val);
> +
> + regmap_update_bits(
> + mixer->engine.regs, 
SUN8I_MIXER_BLEND_PREMULTIPLY(bld_base),
> + SUN8I_MIXER_BLEND_PREMULTIPLY_EN(zpos),
> + out_premulti ? SUN8I_MIXER_BLEND_PREMULTIPLY_EN(zpos) : 
0);
>  }
> 
>  static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int
> channel, @@ -274,7 +296,7 @@ static void
> sun8i_ui_layer_atomic_update(struct drm_plane *plane,
> sun8i_ui_layer_update_coord(mixer, layer->channel,
>   layer->overlay, plane, zpos);
>   sun8i_ui_layer_update_alpha(mixer, layer->channel,
> - layer->overlay, plane);
> + layer->overlay, plane, zpos, 
false);
>   sun8i_ui_layer_update_formats(mixer, layer->channel,
> layer->overlay, plane);
>   

Re: [PATCH v2] drm/sun4i: Enable output signal premultiplication for DE2/DE3

2022-06-05 Thread Jernej Škrabec
Dne nedelja, 05. junij 2022 ob 11:40:18 CEST je Roman Stratiienko napisal(a):
> Otherwise alpha value is discarded, resulting incorrect pixel
> apperance on the display.
> 
> This also fixes missing transparency for the most bottom layer.

Can you explain that a bit more? Also, BSP driver never enables this bit. What 
are we doing differently?

> 
> Test applications and videos w/ w/o this patch are available at [1].
> 
> [1]: https://github.com/GloDroid/glodroid_tests/issues/1

As stated in other emails, commit messages should not contain external links 
(per patch rules).

Best regards,
Jernej

> Signed-off-by: Roman Stratiienko 
> 
> ---
> Changelog:
> 
> V2: Added code hunk missing in v1
> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c | 5 +++--
>  drivers/gpu/drm/sun4i/sun8i_mixer.h | 1 +
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 6b1711a9a71f..ba2932aaed08
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -320,8 +320,9 @@ static void sun8i_mixer_mode_set(struct sunxi_engine
> *engine, else
>   val = 0;
> 
> - regmap_update_bits(engine->regs, 
SUN8I_MIXER_BLEND_OUTCTL(bld_base),
> -SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, 
val);
> + val |= SUN8I_MIXER_BLEND_OUTCTL_PREMULTIPLY;
> +
> + regmap_write(engine->regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base), 
val);
> 
>   DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
>interlaced ? "on" : "off");
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> b/drivers/gpu/drm/sun4i/sun8i_mixer.h index ebfc276b2464..bc12c95af6f3
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -65,6 +65,7 @@
>  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(n)  (0xf << ((n) << 2))
>  #define SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(n)((n) << 2)
> 
> +#define SUN8I_MIXER_BLEND_OUTCTL_PREMULTIPLY BIT(0)
>  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED  BIT(1)
> 
>  #define SUN50I_MIXER_BLEND_CSC_CTL_EN(ch)BIT(ch)






Re: Re: Re: Re: [PATCH] drm/sun4i: Fix blend registers corruption for DE2.0/DE3.0

2022-05-25 Thread Jernej Škrabec
Dne sreda, 25. maj 2022 ob 16:55:56 CEST je Roman Stratiienko napisal(a):
> вт, 24 мая 2022 г. в 22:14, Jernej Škrabec :
> >
> > Dne torek, 24. maj 2022 ob 19:14:35 CEST je Roman Stratiienko napisal(a):
> > > By the way, not related to this issue:
> > >
> > > I cherry-picked
> > > https://patchwork.kernel.org/project/dri-devel/patch/
20220424162633.12369-9-sam...@sholland.org/
> > > and got a blank FB console on OPI3.
> > > Can you check it please?
> >
> > Reply to that patch and we'll talk.
> 
> Despite the fact that I am the original author of the patches I'm not
> even in CC, so I can respond to this thread.

Actually, many people come up with similar idea.

> Is there any other way to respond to the message where you're not in CC?

Of course, I download patch as mbox and import it in my e-mail client. A reply 
to it will continue the thread.

Best regards,
Jernej

> 
> >
> > Best regards,
> > Jernej
> >
> > >
> > > Regards,
> > > Roman
> > >
> > >
> > >
> > > вт, 24 мая 2022 г. в 20:10, Roman Stratiienko :
> > > >
> > > > Please draft a test for the zpos issue you're mentioning.
> > > >
> > > > It's very easy to do with kmsxx using python wrapper.
> > > >
> > > > Or explain steps to reproduce here, I will write it by myself.
> > > >
> > > > Thanks.
> > > > Regards
> > > > Roman
> > > >
> > > > вт, 24 мая 2022 г. в 19:21, Jernej Škrabec :
> > > > >
> > > > > Dne torek, 24. maj 2022 ob 17:31:13 CEST je Roman Stratiienko
> > napisal(a):
> > > > > > NAK for this. Further testing showed such an approach is not 
reliable
> > > > > > due to .atomic_update() callback called only in case planes have 
some
> > > > > > changes.
> > > > >
> > > > > Additionally, I think it would be better to fix underlaying zpos 
issue
> > first
> > > > > (attempted many times) and then worry about blending.
> > > > >
> > > > > Best regards,
> > > > > Jernej
> > > > >
> > > > > >
> > > > > > вт, 24 мая 2022 г. в 16:52, Roman Stratiienko
> > :
> > > > > > >
> > > > > > > Corruption happens when plane zpos is updated
> > > > > > >
> > > > > > > Example scenario:
> > > > > > >
> > > > > > > Initial frame blender state:
> > > > > > > PLANE_ZPOS = {0, 1, 2, 3}
> > > > > > > BLD_ROUTE  = {0, 1, 2, 0}
> > > > > > > BLD_EN = {1, 1, 1, 0}
> > > > > > >
> > > > > > > New frame commit (Only ZPOS has been changed):
> > > > > > >
> > > > > > > PLANE_ZPOS = {0->2, 1->0, 2->1, 3}
> > > > > > >
> > > > > > > Expected results after plane state update:
> > > > > > > Z0 Z1 Z2 Z3
> > > > > > > BLD_ROUTE = {1, 2, 0, 0}
> > > > > > > BLD_EN= {1, 1, 1, 0}
> > > > > > >
> > > > > > > What is currently happening:
> > > > > > >
> > > > > > > 1. sun8i_vi_layer_enable(enabled=true, zpos=2, old_zpos=0):
> > > > > > > BLD_ROUTE = {1->0, 1, 2->0, 0}
> > > > > > > BLD_EN= {1->0, 1, 1->1, 0}
> > > > > > >
> > > > > > > 2. sun8i_ui_layer_enable(enabled=true, zpos=0, old_zpos=1):
> > > > > > > BLD_ROUTE = {0->1, 1->0, 0, 0}
> > > > > > > BLD_EN= {0->1, 1->0, 1, 0}
> > > > > > >
> > > > > > > 3. sun8i_ui_layer_enable(enabled=true, zpos=1, old_zpos=2):
> > > > > > > BLD_ROUTE = {1, 0->2, 0->0, 0}
> > > > > > > BLD_EN= {1, 0->2, 1->0, 0}
> > > > > > >
> > > > > > > After updating of all the planes we are ending up with 
BLD_EN[2]=0,
> > > > > > > which makes this channel disabled.
> > > > > > >
> > > > > > > To fix this issue, clear BLEND registers before updating the 
planes
> > > > > > > and do not clear the old state while processing every plane.
> > > > > >

Re: Re: Re: [PATCH] drm/sun4i: Fix blend registers corruption for DE2.0/DE3.0

2022-05-24 Thread Jernej Škrabec
Dne torek, 24. maj 2022 ob 19:14:35 CEST je Roman Stratiienko napisal(a):
> By the way, not related to this issue:
> 
> I cherry-picked
> https://patchwork.kernel.org/project/dri-devel/patch/20220424162633.12369-9-sam...@sholland.org/
> and got a blank FB console on OPI3.
> Can you check it please?

Reply to that patch and we'll talk.

Best regards,
Jernej

> 
> Regards,
> Roman
> 
> 
> 
> вт, 24 мая 2022 г. в 20:10, Roman Stratiienko :
> >
> > Please draft a test for the zpos issue you're mentioning.
> >
> > It's very easy to do with kmsxx using python wrapper.
> >
> > Or explain steps to reproduce here, I will write it by myself.
> >
> > Thanks.
> > Regards
> > Roman
> >
> > вт, 24 мая 2022 г. в 19:21, Jernej Škrabec :
> > >
> > > Dne torek, 24. maj 2022 ob 17:31:13 CEST je Roman Stratiienko 
napisal(a):
> > > > NAK for this. Further testing showed such an approach is not reliable
> > > > due to .atomic_update() callback called only in case planes have some
> > > > changes.
> > >
> > > Additionally, I think it would be better to fix underlaying zpos issue 
first
> > > (attempted many times) and then worry about blending.
> > >
> > > Best regards,
> > > Jernej
> > >
> > > >
> > > > вт, 24 мая 2022 г. в 16:52, Roman Stratiienko 
:
> > > > >
> > > > > Corruption happens when plane zpos is updated
> > > > >
> > > > > Example scenario:
> > > > >
> > > > > Initial frame blender state:
> > > > > PLANE_ZPOS = {0, 1, 2, 3}
> > > > > BLD_ROUTE  = {0, 1, 2, 0}
> > > > > BLD_EN = {1, 1, 1, 0}
> > > > >
> > > > > New frame commit (Only ZPOS has been changed):
> > > > >
> > > > > PLANE_ZPOS = {0->2, 1->0, 2->1, 3}
> > > > >
> > > > > Expected results after plane state update:
> > > > > Z0 Z1 Z2 Z3
> > > > > BLD_ROUTE = {1, 2, 0, 0}
> > > > > BLD_EN= {1, 1, 1, 0}
> > > > >
> > > > > What is currently happening:
> > > > >
> > > > > 1. sun8i_vi_layer_enable(enabled=true, zpos=2, old_zpos=0):
> > > > > BLD_ROUTE = {1->0, 1, 2->0, 0}
> > > > > BLD_EN= {1->0, 1, 1->1, 0}
> > > > >
> > > > > 2. sun8i_ui_layer_enable(enabled=true, zpos=0, old_zpos=1):
> > > > > BLD_ROUTE = {0->1, 1->0, 0, 0}
> > > > > BLD_EN= {0->1, 1->0, 1, 0}
> > > > >
> > > > > 3. sun8i_ui_layer_enable(enabled=true, zpos=1, old_zpos=2):
> > > > > BLD_ROUTE = {1, 0->2, 0->0, 0}
> > > > > BLD_EN= {1, 0->2, 1->0, 0}
> > > > >
> > > > > After updating of all the planes we are ending up with BLD_EN[2]=0,
> > > > > which makes this channel disabled.
> > > > >
> > > > > To fix this issue, clear BLEND registers before updating the planes
> > > > > and do not clear the old state while processing every plane.
> > > > >
> > > > > Signed-off-by: Roman Stratiienko 

> > > > > ---
> > > > >  drivers/gpu/drm/sun4i/sun8i_mixer.c| 16 +++
> > > > >  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 28 +++
+--
> > > > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 28 +++
+--
> > > > >  3 files changed, 24 insertions(+), 48 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/
sun4i/
> > > sun8i_mixer.c
> > > > > index f5e8aeaa3cdf..004377a000fc 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > > @@ -248,6 +248,21 @@ int sun8i_mixer_drm_format_to_hw(u32 format, 
u32
> > > *hw_format)
> > > > > return -EINVAL;
> > > > >  }
> > > > >
> > > > > +static void sun8i_atomic_begin(struct sunxi_engine *engine,
> > > > > +  struct drm_crtc_state *old_state)
> > > > > +{
> > > > > +   struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
> > > > > +   u32 bld_base = sun8i_blender_base(mixer);
>

Re: Re: Re: [PATCH] drm/sun4i: Fix blend registers corruption for DE2.0/DE3.0

2022-05-24 Thread Jernej Škrabec
Don't top post, it's annoying and against rules.

Dne torek, 24. maj 2022 ob 19:10:06 CEST je Roman Stratiienko napisal(a):
> Please draft a test for the zpos issue you're mentioning.
> 
> It's very easy to do with kmsxx using python wrapper.
> 
> Or explain steps to reproduce here, I will write it by myself.

I'm talking about the issue which you, Ondrej Jirman and me all tried to fix it 
in the past one way or another:

https://patchwork.kernel.org/project/dri-devel/patch/20190914220337.646719-1-meg...@megous.com/
https://patchwork.kernel.org/project/dri-devel/patch/20210106204630.1800284-1-jernej.skra...@siol.net/

Best regards,
Jernej

> 
> Thanks.
> Regards
> Roman
> 
> вт, 24 мая 2022 г. в 19:21, Jernej Škrabec :
> >
> > Dne torek, 24. maj 2022 ob 17:31:13 CEST je Roman Stratiienko napisal(a):
> > > NAK for this. Further testing showed such an approach is not reliable
> > > due to .atomic_update() callback called only in case planes have some
> > > changes.
> >
> > Additionally, I think it would be better to fix underlaying zpos issue first
> > (attempted many times) and then worry about blending.
> >
> > Best regards,
> > Jernej
> >
> > >
> > > вт, 24 мая 2022 г. в 16:52, Roman Stratiienko :
> > > >
> > > > Corruption happens when plane zpos is updated
> > > >
> > > > Example scenario:
> > > >
> > > > Initial frame blender state:
> > > > PLANE_ZPOS = {0, 1, 2, 3}
> > > > BLD_ROUTE  = {0, 1, 2, 0}
> > > > BLD_EN = {1, 1, 1, 0}
> > > >
> > > > New frame commit (Only ZPOS has been changed):
> > > >
> > > > PLANE_ZPOS = {0->2, 1->0, 2->1, 3}
> > > >
> > > > Expected results after plane state update:
> > > > Z0 Z1 Z2 Z3
> > > > BLD_ROUTE = {1, 2, 0, 0}
> > > > BLD_EN= {1, 1, 1, 0}
> > > >
> > > > What is currently happening:
> > > >
> > > > 1. sun8i_vi_layer_enable(enabled=true, zpos=2, old_zpos=0):
> > > > BLD_ROUTE = {1->0, 1, 2->0, 0}
> > > > BLD_EN= {1->0, 1, 1->1, 0}
> > > >
> > > > 2. sun8i_ui_layer_enable(enabled=true, zpos=0, old_zpos=1):
> > > > BLD_ROUTE = {0->1, 1->0, 0, 0}
> > > > BLD_EN= {0->1, 1->0, 1, 0}
> > > >
> > > > 3. sun8i_ui_layer_enable(enabled=true, zpos=1, old_zpos=2):
> > > > BLD_ROUTE = {1, 0->2, 0->0, 0}
> > > > BLD_EN= {1, 0->2, 1->0, 0}
> > > >
> > > > After updating of all the planes we are ending up with BLD_EN[2]=0,
> > > > which makes this channel disabled.
> > > >
> > > > To fix this issue, clear BLEND registers before updating the planes
> > > > and do not clear the old state while processing every plane.
> > > >
> > > > Signed-off-by: Roman Stratiienko 
> > > > ---
> > > >  drivers/gpu/drm/sun4i/sun8i_mixer.c| 16 +++
> > > >  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 28 +++
+--
> > > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 28 +++
+--
> > > >  3 files changed, 24 insertions(+), 48 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/
sun4i/
> > sun8i_mixer.c
> > > > index f5e8aeaa3cdf..004377a000fc 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > @@ -248,6 +248,21 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32
> > *hw_format)
> > > > return -EINVAL;
> > > >  }
> > > >
> > > > +static void sun8i_atomic_begin(struct sunxi_engine *engine,
> > > > +  struct drm_crtc_state *old_state)
> > > > +{
> > > > +   struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
> > > > +   u32 bld_base = sun8i_blender_base(mixer);
> > > > +
> > > > +   regmap_write(engine->regs,
> > > > +SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
> > > > +0);
> > > > +
> > > > +   regmap_write(engine->regs,
> > > > +SUN8I_MIXER_BLEND_ROUTE(bld_base),
> > > > +0);
> > > > +}
> > > > +
> > > >  static void sun

Re: Re: [PATCH] drm/sun4i: mixer: fix scanline for V3s and D1

2022-05-24 Thread Jernej Škrabec
Dne nedelja, 22. maj 2022 ob 12:48:27 CEST je benly...@gmail.com napisal(a):
> Hi Jernej!
> 
> > Which SDK? All SDKs that I have or found on internet don't mention YUV nor 
RGB
> > scanline limit. That doesn't mean there is none, I'm just unable to verify
> > your claim. Did you test this by yourself? Also, please make YUV scanline
> > change separate patch with fixes tag.
> 
> Here is the code about scanline config for V3s:
> https://github.com/Tina-Linux/tina-v3s-linux-4.9/blob/master/drivers/video/
fbdev/sunxi/disp2/disp/de/lowlevel_sun8iw8/de_feat.c#L55
> https://github.com/Tina-Linux/tina-v3s-linux-4.9/blob/master/drivers/video/
fbdev/sunxi/disp2/disp/de/lowlevel_sun8iw8/de_rtmx.c#L1212
> 
> And here is for D1:
> https://gitlab.com/weidongshan/tina-d1-h/-/blob/main/lichee/linux-5.4/
drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_v2x/de_feat.c#L182
> https://gitlab.com/weidongshan/tina-d1-h/-/blob/main/lichee/linux-5.4/
drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_v2x/de_rtmx.c#L1588

Thanks for the links!

> 
> I was tested it on V3s. Without this patch, the plane will not display
> correctly if src_w large than 1024, for both YUV and RGB. I don't have a
> device with D1, so D1 is not tested. But according to the SDK code of D1,
> the scanline value of mixer1 is 1024.
> 
> I'm new to submitting patches, So may I ask a question? If there is no
> problem with this patch, what I need to do is to send new patches as you
> suggested?

https://www.kernel.org/doc/html/latest/process/submitting-patches.html

I already requested changes, so you need to send v2. But wait until discussion 
is finished.

Best regards,
Jernej

> 
> Best regards,
> Genfu Pan
> 
> 




Re: Re: [PATCH] drm/sun4i: mixer: fix scanline for V3s and D1

2022-05-24 Thread Jernej Škrabec
Dne torek, 24. maj 2022 ob 19:07:27 CEST je Samuel Holland napisal(a):
> On 5/23/22 8:14 AM, Icenowy Zheng wrote:
> > 在 2022-05-22星期日的 10:36 +0200,Jernej Škrabec写道:
> >> Hi!
> >>
> >> Dne sobota, 21. maj 2022 ob 15:34:43 CEST je Genfu Pan napisal(a):
> >>> Accrording the SDK from Allwinner, the scanline value of yuv and
> >>> rgb for
> >>> V3s are both 1024.
> >>
> >> s/scanline value/scanline length/
> >>
> >> Which SDK? All SDKs that I have or found on internet don't mention
> >> YUV nor RGB 
> >> scanline limit. That doesn't mean there is none, I'm just unable to
> >> verify 
> >> your claim. Did you test this by yourself? Also, please make YUV
> >> scanline 
> >> change separate patch with fixes tag.
> > 
> > BTW I think chip manuals all say that the chip supports NxN resolution
> > in DE2 chapter, e.g. the V3 datasheet says DE2 "Output size up to
> > 1024x1024".
> > 
> > However there's no information about D1's second mixer.
> 
> My information comes from the BSP driver[0]:
> 
> static const int sun8iw20_de_scale_line_buffer[] = {
> /* DISP0 */
> 2048,
> /* DISP1 */
> 1024,
> };
> 
> It looks like the value returned from de_feat_get_scale_linebuf() may be 
used
> for RGB as well, if scaling is enabled. This appears to be the "format == 3"
> case in de_rtmx_get_coarse_fac[1]. On the other hand, the code for V3 has
> specific code for the RGB limit[2].
> 
> Is there some test I can do on D1 to see what the right value for RGB is?

I use modetest for such tests. It's part of libdrm. In general, you want to 
make plane wider than scanline and then scale it down. Obviously you want to 
test this once with RGB and once with YUV format. This is all done with 
"modetest -P".

Best regards,
Jernej

> 
> Regards,
> Samuel
> 
> [0]:
> https://github.com/Tina-Linux/tina-d1x-linux-5.4/blob/master/drivers/video/
fbdev/sunxi/disp2/disp/de/lowlevel_v2x/de_feat.c#L182
> [1]:
> https://github.com/Tina-Linux/tina-d1x-linux-5.4/blob/master/drivers/video/
fbdev/sunxi/disp2/disp/de/lowlevel_v2x/de_rtmx.c#L1588
> [2]:
> https://github.com/Tina-Linux/tina-d1x-linux-5.4/blob/master/drivers/video/
fbdev/sunxi/disp2/disp/de/lowlevel_sun8iw8/de_rtmx.c#L1211
> 
> >>> The is also the same for mixer 1 of D1. Currently the
> >>> scanline value of rgb is hardcoded to 2048 for all SOCs.
> >>>
> >>> Change the scanline_yuv property of V3s to 1024. > Add the
> >>> scanline_rgb
> >>> property to the mixer config and replace the hardcoded value with
> >>> it before
> >>> scaling.
> >>
> >> I guess RGB scanline patch would also need fixes tag, since it fixes
> >> existing 
> >> bug.
> >>
> >>>
> >>> Signed-off-by: Genfu Pan 
> >>> ---
> >>>  drivers/gpu/drm/sun4i/sun8i_mixer.c| 13 -
> >>>  drivers/gpu/drm/sun4i/sun8i_mixer.h|  1 +
> >>>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c |  3 +--
> >>>  3 files changed, 14 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> >>> b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 875a1156c..e64e08207
> >>> 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> >>> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> >>> @@ -567,6 +567,7 @@ static const struct sun8i_mixer_cfg
> >>> sun8i_a83t_mixer0_cfg = { .ccsc = CCSC_MIXER0_LAYOUT,
> >>> .scaler_mask= 0xf,
> >>> .scanline_yuv   = 2048,
> >>> +   .scanline_rgb   = 2048,
> >>> .ui_num = 3,
> >>> .vi_num = 1,
> >>>  };
> >>> @@ -575,6 +576,7 @@ static const struct sun8i_mixer_cfg
> >>> sun8i_a83t_mixer1_cfg = { .ccsc = CCSC_MIXER1_LAYOUT,
> >>> .scaler_mask= 0x3,
> >>> .scanline_yuv   = 2048,
> >>> +   .scanline_rgb   = 2048,
> >>> .ui_num = 1,
> >>> .vi_num = 1,
> >>>  };
> >>> @@ -584,6 +586,7 @@ static const struct sun8i_mixer_cfg
> >>> sun8i_h3_mixer0_cfg
> >>> = { .mod_rate   = 43200,
> >>> .scaler_mask= 0xf,
> >>> .scanline_yuv   = 2048,
> >>> +   .scanline_rgb   = 2048,
> >>> .ui_num = 3,
> >>> .vi_num   

Re: Re: [PATCH] drm/sun4i: Fix blend registers corruption for DE2.0/DE3.0

2022-05-24 Thread Jernej Škrabec
Dne torek, 24. maj 2022 ob 17:31:13 CEST je Roman Stratiienko napisal(a):
> NAK for this. Further testing showed such an approach is not reliable
> due to .atomic_update() callback called only in case planes have some
> changes.

Additionally, I think it would be better to fix underlaying zpos issue first 
(attempted many times) and then worry about blending.

Best regards,
Jernej

> 
> вт, 24 мая 2022 г. в 16:52, Roman Stratiienko :
> >
> > Corruption happens when plane zpos is updated
> >
> > Example scenario:
> >
> > Initial frame blender state:
> > PLANE_ZPOS = {0, 1, 2, 3}
> > BLD_ROUTE  = {0, 1, 2, 0}
> > BLD_EN = {1, 1, 1, 0}
> >
> > New frame commit (Only ZPOS has been changed):
> >
> > PLANE_ZPOS = {0->2, 1->0, 2->1, 3}
> >
> > Expected results after plane state update:
> > Z0 Z1 Z2 Z3
> > BLD_ROUTE = {1, 2, 0, 0}
> > BLD_EN= {1, 1, 1, 0}
> >
> > What is currently happening:
> >
> > 1. sun8i_vi_layer_enable(enabled=true, zpos=2, old_zpos=0):
> > BLD_ROUTE = {1->0, 1, 2->0, 0}
> > BLD_EN= {1->0, 1, 1->1, 0}
> >
> > 2. sun8i_ui_layer_enable(enabled=true, zpos=0, old_zpos=1):
> > BLD_ROUTE = {0->1, 1->0, 0, 0}
> > BLD_EN= {0->1, 1->0, 1, 0}
> >
> > 3. sun8i_ui_layer_enable(enabled=true, zpos=1, old_zpos=2):
> > BLD_ROUTE = {1, 0->2, 0->0, 0}
> > BLD_EN= {1, 0->2, 1->0, 0}
> >
> > After updating of all the planes we are ending up with BLD_EN[2]=0,
> > which makes this channel disabled.
> >
> > To fix this issue, clear BLEND registers before updating the planes
> > and do not clear the old state while processing every plane.
> >
> > Signed-off-by: Roman Stratiienko 
> > ---
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c| 16 +++
> >  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 28 --
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 28 --
> >  3 files changed, 24 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/
sun8i_mixer.c
> > index f5e8aeaa3cdf..004377a000fc 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > @@ -248,6 +248,21 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 
*hw_format)
> > return -EINVAL;
> >  }
> >
> > +static void sun8i_atomic_begin(struct sunxi_engine *engine,
> > +  struct drm_crtc_state *old_state)
> > +{
> > +   struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
> > +   u32 bld_base = sun8i_blender_base(mixer);
> > +
> > +   regmap_write(engine->regs,
> > +SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
> > +0);
> > +
> > +   regmap_write(engine->regs,
> > +SUN8I_MIXER_BLEND_ROUTE(bld_base),
> > +0);
> > +}
> > +
> >  static void sun8i_mixer_commit(struct sunxi_engine *engine)
> >  {
> > DRM_DEBUG_DRIVER("Committing changes\n");
> > @@ -299,6 +314,7 @@ static struct drm_plane **sun8i_layers_init(struct 
drm_device *drm,
> >  }
> >
> >  static const struct sunxi_engine_ops sun8i_engine_ops = {
> > +   .atomic_begin   = sun8i_atomic_begin,
> > .commit = sun8i_mixer_commit,
> > .layers_init= sun8i_layers_init,
> >  };
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/
sun4i/sun8i_ui_layer.c
> > index 7845c2a53a7f..b294a882626a 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> > @@ -24,8 +24,7 @@
> >  #include "sun8i_ui_scaler.h"
> >
> >  static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
> > - int overlay, bool enable, unsigned int 
zpos,
> > - unsigned int old_zpos)
> > + int overlay, bool enable, unsigned int 
zpos)
> >  {
> > u32 val, bld_base, ch_base;
> >
> > @@ -44,18 +43,6 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer 
*mixer, int channel,
> >SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, 
overlay),
> >SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
> >
> > -   if (!enable || zpos != old_zpos) {
> > -   regmap_update_bits(mixer->engine.regs,
> > -  SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
> > -  
SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
> > -  0);
> > -
> > -   regmap_update_bits(mixer->engine.regs,
> > -  SUN8I_MIXER_BLEND_ROUTE(bld_base),
> > -  
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
> > -  0);
> > -   }
> > -
> > if (enable) {
> > val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
> >
> > @@ -291,31 +278,24 @@ static int sun8i_ui_layer_atomic_check(struct 

Re: [PATCH] drm/sun4i: mixer: fix scanline for V3s and D1

2022-05-22 Thread Jernej Škrabec
Hi!

Dne sobota, 21. maj 2022 ob 15:34:43 CEST je Genfu Pan napisal(a):
> Accrording the SDK from Allwinner, the scanline value of yuv and rgb for
> V3s are both 1024.

s/scanline value/scanline length/

Which SDK? All SDKs that I have or found on internet don't mention YUV nor RGB 
scanline limit. That doesn't mean there is none, I'm just unable to verify 
your claim. Did you test this by yourself? Also, please make YUV scanline 
change separate patch with fixes tag.

> The is also the same for mixer 1 of D1. Currently the
> scanline value of rgb is hardcoded to 2048 for all SOCs.
> 
> Change the scanline_yuv property of V3s to 1024. > Add the scanline_rgb
> property to the mixer config and replace the hardcoded value with it before
> scaling.

I guess RGB scanline patch would also need fixes tag, since it fixes existing 
bug.

> 
> Signed-off-by: Genfu Pan 
> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c| 13 -
>  drivers/gpu/drm/sun4i/sun8i_mixer.h|  1 +
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c |  3 +--
>  3 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 875a1156c..e64e08207 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -567,6 +567,7 @@ static const struct sun8i_mixer_cfg
> sun8i_a83t_mixer0_cfg = { .ccsc   = CCSC_MIXER0_LAYOUT,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 3,
>   .vi_num = 1,
>  };
> @@ -575,6 +576,7 @@ static const struct sun8i_mixer_cfg
> sun8i_a83t_mixer1_cfg = { .ccsc   = CCSC_MIXER1_LAYOUT,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 1,
>   .vi_num = 1,
>  };
> @@ -584,6 +586,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg
> = { .mod_rate = 43200,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 3,
>   .vi_num = 1,
>  };
> @@ -593,6 +596,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg
> = { .mod_rate = 29700,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 3,
>   .vi_num = 1,
>  };
> @@ -602,6 +606,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg
> = { .mod_rate = 29700,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 1,
>   .vi_num = 1,
>  };
> @@ -610,7 +615,8 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg
> = { .vi_num = 2,
>   .ui_num = 1,
>   .scaler_mask = 0x3,
> - .scanline_yuv = 2048,
> + .scanline_yuv = 1024,
> + .scanline_rgb = 1024,
>   .ccsc = CCSC_MIXER0_LAYOUT,
>   .mod_rate = 15000,
>  };
> @@ -620,6 +626,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg
> = { .mod_rate = 29700,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 1,
>   .vi_num = 1,
>  };
> @@ -629,6 +636,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg
> = { .mod_rate = 29700,
>   .scaler_mask= 0x1,
>   .scanline_yuv   = 1024,
> + .scanline_rgb   = 1024,
>   .ui_num = 0,
>   .vi_num = 1,
>  };
> @@ -638,6 +646,7 @@ static const struct sun8i_mixer_cfg
> sun50i_a64_mixer0_cfg = { .mod_rate   = 29700,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 4096,
> + .scanline_rgb   = 2048,
>   .ui_num = 3,
>   .vi_num = 1,
>  };
> @@ -647,6 +656,7 @@ static const struct sun8i_mixer_cfg
> sun50i_a64_mixer1_cfg = { .mod_rate   = 29700,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> + .scanline_rgb   = 2048,
>   .ui_num = 1,
>   .vi_num = 1,
>  };
> @@ -657,6 +667,7 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg
> = { .mod_rate = 6,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 4096,
> + .scanline_rgb   = 2048,
>   .ui_num = 3,
>   .vi_num = 1,
>  };
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 85c94884f..c01b3e9d6 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -172,6 +172,7 @@ struct sun8i_mixer_cfg {
>   unsigned long   mod_rate;
>   unsigned intis_de3 : 1;
>   unsigned intscanline_yuv;
> + unsigned intscanline_rgb;

This quirk needs to be documented above in the comment.

Best regards,
Jernej

>  };
> 
>  struct sun8i_mixer {
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index f7d0b082d..30e6bde92 100644
> --- 

Re: [PATCH v3 2/3] drm/fb-helper: Rename preferred_bpp drm_fbdev_generic_setup() parameter

2022-05-03 Thread Jernej Škrabec
Dne torek, 03. maj 2022 ob 09:15:39 CEST je Javier Martinez Canillas 
napisal(a):
> By default the bits per pixel for the emulated framebuffer device is set
> to dev->mode_config.preferred_depth, but some devices need another value.
> 
> Since this second parameter is only used by a few drivers, and to allow
> drivers to use it for passing other configurations when registering the
> fbdev, rename @preferred_bpp to @options and make it a multi-field param.
> 
> The DRM_FB_OPTION() and DRM_FB_GET_OPTION() macros are provided to drivers
> for computing options bitfield values and getting the values respectively
> 
> For now, only the DRM_FB_BPP option exists but other options can be added.
> 
> Suggested-by: Thomas Zimmermann 
> Signed-off-by: Javier Martinez Canillas 
> Reviewed-by: Thomas Zimmermann 
> Reviewed-by: Laurent Pinchart 
> ---
> 
> Changes in v3:
> - Drop the preferred_bpp local variable (Laurent Pinchart).
> - Add a const qualifier to options parameter (Laurent Pinchart).
> 
> Changes in v2:
> - Rename DRM_FB_SET_OPTION() to DRM_FB_OPTION() and make more clear in
>   the kernel-doc what this macro does (Laurent Pinchart).
> - Fix some kernel-doc issues I didn't notice in v1.
> - Add Reviewed-by tags from Thomas and Laurent.
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  6 +++--
>  drivers/gpu/drm/arm/hdlcd_drv.c   |  2 +-
>  drivers/gpu/drm/arm/malidp_drv.c  |  2 +-
>  drivers/gpu/drm/aspeed/aspeed_gfx_drv.c   |  2 +-
>  drivers/gpu/drm/ast/ast_drv.c |  2 +-
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  |  2 +-
>  drivers/gpu/drm/drm_drv.c |  2 +-
>  drivers/gpu/drm/drm_fb_helper.c   | 26 ---
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c |  2 +-
>  .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c   |  2 +-
>  drivers/gpu/drm/imx/dcss/dcss-kms.c   |  2 +-
>  drivers/gpu/drm/imx/imx-drm-core.c|  2 +-
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c |  2 +-
>  drivers/gpu/drm/mcde/mcde_drv.c   |  2 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c|  2 +-
>  drivers/gpu/drm/meson/meson_drv.c |  2 +-
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c |  2 +-
>  drivers/gpu/drm/pl111/pl111_drv.c |  2 +-
>  drivers/gpu/drm/qxl/qxl_drv.c |  2 +-
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c |  2 +-
>  drivers/gpu/drm/sti/sti_drv.c |  2 +-
>  drivers/gpu/drm/stm/drv.c |  2 +-
>  drivers/gpu/drm/sun4i/sun4i_drv.c |  2 +-

For sun4i:
Acked-by: Jernej Skrabec 

Best regard,
Jernej

>  drivers/gpu/drm/tidss/tidss_drv.c |  2 +-
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c   |  2 +-
>  drivers/gpu/drm/tiny/arcpgu.c |  2 +-
>  drivers/gpu/drm/tiny/bochs.c  |  2 +-
>  drivers/gpu/drm/tve200/tve200_drv.c   |  2 +-
>  drivers/gpu/drm/vboxvideo/vbox_drv.c  |  2 +-
>  drivers/gpu/drm/vc4/vc4_drv.c |  2 +-
>  drivers/gpu/drm/virtio/virtgpu_drv.c  |  2 +-
>  drivers/gpu/drm/xlnx/zynqmp_dpsub.c   |  2 +-
>  include/drm/drm_fb_helper.h   | 14 +-
>  33 files changed, 64 insertions(+), 42 deletions(-)





Re: [PATCH v3 13/14] drm/sun4i: Add support for D1 TCONs

2022-04-24 Thread Jernej Škrabec
Dne nedelja, 24. april 2022 ob 18:26:31 CEST je Samuel Holland napisal(a):
> D1 has a TCON TOP, so its quirks are similar to those for the R40 TCONs.
> While there are some register changes, the part of the TCON TV supported
> by the driver matches the R40 quirks, so that quirks structure can be
> reused. D1 has the first supported TCON LCD with a TCON TOP, so the TCON
> LCD needs a new quirks structure.
> 
> D1's TCON LCD hardware supports LVDS; in fact it provides dual-link LVDS
> from a single TCON. However, it comes with a brand new LVDS PHY. Since
> this PHY has not been tested, leave out LVDS driver support for now.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej Skrabec

> ---
> 
> (no changes since v1)
> 
>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/
sun4i_tcon.c
> index 88db2d2a9336..2ee158aaeb9e 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -1542,6 +1542,12 @@ static const struct sun4i_tcon_quirks 
sun9i_a80_tcon_tv_quirks = {
>   .needs_edp_reset = true,
>  };
>  
> +static const struct sun4i_tcon_quirks sun20i_d1_lcd_quirks = {
> + .has_channel_0  = true,
> + .dclk_min_div   = 1,
> + .set_mux= sun8i_r40_tcon_tv_set_mux,
> +};
> +
>  /* sun4i_drv uses this list to check if a device node is a TCON */
>  const struct of_device_id sun4i_tcon_of_table[] = {
>   { .compatible = "allwinner,sun4i-a10-tcon", .data = 
_a10_quirks },
> @@ -1559,6 +1565,8 @@ const struct of_device_id sun4i_tcon_of_table[] = {
>   { .compatible = "allwinner,sun8i-v3s-tcon", .data = 
_v3s_quirks },
>   { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = 
_a80_tcon_lcd_quirks },
>   { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = 
_a80_tcon_tv_quirks },
> + { .compatible = "allwinner,sun20i-d1-tcon-lcd", .data = 
_d1_lcd_quirks },
> + { .compatible = "allwinner,sun20i-d1-tcon-tv", .data = 
_r40_tv_quirks },
>   { }
>  };
>  MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
> -- 
> 2.35.1
> 
> 




Re: [PATCH v3 12/14] drm/sun4i: Add support for D1 TCON TOP

2022-04-24 Thread Jernej Škrabec
Dne nedelja, 24. april 2022 ob 18:26:30 CEST je Samuel Holland napisal(a):
> D1 has a TCON TOP with TCON TV0 and DSI, but no TCON TV1. This puts the
> DSI clock name at index 1 in clock-output-names. Support this by only
> incrementing the index for clocks that are actually supported.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej Skrabec

> ---
> 
> (no changes since v1)
> 
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 15 ---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/
sun8i_tcon_top.c
> index 1b9b8b48f4a7..da97682b6835 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> @@ -189,22 +189,23 @@ static int sun8i_tcon_top_bind(struct device *dev, 
struct device *master,
>* if TVE is active on each TCON TV. If it is, mux should be 
switched
>* to TVE clock parent.
>*/
> + i = 0;
>   clk_data->hws[CLK_TCON_TOP_TV0] =
>   sun8i_tcon_top_register_gate(dev, "tcon-tv0", regs,
>_top-
>reg_lock,
> -  
TCON_TOP_TCON_TV0_GATE, 0);
> +  
TCON_TOP_TCON_TV0_GATE, i++);
>  
>   if (quirks->has_tcon_tv1)
>   clk_data->hws[CLK_TCON_TOP_TV1] =
>   sun8i_tcon_top_register_gate(dev, "tcon-
tv1", regs,
>
_top->reg_lock,
> -  
TCON_TOP_TCON_TV1_GATE, 1);
> +  
TCON_TOP_TCON_TV1_GATE, i++);
>  
>   if (quirks->has_dsi)
>   clk_data->hws[CLK_TCON_TOP_DSI] =
>   sun8i_tcon_top_register_gate(dev, "dsi", 
regs,
>
_top->reg_lock,
> -  
TCON_TOP_TCON_DSI_GATE, 2);
> +  
TCON_TOP_TCON_DSI_GATE, i++);
>  
>   for (i = 0; i < CLK_NUM; i++)
>   if (IS_ERR(clk_data->hws[i])) {
> @@ -272,6 +273,10 @@ static const struct sun8i_tcon_top_quirks 
sun8i_r40_tcon_top_quirks = {
>   .has_dsi= true,
>  };
>  
> +static const struct sun8i_tcon_top_quirks sun20i_d1_tcon_top_quirks = {
> + .has_dsi= true,
> +};
> +
>  static const struct sun8i_tcon_top_quirks sun50i_h6_tcon_top_quirks = {
>   /* Nothing special */
>  };
> @@ -282,6 +287,10 @@ const struct of_device_id sun8i_tcon_top_of_table[] = {
>   .compatible = "allwinner,sun8i-r40-tcon-top",
>   .data = _r40_tcon_top_quirks
>   },
> + {
> + .compatible = "allwinner,sun20i-d1-tcon-top",
> + .data = _d1_tcon_top_quirks
> + },
>   {
>   .compatible = "allwinner,sun50i-h6-tcon-top",
>   .data = _h6_tcon_top_quirks
> -- 
> 2.35.1
> 
> 




Re: [PATCH v3 10/14] drm/sun4i: csc: Add support for the new MMIO layout

2022-04-24 Thread Jernej Škrabec
Dne nedelja, 24. april 2022 ob 18:26:28 CEST je Samuel Holland napisal(a):
> D1 changes the MMIO offsets for the CSC blocks in the first mixer. The
> mixers' ccsc property is used as an index into the ccsc_base array. Use
> an enumeration to describe this index, and add the new set of offsets.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej Skrabec

> ---
> 
> (no changes since v2)
> 
> Changes in v2:
>  - Use an enumeration for the ccsc value.
> 
>  drivers/gpu/drm/sun4i/sun8i_csc.c   |  7 ---
>  drivers/gpu/drm/sun4i/sun8i_csc.h   |  1 +
>  drivers/gpu/drm/sun4i/sun8i_mixer.c | 18 +-
>  drivers/gpu/drm/sun4i/sun8i_mixer.h | 14 ++
>  4 files changed, 24 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/
sun8i_csc.c
> index 9bd62de0c288..58480d8e4f70 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> @@ -8,9 +8,10 @@
>  #include "sun8i_csc.h"
>  #include "sun8i_mixer.h"
>  
> -static const u32 ccsc_base[2][2] = {
> - {CCSC00_OFFSET, CCSC01_OFFSET},
> - {CCSC10_OFFSET, CCSC11_OFFSET},
> +static const u32 ccsc_base[][2] = {
> + [CCSC_MIXER0_LAYOUT]= {CCSC00_OFFSET, CCSC01_OFFSET},
> + [CCSC_MIXER1_LAYOUT]= {CCSC10_OFFSET, CCSC11_OFFSET},
> + [CCSC_D1_MIXER0_LAYOUT] = {CCSC00_OFFSET, 
CCSC01_D1_OFFSET},
>  };
>  
>  /*
> diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/
sun8i_csc.h
> index 022cafa6c06c..828b86fd0cab 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_csc.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_csc.h
> @@ -13,6 +13,7 @@ struct sun8i_mixer;
>  /* VI channel CSC units offsets */
>  #define CCSC00_OFFSET 0xAA050
>  #define CCSC01_OFFSET 0xFA050
> +#define CCSC01_D1_OFFSET 0xFA000
>  #define CCSC10_OFFSET 0xA
>  #define CCSC11_OFFSET 0xF
>  
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/
sun8i_mixer.c
> index 6b1711a9a71f..4ce593c99807 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -564,7 +564,7 @@ static int sun8i_mixer_remove(struct platform_device 
*pdev)
>  }
>  
>  static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
> - .ccsc   = 0,
> + .ccsc   = CCSC_MIXER0_LAYOUT,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
>   .ui_num = 3,
> @@ -572,7 +572,7 @@ static const struct sun8i_mixer_cfg 
sun8i_a83t_mixer0_cfg = {
>  };
>  
>  static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
> - .ccsc   = 1,
> + .ccsc   = CCSC_MIXER1_LAYOUT,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
>   .ui_num = 1,
> @@ -580,7 +580,7 @@ static const struct sun8i_mixer_cfg 
sun8i_a83t_mixer1_cfg = {
>  };
>  
>  static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
> - .ccsc   = 0,
> + .ccsc   = CCSC_MIXER0_LAYOUT,
>   .mod_rate   = 43200,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
> @@ -589,7 +589,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg 
= {
>  };
>  
>  static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
> - .ccsc   = 0,
> + .ccsc   = CCSC_MIXER0_LAYOUT,
>   .mod_rate   = 29700,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 2048,
> @@ -598,7 +598,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg 
= {
>  };
>  
>  static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
> - .ccsc   = 1,
> + .ccsc   = CCSC_MIXER1_LAYOUT,
>   .mod_rate   = 29700,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> @@ -611,12 +611,12 @@ static const struct sun8i_mixer_cfg 
sun8i_v3s_mixer_cfg = {
>   .ui_num = 1,
>   .scaler_mask = 0x3,
>   .scanline_yuv = 2048,
> - .ccsc = 0,
> + .ccsc = CCSC_MIXER0_LAYOUT,
>   .mod_rate = 15000,
>  };
>  
>  static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
> - .ccsc   = 0,
> + .ccsc   = CCSC_MIXER0_LAYOUT,
>   .mod_rate   = 29700,
>   .scaler_mask= 0xf,
>   .scanline_yuv   = 4096,
> @@ -625,7 +625,7 @@ static const struct sun8i_mixer_cfg 
sun50i_a64_mixer0_cfg = {
>  };
>  
>  static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
> - .ccsc   = 1,
> + .ccsc   = CCSC_MIXER1_LAYOUT,
>   .mod_rate   = 29700,
>   .scaler_mask= 0x3,
>   .scanline_yuv   = 2048,
> @@ -634,7 +634,7 @@ static const struct sun8i_mixer_cfg 
sun50i_a64_mixer1_cfg = {
>  };
>  
>  static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
> - .ccsc   = 0,
> + .ccsc   = CCSC_MIXER0_LAYOUT,
>   .is_de3 = true,
>   .mod_rate   = 6,
>   .scaler_mask= 0xf,
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h 

Re: [PATCH v3 09/14] drm/sun4i: Allow VI layers to be primary planes

2022-04-24 Thread Jernej Škrabec
Dne nedelja, 24. april 2022 ob 18:26:27 CEST je Samuel Holland napisal(a):
> D1's mixer 1 has no UI layers, only a single VI layer. That means the
> mixer can only be used if the primary plane comes from this VI layer.
> Add the code to handle this case.
> 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej Skrabec

> ---
> 
> (no changes since v2)
> 
> Changes in v2:
>  - Use Jernej's patches for mixer mode setting.
> 
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/
sun8i_vi_layer.c
> index bb7c43036dfa..f7d0b082d634 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> @@ -542,6 +542,7 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct 
drm_device *drm,
>  struct 
sun8i_mixer *mixer,
>  int index)
>  {
> + enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
>   u32 supported_encodings, supported_ranges;
>   unsigned int plane_cnt, format_count;
>   struct sun8i_vi_layer *layer;
> @@ -560,12 +561,15 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct 
drm_device *drm,
>   format_count = ARRAY_SIZE(sun8i_vi_layer_formats);
>   }
>  
> + if (!mixer->cfg->ui_num && index == 0)
> + type = DRM_PLANE_TYPE_PRIMARY;
> +
>   /* possible crtcs are set later */
>   ret = drm_universal_plane_init(drm, >plane, 0,
>  _vi_layer_funcs,
>  formats, format_count,
>  sun8i_layer_modifiers,
> -DRM_PLANE_TYPE_OVERLAY, 
NULL);
> +type, NULL);
>   if (ret) {
>   dev_err(drm->dev, "Couldn't initialize layer\n");
>   return ERR_PTR(ret);
> -- 
> 2.35.1
> 
> 




Re: [PATCH v3 04/14] drm/sun4i: hdmi: Use more portable I/O helpers

2022-04-24 Thread Jernej Škrabec
Dne nedelja, 24. april 2022 ob 18:26:22 CEST je Samuel Holland napisal(a):
> readsb/writesb are unavailable on some architectures. In preparation for
> removing the Kconfig architecture dependency, switch to the equivalent
> but more portable ioread/write8_rep helpers.
> 
> Reported-by: kernel test robot 
> Signed-off-by: Samuel Holland 

Reviewed-by: Jernej Skrabec 

Best regards,
Jernej Skrabec

> ---
> 
> (no changes since v2)
> 
> Changes in v2:
>  - New patch: I/O helper portability
> 
>  drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c b/drivers/gpu/drm/sun4i/
sun4i_hdmi_i2c.c
> index b66fa27fe6ea..c7d7e9fff91c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c
> @@ -56,9 +56,9 @@ static int fifo_transfer(struct sun4i_hdmi *hdmi, u8 *buf, 
int len, bool read)
>   return -EIO;
>  
>   if (read)
> - readsb(hdmi->base + hdmi->variant->ddc_fifo_reg, buf, 
len);
> + ioread8_rep(hdmi->base + hdmi->variant->ddc_fifo_reg, 
buf, len);
>   else
> - writesb(hdmi->base + hdmi->variant->ddc_fifo_reg, buf, 
len);
> + iowrite8_rep(hdmi->base + hdmi->variant->ddc_fifo_reg, 
buf, len);
>  
>   /* Clear FIFO request bit by forcing a write to that bit */
>   regmap_field_force_write(hdmi->field_ddc_int_status,
> -- 
> 2.35.1
> 
> 




Re: [PATCH 10/10] drm/sun4i: Add compatible for D1 display engine

2022-04-11 Thread Jernej Škrabec
Dne ponedeljek, 11. april 2022 ob 06:34:22 CEST je Samuel Holland napisal(a):
> Now that the various blocks in the D1 display engine pipeline are
> supported, we can enable the overall engine.
> 
> Signed-off-by: Samuel Holland 

Acked-by: Jernej Skrabec 

Best regards,
Jernej

> ---
> 
>  drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/
sun4i_drv.c
> index 6a9ba8a77c77..275f7e4a03ae 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -418,6 +418,7 @@ static const struct of_device_id sun4i_drv_of_table[] = 
{
>   { .compatible = "allwinner,sun8i-r40-display-engine" },
>   { .compatible = "allwinner,sun8i-v3s-display-engine" },
>   { .compatible = "allwinner,sun9i-a80-display-engine" },
> + { .compatible = "allwinner,sun20i-d1-display-engine" },
>   { .compatible = "allwinner,sun50i-a64-display-engine" },
>   { .compatible = "allwinner,sun50i-h6-display-engine" },
>   { }
> -- 
> 2.35.1
> 
> 




  1   2   3   4   >