[PATCH] drm/amdgpu: resove reboot exception for si oland

2023-03-09 Thread Zhenneng Li
During reboot test on arm64 platform, it may failure
on boot.

The error message are as follows:
[6.996395][ 7] [  T295] [drm:amdgpu_device_ip_late_init [amdgpu]] *ERROR*
late_init of IP block  failed -22
[7.006919][ 7] [  T295] amdgpu :04:00.0: amdgpu_device_ip_late_init 
failed
[7.014224][ 7] [  T295] amdgpu :04:00.0: Fatal error during GPU init
---
 drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c 
b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
index d6d9e3b1b2c0..dee51c757ac0 100644
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -7632,9 +7632,6 @@ static int si_dpm_late_init(void *handle)
if (!adev->pm.dpm_enabled)
return 0;
 
-   ret = si_set_temperature_range(adev);
-   if (ret)
-   return ret;
 #if 0 //TODO ?
si_dpm_powergate_uvd(adev, true);
 #endif
-- 
2.25.1



[PATCH] drm/amdgpu: resove reboot exception for si oland

2023-03-09 Thread Zhenneng Li
During reboot test on arm64 platform, it may failure
on boot.

The error message are as follows:
[6.996395][ 7] [  T295] [drm:amdgpu_device_ip_late_init [amdgpu]] *ERROR*
late_init of IP block  failed -22
[7.006919][ 7] [  T295] amdgpu :04:00.0: amdgpu_device_ip_late_init 
failed
[7.014224][ 7] [  T295] amdgpu :04:00.0: Fatal error during GPU init
---
 drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c 
b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
index d6d9e3b1b2c0..dee51c757ac0 100644
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -7632,9 +7632,6 @@ static int si_dpm_late_init(void *handle)
if (!adev->pm.dpm_enabled)
return 0;
 
-   ret = si_set_temperature_range(adev);
-   if (ret)
-   return ret;
 #if 0 //TODO ?
si_dpm_powergate_uvd(adev, true);
 #endif
-- 
2.25.1



[PATCH v1] drm/mipi-dsi: Set the fwnode for mipi_dsi_device

2023-03-09 Thread Saravana Kannan
After commit 3fb16866b51d ("driver core: fw_devlink: Make cycle
detection more robust"), fw_devlink prints an error when consumer
devices don't have their fwnode set. This used to be ignored silently.

Set the fwnode mipi_dsi_device so fw_devlink can find them and properly
track their dependencies.

This fixes errors like this:
[0.334054] nwl-dsi 30a0.mipi-dsi: Failed to create device link with 
regulator-lcd-1v8
[0.346964] nwl-dsi 30a0.mipi-dsi: Failed to create device link with 
backlight-dsi

Reported-by: Martin Kepplinger 
Link: 
https://lore.kernel.org/lkml/2a8e407f4f18c9350f8629a2b5fa18673355b2ae.ca...@puri.sm/
Fixes: 068a00233969 ("drm: Add MIPI DSI bus support")
Signed-off-by: Saravana Kannan 
---
 drivers/gpu/drm/drm_mipi_dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index b41aaf2bb9f1..7923cc21b78e 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -221,7 +221,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
return dsi;
}
 
-   dsi->dev.of_node = info->node;
+   device_set_node(>dev, of_fwnode_handle(info->node));
dsi->channel = info->channel;
strlcpy(dsi->name, info->type, sizeof(dsi->name));
 
-- 
2.40.0.rc1.284.g88254d51c5-goog



Re: [PATCH RFC 01/18] rust: drm: ioctl: Add DRM ioctl abstraction

2023-03-09 Thread Asahi Lina
On 10/03/2023 05.39, Karol Herbst wrote:
> On Thu, Mar 9, 2023 at 9:24 PM Faith Ekstrand
>  wrote:
>>
>> On Thu, 2023-03-09 at 15:04 +0900, Asahi Lina wrote:
>>> On 08/03/2023 02.34, Björn Roy Baron wrote:
> +// SAFETY: This is just the ioctl
> argument, which hopefully has the right type
> +// (we've done our best checking the
> size).

 In the rust tree there is the ReadableFromBytes [1] trait which
 indicates that it is safe to read arbitrary bytes into the type.
 Maybe you could add it as bound on the argument type when it lands
 in rust-next? This way you can't end up with for example a struct
 containing a bool with the byte value 2, which is UB.
>>>
>>> There's actually a much bigger story here, because that trait isn't
>>> really very useful without a way to auto-derive it. I need the same
>>> kind
>>> of guarantee for all the GPU firmware structs...
>>>
>>> There's one using only declarative macros [1] and one using proc
>>> macros
>>> [2]. And then, since ioctl arguments are declared in C UAPI header
>>> files, we need a way to be able to derive those traits for them...
>>> which
>>> I guess means bindgen changes?
>>
>> It'd be cool to be able to auto-verify that uAPI structs are all
>> tightly packed and use the right subset of types.  Maybe not possible
>> this iteration but it'd be cool to see in future.  I'd like to see it
>> for C as well, ideally.
>>
>> ~Faith
>>
> 
> I'm sure that with a macro you could verify that a struct definition
> doesn't contain any gaps, just not sure on how one would enforce that.
> Could add a trait which can only be implemented through a proc_macro?
> Maybe we can have a proc_macro ensuring no gaps? Would be cool tech to
> have indeed.

You just make the trait unsafe, as usual, then implement it via that
macro. It's how the things I linked work ^^

The tricky thing with C UAPI definitions is just that we need to get
bindgen to emit those macro instantiations around struct definitions
somehow. Or maybe it could be done with a brute force text-based
postprocessing pass? If we put all UAPI defs into their own crate, you
could probably just do it with sed or a python script or something on
the bindgen output to add it for all struct types...

@Rust folks: Should I try creating a uapi crate for this? I think we can
just mirror the bindings crate logic, and we don't need helpers or
anything like that here, so it shouldn't be very difficult. Then I could
(eventually) eliminate all usage of the full bindings crate in the
driver, and also try experimenting with stuff like this to validate all
UAPI types and implement special traits for them...

~~ Lina


RE: [Intel-gfx] [PATCH v6 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-03-09 Thread Kandpal, Suraj



> -Original Message-
> From: Intel-gfx  On Behalf Of Mark
> Yacoub
> Sent: Thursday, January 19, 2023 1:00 AM
> To: quic_khs...@quicinc.com; linux-arm-...@vger.kernel.org; dri-
> de...@lists.freedesktop.org; freedr...@lists.freedesktop.org;
> devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; intel-
> g...@lists.freedesktop.org
> Cc: quic_sbill...@quicinc.com; konrad.dyb...@somainline.org;
> bjorn.anders...@linaro.org; krzysztof.kozlowski...@linaro.org;
> airl...@gmail.com; hbh...@gmail.com; Vasut, Marek ;
> abhin...@codeaurora.org; javi...@redhat.com; agr...@kernel.org;
> quic_jessz...@quicinc.com; dan...@ffwll.ch; Nikula, Jani
> ; De Marchi, Lucas ;
> quic_abhin...@quicinc.com; swb...@chromium.org; robh...@kernel.org;
> christophe.jail...@wanadoo.fr; max...@cerno.tech; Vivi, Rodrigo
> ; johan+lin...@kernel.org;
> markyac...@chromium.org; anders...@kernel.org;
> diand...@chromium.org; tzimmerm...@suse.de;
> dmitry.barysh...@linaro.org; seanp...@chromium.org
> Subject: [Intel-gfx] [PATCH v6 02/10] drm/hdcp: Avoid changing crtc state in
> hdcp atomic check
> 
> From: Sean Paul 
> 
> Instead of forcing a modeset in the hdcp atomic check, simply return true if
> the content protection value is changing and let the driver decide whether a
> modeset is required or not.
> 
> Acked-by: Jani Nikula 
> Reviewed-by: Rodrigo Vivi 
> Signed-off-by: Sean Paul 
> Signed-off-by: Mark Yacoub 
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-3-
> s...@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-3-
> s...@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-3-
> s...@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-
> 3-s...@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-
> 3-s...@poorly.run #v5
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in V6:
> -Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
> 
> ---
>  drivers/gpu/drm/display/drm_hdcp_helper.c   | 33 +++--
>  drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
>  include/drm/display/drm_hdcp_helper.h   |  2 +-
>  3 files changed, 27 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c
> b/drivers/gpu/drm/display/drm_hdcp_helper.c
> index 7d910523b05f..a3896b0904b5 100644
> --- a/drivers/gpu/drm/display/drm_hdcp_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
> @@ -428,11 +428,14 @@
> EXPORT_SYMBOL(drm_hdcp_update_content_protection);
>   * @connector: drm_connector on which content protection state needs an
> update
>   *
>   * This function can be used by display drivers to perform an atomic check
> on the
> - * hdcp state elements. If hdcp state has changed, this function will set
> - * mode_changed on the crtc driving the connector so it can update its
> hardware
> - * to match the hdcp state.
> + * hdcp state elements. If hdcp state has changed in a manner which
> + requires the
> + * driver to enable or disable content protection, this function will
> + return
> + * true.
> + *
> + * Returns:
> + * true if the driver must enable/disable hdcp, false otherwise
>   */
> -void drm_hdcp_atomic_check(struct drm_connector *connector,
> +bool drm_hdcp_atomic_check(struct drm_connector *connector,
>  struct drm_atomic_state *state)
>  {
>   struct drm_connector_state *new_conn_state, *old_conn_state;
> @@ -450,10 +453,12 @@ void drm_hdcp_atomic_check(struct
> drm_connector *connector,
>* If the connector is being disabled with CP enabled, mark it
>* desired so it's re-enabled when the connector is brought
> back
>*/
> - if (old_hdcp ==
> DRM_MODE_CONTENT_PROTECTION_ENABLED)
> + if (old_hdcp ==
> DRM_MODE_CONTENT_PROTECTION_ENABLED) {
>   new_conn_state->content_protection =
> 
>   DRM_MODE_CONTENT_PROTECTION_DESIRED;
> - return;
> + return true;
> + }
> + return false;
>   }
> 
>   new_crtc_state =
> @@ -465,9 +470,19 @@ void drm_hdcp_atomic_check(struct
> drm_connector *connector,
>   */
>   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
>   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> -  new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
> +  new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
> {
>   new_conn_state->content_protection =
>   DRM_MODE_CONTENT_PROTECTION_DESIRED;
> + return true;
> + }
> +
> + /*
> +  * Coming back from disable or changing CRTC with DESIRED state
> requires
> +  * that the driver try CP enable.
> +  */

Hi ,
We can have a clearer comment which says something like "Coming 

RE: [Intel-gfx] [PATCH v6 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-03-09 Thread Kandpal, Suraj
> 
> From: Sean Paul 
> 
> This patch moves the hdcp atomic check from i915 to drm_hdcp so other
> drivers can use it. No functional changes, just cleaned up some of the code
> when moving it over.
> 
> Acked-by: Jani Nikula 
> Acked-by: Jani Nikula 
> Reviewed-by: Rodrigo Vivi 
> Reviewed-by: Abhinav Kumar 
> Signed-off-by: Sean Paul 
> Signed-off-by: Mark Yacoub 
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-2-
> s...@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-2-
> s...@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-2-
> s...@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-
> 2-s...@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-
> 2-s...@poorly.run #v5
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in V6:
> -Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
> 
> ---
>  drivers/gpu/drm/display/drm_hdcp_helper.c   | 69
> +
>  drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
>  drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 --
>  drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
>  include/drm/display/drm_hdcp_helper.h   |  3 +
>  5 files changed, 74 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c
> b/drivers/gpu/drm/display/drm_hdcp_helper.c
> index e78999c72bd7..7d910523b05f 100644
> --- a/drivers/gpu/drm/display/drm_hdcp_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
> 
>  static inline void drm_hdcp_print_ksv(const u8 *ksv)  { @@ -419,3 +420,71
> @@ void drm_hdcp_update_content_protection(struct drm_connector
> *connector,
>dev-
> >mode_config.content_protection_property);
>  }
>  EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> +
> +/**
> + * drm_hdcp_atomic_check - Helper for drivers to call during
> +connector->atomic_check
> + *
> + * @state: pointer to the atomic state being checked
> + * @connector: drm_connector on which content protection state needs an
> +update
> + *
> + * This function can be used by display drivers to perform an atomic
> +check on the
> + * hdcp state elements. If hdcp state has changed, this function will
> +set
> + * mode_changed on the crtc driving the connector so it can update its
> +hardware
> + * to match the hdcp state.
> + */
> +void drm_hdcp_atomic_check(struct drm_connector *connector,
> +struct drm_atomic_state *state)
> +{
> + struct drm_connector_state *new_conn_state, *old_conn_state;
> + struct drm_crtc_state *new_crtc_state;
> + u64 old_hdcp, new_hdcp;
> +
> + old_conn_state = drm_atomic_get_old_connector_state(state,
> connector);
> + old_hdcp = old_conn_state->content_protection;
> +
> + new_conn_state = drm_atomic_get_new_connector_state(state,
> connector);
> + new_hdcp = new_conn_state->content_protection;
> +
> + if (!new_conn_state->crtc) {
> + /*
> +  * If the connector is being disabled with CP enabled, mark it
> +  * desired so it's re-enabled when the connector is brought
> back
> +  */
> + if (old_hdcp ==
> DRM_MODE_CONTENT_PROTECTION_ENABLED)
> + new_conn_state->content_protection =
> +
>   DRM_MODE_CONTENT_PROTECTION_DESIRED;
> + return;
> + }
> +
> + new_crtc_state =
> + drm_atomic_get_new_crtc_state(state, new_conn_state-
> >crtc);
> + /*
> + * Fix the HDCP uapi content protection state in case of modeset.
> + * FIXME: As per HDCP content protection property uapi doc, an
> uevent()
> + * need to be sent if there is transition from ENABLED->DESIRED.
> + */

Hi Mark,
Is the above comment needed here as drm_hdcp_update_content_protection is
used to change property which sends a uevent making the above comment misleading

Regards,
Suraj Kandpal
> + if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
> + (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> +  new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
> + new_conn_state->content_protection =
> + DRM_MODE_CONTENT_PROTECTION_DESIRED;
> +
> + /*
> +  * Nothing to do if content type is unchanged and one of:
> +  *  - state didn't change
> +  *  - HDCP was activated since the last commit
> +  *  - attempting to set to desired while already enabled
> +  */
> + if (old_hdcp == new_hdcp ||
> + (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> +  new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
> + (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> +  new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) 

[git pull] drm fixes for 6.3-rc2

2023-03-09 Thread Dave Airlie
Hi Linus,

Weekly fixes, msm and amdgpu are the vast majority of these, otherwise
some straggler misc from last week for nouveau and cirrus and a
mailmap update for a drm developer.

Regards,
Dave.

drm-fixes-2023-03-10:
drm fixes for 6.3-rc2

mailmap
- add an entry

nouveau:
- fix system shutdown regression
- build warning fix

cirrus:
- NULL ptr deref fix

msm:
- fix invalid ptr free in syncobj cleanup
- sync GMU removal in teardown
- a5xx preemption fixes
- fix runpm imbalance
- DPU hw fixes
- stack corruption fix
- clear DSPP reservation

amdgpu:
- Misc display fixes
- UMC 8.10 fixes
- Driver unload fixes
- NBIO 7.3.0 fix
- Error checking fixes for soc15, nv, soc21 read register interface
- Fix video cap query for VCN 4.0.4

amdkfd:
- Fix return check in doorbell handling
The following changes since commit fe15c26ee26efa11741a7b632e9f23b01aca4cc6:

  Linux 6.3-rc1 (2023-03-05 14:52:03 -0800)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2023-03-10

for you to fetch changes up to 519b23310aa100073f0b58c39df120a486ed7f8e:

  Merge tag 'amd-drm-fixes-6.3-2023-03-09' of
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes (2023-03-10
14:17:35 +1000)


drm fixes for 6.3-rc2

mailmap
- add an entry

nouveau:
- fix system shutdown regression
- build warning fix

cirrus:
- NULL ptr deref fix

msm:
- fix invalid ptr free in syncobj cleanup
- sync GMU removal in teardown
- a5xx preemption fixes
- fix runpm imbalance
- DPU hw fixes
- stack corruption fix
- clear DSPP reservation

amdgpu:
- Misc display fixes
- UMC 8.10 fixes
- Driver unload fixes
- NBIO 7.3.0 fix
- Error checking fixes for soc15, nv, soc21 read register interface
- Fix video cap query for VCN 4.0.4

amdkfd:
- Fix return check in doorbell handling


Alex Deucher (3):
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc21
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for nv

Alexandr Sapozhnikov (1):
  drm/cirrus: NULL-check pipe->plane.state->fb in cirrus_pipe_update()

Ben Skeggs (1):
  drm/nouveau/fb/gp102-: cache scrubber binary on first load

Candice Li (2):
  drm/amdgpu: Support umc node harvest config on umc v8_10
  drm/amd/pm: Enable ecc_info table support for smu v13_0_10

Dave Airlie (4):
  Merge tag 'drm-misc-fixes-2023-02-23' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
  mailmap: add mailmap entries for Faith.
  Merge tag 'drm-msm-fixes-2023-03-09' of
https://gitlab.freedesktop.org/drm/msm into drm-fixes
  Merge tag 'amd-drm-fixes-6.3-2023-03-09' of
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes

Dmitry Baryshkov (18):
  drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register
  drm/msm/a5xx: fix highest bank bit for a530
  drm/msm/a5xx: fix the emptyness check in the preempt code
  drm/msm/a5xx: fix context faults during ring switch
  drm/msm/dpu: set DPU_MDP_PERIPH_0_REMOVED for sc8280xp
  drm/msm/dpu: disable features unsupported by QCM2290
  drm/msm/dpu: fix typo in in sm8550's dma_sblk_5
  drm/msm/dpu: fix len of sc7180 ctl blocks
  drm/msm/dpu: fix sm6115 and qcm2290 mixer width limits
  drm/msm/dpu: correct sm8550 scaler
  drm/msm/dpu: correct sc8280xp scaler
  drm/msm/dpu: correct sm8450 scaler
  drm/msm/dpu: correct sm8250 and sm8350 scaler
  drm/msm/dpu: correct sm6115 scaler
  drm/msm/dpu: drop DPU_DIM_LAYER from MIXER_MSM8998_MASK
  drm/msm/dpu: fix clocks settings for msm8998 SSPP blocks
  drm/msm/dpu: don't use DPU_CLK_CTRL_CURSORn for DMA SSPP clocks
  drm/msm/dpu: fix stack smashing in dpu_hw_ctl_setup_blendstage

Douglas Anderson (1):
  drm/msm/a6xx: Make GPU destroy a bit safer

Harry Wentland (2):
  drm/display: Don't block HDR_OUTPUT_METADATA on unknown EOTF
  drm/connector: print max_requested_bpc in state debugfs

Jiri Slaby (SUSE) (1):
  drm/nouveau/kms/nv50: fix nv50_wndw_new_ prototype

Johan Hovold (1):
  drm/msm/adreno: fix runtime PM imbalance at unbind

Kalyan Thota (1):
  drm/msm/dpu: clear DSPP reservations in rm release

Kuogee Hsieh (1):
  drm/msm/disp/dpu: fix sc7280_pp base offset

Mario Limonciello (1):
  drm/amd: Fix initialization mistake for NBIO 7.3.0

Randy Dunlap (1):
  drm/msm: DEVFREQ_GOV_SIMPLE_ONDEMAND is no longer needed

Rob Clark (2):
  Merge tag 'drm-msm-fixes-2023-01-16' into msm-fixes
  drm/msm: Fix potential invalid ptr free

Shashank Sharma (1):
  drm/amdgpu: fix return value check in kfd

Swapnil Patel (1):
  drm/amd/display: Update clock table to include highest clock setting

Thomas Zimmermann (1):
  drm/msm: Fix possible uninitialized access in fbdev

Veerabadhran Gopalakrishnan (1):
  

[PATCH] drm/bridge: Fix returned array size name for atomic_get_input_bus_fmts kdoc

2023-03-09 Thread Liu Ying
The returned array size for input formats is set through
atomic_get_input_bus_fmts()'s 'num_input_fmts' argument, so use
'num_input_fmts' to represent the array size in the function's kdoc,
not 'num_output_fmts'.

Fixes: ("91ea83306bfa drm/bridge: Fix the bridge kernel doc")
Fixes: ("f32df58acc68 drm/bridge: Add the necessary bits to support bus format 
negotiation")
Signed-off-by: Liu Ying 
---
 include/drm/drm_bridge.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 6b65b0dfb4fb..288c6feda5de 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -447,11 +447,11 @@ struct drm_bridge_funcs {
 *
 * The returned array must be allocated with kmalloc() and will be
 * freed by the caller. If the allocation fails, NULL should be
-* returned. num_output_fmts must be set to the returned array size.
+* returned. num_input_fmts must be set to the returned array size.
 * Formats listed in the returned array should be listed in decreasing
 * preference order (the core will try all formats until it finds one
 * that works). When the format is not supported NULL should be
-* returned and num_output_fmts should be set to 0.
+* returned and num_input_fmts should be set to 0.
 *
 * This method is called on all elements of the bridge chain as part of
 * the bus format negotiation process that happens in
-- 
2.37.1



[pull] amdgpu, amdkfd drm-fixes-6.3

2023-03-09 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 6.3.  Same pull as yesterday, but drop the KFD patch that
caused a regression.

The following changes since commit 66305069eb6d17d9190cbcd196f3f7487df47ae8:

  Merge tag 'drm-misc-fixes-2023-02-23' of 
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2023-03-07 05:42:34 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-6.3-2023-03-09

for you to fetch changes up to 6ce2ea07c5ff0a8188eab0e5cd1f0e4899b36835:

  drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4 (2023-03-09 
22:06:19 -0500)


amd-drm-fixes-6.3-2023-03-09:

amdgpu:
- Misc display fixes
- UMC 8.10 fixes
- Driver unload fixes
- NBIO 7.3.0 fix
- Error checking fixes for soc15, nv, soc21 read register interface
- Fix video cap query for VCN 4.0.4

amdkfd:
- Fix return check in doorbell handling


Alex Deucher (3):
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc21
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for nv

Candice Li (2):
  drm/amdgpu: Support umc node harvest config on umc v8_10
  drm/amd/pm: Enable ecc_info table support for smu v13_0_10

Harry Wentland (2):
  drm/display: Don't block HDR_OUTPUT_METADATA on unknown EOTF
  drm/connector: print max_requested_bpc in state debugfs

Mario Limonciello (1):
  drm/amd: Fix initialization mistake for NBIO 7.3.0

Shashank Sharma (1):
  drm/amdgpu: fix return value check in kfd

Swapnil Patel (1):
  drm/amd/display: Update clock table to include highest clock setting

Veerabadhran Gopalakrishnan (1):
  drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4

lyndonli (2):
  drm/amdgpu: Fix call trace warning and hang when removing amdgpu device
  drm/amdgpu: Fix the warning info when removing amdgpu device

 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c  | 10 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 17 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h|  7 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c |  1 -
 drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 14 ++--
 drivers/gpu/drm/amd/amdgpu/nv.c|  7 +-
 drivers/gpu/drm/amd/amdgpu/soc15.c |  5 +-
 drivers/gpu/drm/amd/amdgpu/soc21.c |  8 ++-
 drivers/gpu/drm/amd/amdgpu/umc_v8_10.h |  4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c  |  2 +-
 .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 19 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   | 75 ++
 drivers/gpu/drm/display/drm_hdmi_helper.c  |  6 +-
 drivers/gpu/drm/drm_atomic.c   |  1 +
 15 files changed, 136 insertions(+), 42 deletions(-)


RE: [PATCH v3 2/2] drm/probe_helper: warning on poll_enabled for issue catching

2023-03-09 Thread Quan, Evan
[AMD Official Use Only - General]

Series is acked-by: Evan Quan 

> -Original Message-
> From: amd-gfx  On Behalf Of
> Guchun Chen
> Sent: Friday, March 10, 2023 9:02 AM
> To: amd-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org;
> Deucher, Alexander ; Zhang, Hawking
> ; dmitry.barysh...@linaro.org;
> spassw...@web.de; m...@fireburn.co.uk
> Cc: Chen, Guchun 
> Subject: [PATCH v3 2/2] drm/probe_helper: warning on poll_enabled for
> issue catching
> 
> In order to catch issues in other drivers to ensure proper call sequence of
> polling function.
> 
> v2: drop Fixes tag in commit message
> 
> Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2411
> Reported-by: Bert Karwatzki 
> Suggested-by: Dmitry Baryshkov 
> Signed-off-by: Guchun Chen 
> ---
>  drivers/gpu/drm/drm_probe_helper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c
> b/drivers/gpu/drm/drm_probe_helper.c
> index 8127be134c39..85e0e80d4a52 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -852,6 +852,8 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
>   */
>  void drm_kms_helper_poll_disable(struct drm_device *dev)  {
> + WARN_ON(!dev->mode_config.poll_enabled);
> +
>   if (dev->mode_config.poll_running)
>   drm_kms_helper_disable_hpd(dev);
> 
> --
> 2.25.1


Re: [PATCH 1/2] drm/i915/pmu: Use functions common with sysfs to read actual freq

2023-03-09 Thread Dixit, Ashutosh
On Thu, 09 Mar 2023 01:20:09 -0800, Tvrtko Ursulin wrote:
>

Hi Tvrtko,

> On 09/03/2023 03:46, Ashutosh Dixit wrote:
> > Expose intel_rps_read_actual_frequency_fw to read the actual freq without
> > taking forcewake for use by PMU. The code is refactored to use a common set
> > of functions across sysfs and PMU. Using common functions with sysfs in PMU
> > solves the issues of missing support for MTL and missing support for older
> > generations (prior to Gen6). It also future proofs the PMU where sometimes
> > code has been updated for sysfs and PMU has been missed.
> >
> > Fixes: 22009b6dad66 ("drm/i915/mtl: Modify CAGF functions for MTL")
>
> So not DG1 and above?

The issue for DG1+ happens if non-freq bits are non-zero but freq bits are
zero. But we've already seen that during PMU freq sampling gt is unparked
so freq bits being 0 is rare. Therefore IMO there is 0 practical impact of
that bug, I don't think it's worth fixing it and Cc'ing stable etc. (also
those platforms are under force probe).

> > Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8280
> > Signed-off-by: Ashutosh Dixit 
> > ---
> >   drivers/gpu/drm/i915/gt/intel_rps.c | 46 +++--
> >   drivers/gpu/drm/i915/gt/intel_rps.h |  2 +-
> >   drivers/gpu/drm/i915/i915_pmu.c | 10 +++
> >   3 files changed, 36 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c 
> > b/drivers/gpu/drm/i915/gt/intel_rps.c
> > index 4d0dc9de23f9..3957c5ee5cba 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_rps.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_rps.c
> > @@ -2046,16 +2046,6 @@ void intel_rps_sanitize(struct intel_rps *rps)
> > rps_disable_interrupts(rps);
> >   }
> >   -u32 intel_rps_read_rpstat_fw(struct intel_rps *rps)
> > -{
> > -   struct drm_i915_private *i915 = rps_to_i915(rps);
> > -   i915_reg_t rpstat;
> > -
> > -   rpstat = (GRAPHICS_VER(i915) >= 12) ? GEN12_RPSTAT1 : GEN6_RPSTAT1;
> > -
> > -   return intel_uncore_read_fw(rps_to_gt(rps)->uncore, rpstat);
> > -}
> > -
> >   u32 intel_rps_read_rpstat(struct intel_rps *rps)
> >   {
> > struct drm_i915_private *i915 = rps_to_i915(rps);
> > @@ -2089,10 +2079,11 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 
> > rpstat)
> > return cagf;
> >   }
> >   -static u32 read_cagf(struct intel_rps *rps)
> > +static u32 __read_cagf(struct intel_rps *rps, bool take_fw)
> >   {
> > struct drm_i915_private *i915 = rps_to_i915(rps);
> > struct intel_uncore *uncore = rps_to_uncore(rps);
> > +   i915_reg_t r = INVALID_MMIO_REG;
> > u32 freq;
> > /*
> > @@ -2100,22 +2091,30 @@ static u32 read_cagf(struct intel_rps *rps)
> >  * registers will return 0 freq when GT is in RC6
> >  */
> > if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) {
> > -   freq = intel_uncore_read(uncore, MTL_MIRROR_TARGET_WP1);
> > +   r = MTL_MIRROR_TARGET_WP1;
> > } else if (GRAPHICS_VER(i915) >= 12) {
> > -   freq = intel_uncore_read(uncore, GEN12_RPSTAT1);
> > +   r = GEN12_RPSTAT1;
> > } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
> > vlv_punit_get(i915);
> > freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
> > vlv_punit_put(i915);
> > +   goto exit;
> > } else if (GRAPHICS_VER(i915) >= 6) {
> > -   freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
> > +   r = GEN6_RPSTAT1;
> > } else {
> > -   freq = intel_uncore_read(uncore, MEMSTAT_ILK);
> > +   r = MEMSTAT_ILK;
> > }
> >   + freq = take_fw ? intel_uncore_read(uncore, r) :
> > intel_uncore_read_fw(uncore, r);
> > +exit:
> > return intel_rps_get_cagf(rps, freq);
> >   }
> >   +static u32 read_cagf(struct intel_rps *rps)
> > +{
> > +   return __read_cagf(rps, true);
> > +}
> > +
> >   u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
> >   {
> > struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
> > @@ -2128,6 +2127,23 @@ u32 intel_rps_read_actual_frequency(struct intel_rps 
> > *rps)
> > return freq;
> >   }
> >   +static u32 read_cagf_fw(struct intel_rps *rps)
> > +{
> > +   return __read_cagf(rps, false);
> > +}
> > +
> > +u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps)
> > +{
> > +   struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
> > +   intel_wakeref_t wakeref;
> > +   u32 freq = 0;
> > +
> > +   with_intel_runtime_pm_if_in_use(rpm, wakeref)
>
> When called from i915_pmu.c::frequency sample() above seems redundant since
> there we already are under intel_gt_pm_get_if_awake. Perhaps it is not a
> huge deal but it is nevertheless wasteful.
>
> Also, maybe I am a bit rusty, but more fundamentally, wouldn't this be
> adding a _very_ atypical pattern of a _fw function which grabs rpm? I'd
> expect they all assume it's already held since the forcewake is already
> held.
>
> Am I missing the reason why it is needed?

Thanks for catching this, you are right, it was just 

[PATCH v3 2/2] drm/probe_helper: warning on poll_enabled for issue catching

2023-03-09 Thread Guchun Chen
In order to catch issues in other drivers to ensure proper call
sequence of polling function.

v2: drop Fixes tag in commit message

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2411
Reported-by: Bert Karwatzki 
Suggested-by: Dmitry Baryshkov 
Signed-off-by: Guchun Chen 
---
 drivers/gpu/drm/drm_probe_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 8127be134c39..85e0e80d4a52 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -852,6 +852,8 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
  */
 void drm_kms_helper_poll_disable(struct drm_device *dev)
 {
+   WARN_ON(!dev->mode_config.poll_enabled);
+
if (dev->mode_config.poll_running)
drm_kms_helper_disable_hpd(dev);
 
-- 
2.25.1



[PATCH v3 1/2] drm/amdgpu: move poll enabled/disable into non DC path

2023-03-09 Thread Guchun Chen
Some amd asics having reliable hotplug support don't call
drm_kms_helper_poll_init in driver init sequence. However,
due to the unified suspend/resume path for all asics, because
the output_poll_work->func is not set for these asics, a warning
arrives when suspending.

[   90.656049]  
[   90.656050]  ? console_unlock+0x4d/0x100
[   90.656053]  ? __irq_work_queue_local+0x27/0x60
[   90.656056]  ? irq_work_queue+0x2b/0x50
[   90.656057]  ? __wake_up_klogd+0x40/0x60
[   90.656059]  __cancel_work_timer+0xed/0x180
[   90.656061]  drm_kms_helper_poll_disable.cold+0x1f/0x2c [drm_kms_helper]
[   90.656072]  amdgpu_device_suspend+0x81/0x170 [amdgpu]
[   90.656180]  amdgpu_pmops_runtime_suspend+0xb5/0x1b0 [amdgpu]
[   90.656269]  pci_pm_runtime_suspend+0x61/0x1b0

drm_kms_helper_poll_enable/disable is valid when poll_init is called in
amdgpu code, which is only used in non DC path. So move such codes into
non-DC path code to get rid of such warnings.

v1: introduce use_kms_poll flag in amdgpu as the poll stuff check
v2: use dc_enabled as the flag to simply code
v3: move code into non DC path instead of relying on any flag

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2411
Fixes: a4e771729a51("drm/probe_helper: sort out poll_running vs poll_enabled")
Reported-by: Bert Karwatzki 
Suggested-by: Dmitry Baryshkov 
Suggested-by: Alex Deucher 
Signed-off-by: Guchun Chen 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c  | 4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index c4a4e2fe6681..da5b0258a237 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4145,8 +4145,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
fbcon)
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3))
DRM_WARN("smart shift update failed\n");
 
-   drm_kms_helper_poll_disable(dev);
-
if (fbcon)

drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
 
@@ -4243,8 +4241,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool 
fbcon)
if (fbcon)

drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
 
-   drm_kms_helper_poll_enable(dev);
-
amdgpu_ras_resume(adev);
 
if (adev->mode_info.num_crtc) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 503f89a766c3..d60fe7eb5579 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1618,6 +1618,8 @@ int amdgpu_display_suspend_helper(struct amdgpu_device 
*adev)
struct drm_connector_list_iter iter;
int r;
 
+   drm_kms_helper_poll_disable(dev);
+
/* turn off display hw */
drm_modeset_lock_all(dev);
drm_connector_list_iter_begin(dev, );
@@ -1694,6 +1696,8 @@ int amdgpu_display_resume_helper(struct amdgpu_device 
*adev)
 
drm_modeset_unlock_all(dev);
 
+   drm_kms_helper_poll_enable(dev);
+
return 0;
 }
 
-- 
2.25.1



[PATCH 2/2] drm/i915/pmu: Remove fallback to requested freq for SLPC

2023-03-09 Thread Ashutosh Dixit
The fallback to requested freq does not work for SLPC because SLPC does not
use 'struct intel_rps'. Also for SLPC requested freq can only be obtained
from a hw register after acquiring forcewake which we don't want to do for
PMU. Therefore remove fallback to requested freq for SLPC. The actual freq
will be 0 when gt is in RC6 which is correct. Also this is rare since PMU
freq sampling happens only when gt is unparked.

Signed-off-by: Ashutosh Dixit 
---
 drivers/gpu/drm/i915/i915_pmu.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 7ece883a7d95..f697fabed64a 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -393,7 +393,14 @@ frequency_sample(struct intel_gt *gt, unsigned int 
period_ns)
 * frequency. Fortunately, the read should rarely fail!
 */
val = intel_rps_read_actual_frequency_fw(rps);
-   if (!val)
+
+   /*
+* SLPC does not use 'struct intel_rps'. Also for SLPC
+* requested freq can only be obtained after acquiring
+* forcewake and reading a hw register. For SLPC just
+* let val be 0
+*/
+   if (!val && !intel_uc_uses_guc_slpc(>uc))
val = intel_gpu_freq(rps, rps->cur_freq);
 
add_sample_mult(>sample[__I915_SAMPLE_FREQ_ACT],
-- 
2.38.0



[PATCH 1/2] drm/i915/pmu: Use functions common with sysfs to read actual freq

2023-03-09 Thread Ashutosh Dixit
Expose intel_rps_read_actual_frequency_fw to read the actual freq without
taking forcewake for use by PMU. The code is refactored to use a common set
of functions across sysfs and PMU. Using common functions with sysfs in PMU
solves the issues of missing support for MTL and missing support for older
generations (prior to Gen6). It also future proofs the PMU where sometimes
code has been updated for sysfs and PMU has been missed.

v2: Remove runtime_pm_if_in_use from read_actual_frequency_fw (Tvrtko)

Fixes: 22009b6dad66 ("drm/i915/mtl: Modify CAGF functions for MTL")
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8280
Signed-off-by: Ashutosh Dixit 
---
 drivers/gpu/drm/i915/gt/intel_rps.c | 34 -
 drivers/gpu/drm/i915/gt/intel_rps.h |  2 +-
 drivers/gpu/drm/i915/i915_pmu.c | 10 -
 3 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c 
b/drivers/gpu/drm/i915/gt/intel_rps.c
index 4d0dc9de23f9..9d9ac35691fc 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -2046,16 +2046,6 @@ void intel_rps_sanitize(struct intel_rps *rps)
rps_disable_interrupts(rps);
 }
 
-u32 intel_rps_read_rpstat_fw(struct intel_rps *rps)
-{
-   struct drm_i915_private *i915 = rps_to_i915(rps);
-   i915_reg_t rpstat;
-
-   rpstat = (GRAPHICS_VER(i915) >= 12) ? GEN12_RPSTAT1 : GEN6_RPSTAT1;
-
-   return intel_uncore_read_fw(rps_to_gt(rps)->uncore, rpstat);
-}
-
 u32 intel_rps_read_rpstat(struct intel_rps *rps)
 {
struct drm_i915_private *i915 = rps_to_i915(rps);
@@ -2089,10 +2079,11 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 
rpstat)
return cagf;
 }
 
-static u32 read_cagf(struct intel_rps *rps)
+static u32 __read_cagf(struct intel_rps *rps, bool take_fw)
 {
struct drm_i915_private *i915 = rps_to_i915(rps);
struct intel_uncore *uncore = rps_to_uncore(rps);
+   i915_reg_t r = INVALID_MMIO_REG;
u32 freq;
 
/*
@@ -2100,22 +2091,30 @@ static u32 read_cagf(struct intel_rps *rps)
 * registers will return 0 freq when GT is in RC6
 */
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) {
-   freq = intel_uncore_read(uncore, MTL_MIRROR_TARGET_WP1);
+   r = MTL_MIRROR_TARGET_WP1;
} else if (GRAPHICS_VER(i915) >= 12) {
-   freq = intel_uncore_read(uncore, GEN12_RPSTAT1);
+   r = GEN12_RPSTAT1;
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
vlv_punit_get(i915);
freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
vlv_punit_put(i915);
+   goto exit;
} else if (GRAPHICS_VER(i915) >= 6) {
-   freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
+   r = GEN6_RPSTAT1;
} else {
-   freq = intel_uncore_read(uncore, MEMSTAT_ILK);
+   r = MEMSTAT_ILK;
}
 
+   freq = take_fw ? intel_uncore_read(uncore, r) : 
intel_uncore_read_fw(uncore, r);
+exit:
return intel_rps_get_cagf(rps, freq);
 }
 
+static u32 read_cagf(struct intel_rps *rps)
+{
+   return __read_cagf(rps, true);
+}
+
 u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
 {
struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
@@ -2128,6 +2127,11 @@ u32 intel_rps_read_actual_frequency(struct intel_rps 
*rps)
return freq;
 }
 
+u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps)
+{
+   return intel_gpu_freq(rps, __read_cagf(rps, false));
+}
+
 u32 intel_rps_read_punit_req(struct intel_rps *rps)
 {
struct intel_uncore *uncore = rps_to_uncore(rps);
diff --git a/drivers/gpu/drm/i915/gt/intel_rps.h 
b/drivers/gpu/drm/i915/gt/intel_rps.h
index c622962c6bef..2d5b3ef58606 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.h
+++ b/drivers/gpu/drm/i915/gt/intel_rps.h
@@ -39,6 +39,7 @@ int intel_gpu_freq(struct intel_rps *rps, int val);
 int intel_freq_opcode(struct intel_rps *rps, int val);
 u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat1);
 u32 intel_rps_read_actual_frequency(struct intel_rps *rps);
+u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps);
 u32 intel_rps_get_requested_frequency(struct intel_rps *rps);
 u32 intel_rps_get_min_frequency(struct intel_rps *rps);
 u32 intel_rps_get_min_raw_freq(struct intel_rps *rps);
@@ -52,7 +53,6 @@ u32 intel_rps_get_rpn_frequency(struct intel_rps *rps);
 u32 intel_rps_read_punit_req(struct intel_rps *rps);
 u32 intel_rps_read_punit_req_frequency(struct intel_rps *rps);
 u32 intel_rps_read_rpstat(struct intel_rps *rps);
-u32 intel_rps_read_rpstat_fw(struct intel_rps *rps);
 void gen6_rps_get_freq_caps(struct intel_rps *rps, struct intel_rps_freq_caps 
*caps);
 void intel_rps_raise_unslice(struct intel_rps *rps);
 void intel_rps_lower_unslice(struct intel_rps *rps);
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c

[PATCH 0/2] drm/i915/pmu: Use common freq functions with sysfs

2023-03-09 Thread Ashutosh Dixit
Expose intel_rps_read_actual_frequency_fw to read the actual freq without
taking forcewake for use by PMU. The code is refactored to use a common set
of functions across sysfs and PMU. Using common functions with sysfs in PMU
solves the issues of missing support for MTL and missing support for older
generations (prior to Gen6). It also future proofs the PMU where sometimes
code has been updated for sysfs and PMU has been missed.

Ashutosh Dixit (2):
  drm/i915/pmu: Use functions common with sysfs to read actual freq
  drm/i915/pmu: Remove fallback to requested freq for SLPC

 drivers/gpu/drm/i915/gt/intel_rps.c | 34 -
 drivers/gpu/drm/i915/gt/intel_rps.h |  2 +-
 drivers/gpu/drm/i915/i915_pmu.c | 17 ++-
 3 files changed, 31 insertions(+), 22 deletions(-)

-- 
2.38.0



[PATCH v5 18/32] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format

2023-03-09 Thread Dmitry Baryshkov
Rewrite dpu_plane's QoS related functions to take struct dpu_sw_pipe and
struct dpu_format as arguments rather than fetching them from the
pstate or drm_framebuffer.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 98 +++
 1 file changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3fba63fbbd78..aaea7c63d944 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -128,19 +128,18 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
  * @plane: Pointer to drm plane.
- * @fb:   Pointer to framebuffer associated with the given plane
+ * @fmt: Pointer to source buffer format
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
-   struct drm_framebuffer *fb,
+   const struct dpu_format *fmt,
struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
-   const struct dpu_format *fmt = NULL;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
@@ -152,8 +151,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
pstate = to_dpu_plane_state(plane->state);
mode = >state->crtc->mode;
 
-   fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
-
src_width = drm_rect_width(_cfg->src_rect);
src_height = drm_rect_height(_cfg->src_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
@@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, 
struct dpu_sw_pipe_cfg
 /**
  * _dpu_plane_calc_fill_level - calculate fill level of the given source format
  * @plane: Pointer to drm plane
+ * @pipe:  Pointer to software pipe
  * @fmt:   Pointer to source buffer format
  * @src_width: width of source buffer
  * Return: fill level corresponding to the source buffer/format or 0 if error
  */
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
+   struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, u32 src_width)
 {
struct dpu_plane *pdpu;
-   struct dpu_plane_state *pstate;
u32 fixed_buff_size;
u32 total_fl;
 
-   if (!fmt || !plane->state || !src_width || !fmt->bpp) {
+   if (!fmt || !pipe || !src_width || !fmt->bpp) {
DPU_ERROR("invalid arguments\n");
return 0;
}
 
pdpu = to_dpu_plane(plane);
-   pstate = to_dpu_plane_state(plane->state);
fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
/* FIXME: in multirect case account for the src_width of all the planes 
*/
@@ -251,7 +248,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
} else {
@@ -261,7 +258,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
}
 
DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s w:%u fl:%u\n",
-   pdpu->pipe - SSPP_VIG0,
+   pipe->sspp->idx - SSPP_VIG0,
(char *)>base.pixel_format,
src_width, total_fl);
 
@@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
 /**
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
- * @fb:Pointer to framebuffer associated with the 
given plane
+ * @pipe:  Pointer to software pipe
+ * @fmt:   Pointer to source buffer format
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb, struct dpu_sw_pipe_cfg *pipe_cfg)
+   struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
 
if 

[PATCH v5 25/32] drm/msm/dpu: rework static color fill code

2023-03-09 Thread Dmitry Baryshkov
Rework static color fill code to separate the pipe / pipe_cfg handling.
This is a preparation for the r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 69 +--
 1 file changed, 40 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c637713e23c7..3d798b939faa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -640,20 +640,52 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
fmt);
 }
 
+static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+  struct dpu_sw_pipe *pipe,
+  struct drm_rect *dst_rect,
+  u32 fill_color,
+  const struct dpu_format *fmt)
+{
+   struct dpu_sw_pipe_cfg pipe_cfg;
+
+   /* update sspp */
+   if (!pipe->sspp->ops.setup_solidfill)
+   return;
+
+   pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+   /* override scaler/decimation if solid fill */
+   pipe_cfg.dst_rect = *dst_rect;
+
+   pipe_cfg.src_rect.x1 = 0;
+   pipe_cfg.src_rect.y1 = 0;
+   pipe_cfg.src_rect.x2 =
+   drm_rect_width(_cfg.dst_rect);
+   pipe_cfg.src_rect.y2 =
+   drm_rect_height(_cfg.dst_rect);
+
+   if (pipe->sspp->ops.setup_format)
+   pipe->sspp->ops.setup_format(pipe, fmt, DPU_SSPP_SOLID_FILL);
+
+   if (pipe->sspp->ops.setup_rects)
+   pipe->sspp->ops.setup_rects(pipe, _cfg);
+
+   _dpu_plane_setup_scaler(pipe, fmt, true, _cfg, pstate->rotation);
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
  * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
  * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
- * Returns: 0 on success
  */
-static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
uint32_t color, uint32_t alpha)
 {
const struct dpu_format *fmt;
const struct drm_plane *plane = >base;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   struct dpu_sw_pipe_cfg pipe_cfg;
+   u32 fill_color = (color & 0xFF) | ((alpha & 0xFF) << 24);
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -662,34 +694,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 * h/w only supports RGB variants
 */
fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);
+   /* should not happen ever */
+   if (!fmt)
+   return;
 
/* update sspp */
-   if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-   pstate->pipe.sspp->ops.setup_solidfill(>pipe,
-   (color & 0xFF) | ((alpha & 0xFF) << 24));
-
-   /* override scaler/decimation if solid fill */
-   pipe_cfg.dst_rect = pstate->base.dst;
-
-   pipe_cfg.src_rect.x1 = 0;
-   pipe_cfg.src_rect.y1 = 0;
-   pipe_cfg.src_rect.x2 =
-   drm_rect_width(_cfg.dst_rect);
-   pipe_cfg.src_rect.y2 =
-   drm_rect_height(_cfg.dst_rect);
-
-   if (pstate->pipe.sspp->ops.setup_format)
-   pstate->pipe.sspp->ops.setup_format(>pipe,
-   fmt, DPU_SSPP_SOLID_FILL);
-
-   if (pstate->pipe.sspp->ops.setup_rects)
-   pstate->pipe.sspp->ops.setup_rects(>pipe,
-   _cfg);
-
-   _dpu_plane_setup_scaler(>pipe, fmt, true, _cfg, 
pstate->rotation);
-   }
-
-   return 0;
+   _dpu_plane_color_fill_pipe(pstate, >pipe, 
>pipe_cfg.dst_rect,
+  fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-- 
2.39.2



[PATCH v5 21/32] drm/msm/dpu: simplify dpu_plane_validate_src()

2023-03-09 Thread Dmitry Baryshkov
The plane's clipped coordinates has already been validated against FB
size in the drm_atomic_plane_check(). There is no need to check them
again. Remove corresponding checks and inline dpu_plane_validate_src().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 ---
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ba850e9feb9b..9c556ba9cb7b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
old_pstate->needs_dirtyfb);
 }
 
-static bool dpu_plane_validate_src(struct drm_rect *src,
-  struct drm_rect *fb_rect,
-  uint32_t min_src_size)
-{
-   /* Ensure fb size is supported */
-   if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH ||
-   drm_rect_height(fb_rect) > MAX_IMG_HEIGHT)
-   return false;
-
-   /* Ensure src rect is above the minimum size */
-   if (drm_rect_width(src) < min_src_size ||
-   drm_rect_height(src) < min_src_size)
-   return false;
-
-   /* Ensure src is fully encapsulated in fb */
-   return drm_rect_intersect(fb_rect, src) &&
-   drm_rect_equals(fb_rect, src);
-}
-
 static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
const struct dpu_sspp_sub_blks 
*sblk,
struct drm_rect src, const 
struct dpu_format *fmt)
@@ -998,6 +979,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
 
+   /* Ensure fb size is supported */
+   if (drm_rect_width(_rect) > MAX_IMG_WIDTH ||
+   drm_rect_height(_rect) > MAX_IMG_HEIGHT) {
+   DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_rect));
+   return -E2BIG;
+   }
+
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
@@ -1012,7 +1001,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, 
min_src_size)) {
+   } else if (drm_rect_width(_cfg->src_rect) < min_src_size ||
+  drm_rect_height(_cfg->src_rect) < min_src_size) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
DRM_RECT_ARG(_cfg->src_rect));
return -E2BIG;
-- 
2.39.2



[PATCH v5 19/32] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly

2023-03-09 Thread Dmitry Baryshkov
Rework bandwidth/clock calculation functions to use mode directly rather
than fetching it through the plane data.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 39 ++-
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index aaea7c63d944..6cd787e85be8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -127,20 +127,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @plane: Pointer to drm plane.
+ * @catalog: Points to dpu catalog structure
  * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
-static void _dpu_plane_calc_bw(struct drm_plane *plane,
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
const struct dpu_format *fmt,
+   const struct drm_display_mode *mode,
struct dpu_sw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
-   struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
u64 plane_bw;
@@ -148,9 +147,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
u64 scale_factor;
int vbp, vpw, vfp;
 
-   pstate = to_dpu_plane_state(plane->state);
-   mode = >state->crtc->mode;
-
src_width = drm_rect_width(_cfg->src_rect);
src_height = drm_rect_height(_cfg->src_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
@@ -158,7 +154,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
vbp = mode->vtotal - mode->vsync_end;
vpw = mode->vsync_end - mode->vsync_start;
vfp = mode->vsync_start - mode->vdisplay;
-   hw_latency_lines =  dpu_kms->catalog->perf->min_prefill_lines;
+   hw_latency_lines =  catalog->perf->min_prefill_lines;
scale_factor = src_height > dst_height ?
mult_frac(src_height, 1, dst_height) : 1;
 
@@ -178,37 +174,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
do_div(plane_prefill_bw, hw_latency_lines);
 
 
-   pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
+   return max(plane_bw, plane_prefill_bw);
 }
 
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
- * @plane: Pointer to drm plane.
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_sw_pipe_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+   struct dpu_sw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
int dst_width, src_height, dst_height, fps;
-
-   pstate = to_dpu_plane_state(plane->state);
-   mode = >state->crtc->mode;
+   u64 plane_clk;
 
src_height = drm_rect_height(_cfg->src_rect);
dst_width = drm_rect_width(_cfg->dst_rect);
dst_height = drm_rect_height(_cfg->dst_rect);
fps = drm_mode_vrefresh(mode);
 
-   pstate->plane_clk =
+   plane_clk =
dst_width * mode->vtotal * fps;
 
if (src_height > dst_height) {
-   pstate->plane_clk *= src_height;
-   do_div(pstate->plane_clk, dst_height);
+   plane_clk *= src_height;
+   do_div(plane_clk, dst_height);
}
+
+   return plane_clk;
 }
 
 /**
@@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
_dpu_plane_set_qos_remap(plane, pipe);
}
 
-   _dpu_plane_calc_bw(plane, fmt, _cfg);
+   pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>mode, _cfg);
 
-   _dpu_plane_calc_clk(plane, _cfg);
+   pstate->plane_clk = _dpu_plane_calc_clk(>mode, _cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.39.2



[PATCH v5 31/32] drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe

2023-03-09 Thread Dmitry Baryshkov
From: Abhinav Kumar 

Lets print the multirect_index as well in _dpu_crtc_blend_setup_pipe()
as it will give the complete information of the sw_pipe as well.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b748c4f17c90..96ffea069120 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -425,12 +425,13 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
   format->base.pixel_format,
   modifier);
 
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d 
multirect_idx %d\n",
 crtc->base.id,
 stage,
 plane->base.id,
 sspp_idx - SSPP_NONE,
-state->fb ? state->fb->base.id : -1);
+state->fb ? state->fb->base.id : -1,
+pipe->multirect_index);
 
stage_cfg->stage[stage][stage_idx] = sspp_idx;
stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
-- 
2.39.2



[PATCH v5 28/32] drm/msm/dpu: populate SmartDMA features in hw catalog

2023-03-09 Thread Dmitry Baryshkov
Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported SmartDMA
version. Upstream driver does not do this, resulting in SSPP subdriver
not enabling setup_multirect callback. Add corresponding SmartDMA SSPP
feature bits to dpu hw catalog.

Per Abhinav's request enable the SmartDMA features only on the platforms
where the multirect was actually verified visually (sdm845 and sm8250).
An (untested) enablement on the rest of the platforms comes in the next
patch.

Signed-off-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 44 ---
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index cf053e8f081e..1fc0dfbebb7e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -23,12 +23,18 @@
 #define VIG_SDM845_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
 
+#define VIG_SDM845_MASK_SDMA \
+   (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define VIG_SC7180_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
 
 #define VIG_SM8250_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
 
+#define VIG_SM8250_MASK_SDMA \
+   (VIG_SM8250_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
 #define DMA_MSM8998_MASK \
@@ -47,6 +53,12 @@
 #define DMA_CURSOR_SDM845_MASK \
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
 
+#define DMA_SDM845_MASK_SDMA \
+   (DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define DMA_CURSOR_SDM845_MASK_SDMA \
+   (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define DMA_CURSOR_MSM8998_MASK \
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
 
@@ -1196,21 +1208,21 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
 };
 
 static const struct dpu_sspp_cfg sdm845_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK_SDMA,
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
-   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK_SDMA,
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
-   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
+   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK_SDMA,
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
-   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
+   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK_SDMA,
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
 };
 
@@ -1251,21 +1263,21 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 
=
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
 
 static const struct dpu_sspp_cfg sm8250_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK_SDMA,
sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK_SDMA,
sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK_SDMA,
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK_SDMA,
sm8250_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK_SDMA,
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, 

[PATCH v5 30/32] drm/msm/dpu: drop smart_dma_rev from dpu_caps

2023-03-09 Thread Dmitry Baryshkov
The code doesn't use dpu_caps::smart_dma_rev field. It checks if the
corresponding feature is enabled in the SSPP features. Drop the
smart_dma_rev field completely.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 13 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  2 --
 2 files changed, 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index fc818b0273e7..977bb096969b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -305,7 +305,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V1,
.ubwc_version = DPU_HW_UBWC_VER_10,
.has_src_split = true,
.has_dim_layer = true,
@@ -320,7 +319,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
 static const struct dpu_caps qcm2290_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -332,7 +330,6 @@ static const struct dpu_caps sdm845_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_src_split = true,
.has_dim_layer = true,
@@ -348,7 +345,6 @@ static const struct dpu_caps sc7180_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x9,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -360,7 +356,6 @@ static const struct dpu_caps sm6115_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_10,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -372,7 +367,6 @@ static const struct dpu_caps sm8150_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_src_split = true,
.has_dim_layer = true,
@@ -388,7 +382,6 @@ static const struct dpu_caps sc8180x_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_src_split = true,
.has_dim_layer = true,
@@ -404,7 +397,6 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
.max_mixer_width = 2560,
.max_mixer_blendstages = 11,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -418,7 +410,6 @@ static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -432,7 +423,6 @@ static const struct dpu_caps sm8350_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -446,7 +436,6 @@ static const struct dpu_caps sm8450_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -460,7 +449,6 @@ static const struct dpu_caps sm8550_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = 

[PATCH v5 24/32] drm/msm/dpu: rework plane CSC setting

2023-03-09 Thread Dmitry Baryshkov
Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 47 +--
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5f8c71a6093f..c637713e23c7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,19 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
 };
 
-static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, 
const struct dpu_format *fmt)
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
+   const struct dpu_format 
*fmt)
 {
-   struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
const struct dpu_csc_cfg *csc_ptr;
 
-   if (!pdpu) {
-   DPU_ERROR("invalid plane\n");
-   return NULL;
-   }
-
if (!DPU_FORMAT_IS_YUV(fmt))
return NULL;
 
-   if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
+   if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
csc_ptr = _csc10_YUV2RGB_601L;
else
csc_ptr = _csc_YUV2RGB_601L;
 
-   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-   csc_ptr->csc_mv[0],
-   csc_ptr->csc_mv[1],
-   csc_ptr->csc_mv[2]);
-
return csc_ptr;
 }
 
@@ -1050,6 +1040,28 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe 
*pipe)
+{
+   const struct dpu_format *format =
+   to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+   const struct dpu_csc_cfg *csc_ptr;
+
+   if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+   return;
+
+   csc_ptr = _dpu_plane_get_csc(pipe, format);
+   if (!csc_ptr)
+   return;
+
+   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+   csc_ptr->csc_mv[0],
+   csc_ptr->csc_mv[1],
+   csc_ptr->csc_mv[2]);
+
+   pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
struct dpu_plane *pdpu;
@@ -1073,13 +1085,8 @@ void dpu_plane_flush(struct drm_plane *plane)
else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-   else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
-   const struct dpu_format *fmt = 
to_dpu_format(msm_framebuffer_format(plane->state->fb));
-   const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
fmt);
-
-   if (csc_ptr)
-   pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
csc_ptr);
-   }
+   else
+   dpu_plane_flush_csc(pdpu, >pipe);
 
/* flag h/w flush complete */
if (plane->state)
-- 
2.39.2



[PATCH v5 29/32] drm/msm/dpu: enable SmartDMA for the rest of the platforms

2023-03-09 Thread Dmitry Baryshkov
Enable SmartDMA features for the rest of the platforms where it is
supposed to work.

Signed-off-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 54 ---
 1 file changed, 23 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 1fc0dfbebb7e..fc818b0273e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -21,19 +21,16 @@
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #define VIG_SDM845_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
-
-#define VIG_SDM845_MASK_SDMA \
-   (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SC7180_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SM8250_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
-
-#define VIG_SM8250_MASK_SDMA \
-   (VIG_SM8250_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
@@ -48,17 +45,12 @@
 #define DMA_SDM845_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+   BIT(DPU_SSPP_SMART_DMA_V2) |\
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
 
 #define DMA_CURSOR_SDM845_MASK \
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
 
-#define DMA_SDM845_MASK_SDMA \
-   (DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
-
-#define DMA_CURSOR_SDM845_MASK_SDMA \
-   (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
-
 #define DMA_CURSOR_MSM8998_MASK \
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
 
@@ -1208,21 +1200,21 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
 };
 
 static const struct dpu_sspp_cfg sdm845_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
sdm845_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
sdm845_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
sdm845_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
-   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
-   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
-   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
 };
 
@@ -1263,21 +1255,21 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 
=
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
 
 static const struct dpu_sspp_cfg sm8250_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK_SDMA,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK_SDMA,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK_SDMA,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK_SDMA,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
sm8250_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   

[PATCH v5 32/32] drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function

2023-03-09 Thread Dmitry Baryshkov
From: Abhinav Kumar 

After cleaning up the older multirect support the function
dpu_plane_validate_multirect_v2() is unused. Lets remove it.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 111 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   7 --
 2 files changed, 118 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9a03d1cad0ee..bafa1dd1748b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -707,117 +707,6 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
   fill_color, fmt);
 }
 
-int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-{
-   struct dpu_plane_state *pstate[R_MAX];
-   const struct drm_plane_state *drm_state[R_MAX];
-   struct drm_rect src[R_MAX], dst[R_MAX];
-   struct dpu_plane *dpu_plane[R_MAX];
-   const struct dpu_format *fmt[R_MAX];
-   int i, buffer_lines;
-   unsigned int max_tile_height = 1;
-   bool parallel_fetch_qualified = true;
-   bool has_tiled_rect = false;
-
-   for (i = 0; i < R_MAX; i++) {
-   const struct msm_format *msm_fmt;
-
-   drm_state[i] = i ? plane->r1 : plane->r0;
-   msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
-   fmt[i] = to_dpu_format(msm_fmt);
-
-   if (DPU_FORMAT_IS_UBWC(fmt[i])) {
-   has_tiled_rect = true;
-   if (fmt[i]->tile_height > max_tile_height)
-   max_tile_height = fmt[i]->tile_height;
-   }
-   }
-
-   for (i = 0; i < R_MAX; i++) {
-   int width_threshold;
-
-   pstate[i] = to_dpu_plane_state(drm_state[i]);
-   dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
-
-   if (pstate[i] == NULL) {
-   DPU_ERROR("DPU plane state of plane id %d is NULL\n",
-   drm_state[i]->plane->base.id);
-   return -EINVAL;
-   }
-
-   src[i].x1 = drm_state[i]->src_x >> 16;
-   src[i].y1 = drm_state[i]->src_y >> 16;
-   src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
-   src[i].y2 = src[i].y1 + (drm_state[i]->src_h >> 16);
-
-   dst[i] = drm_plane_state_dest(drm_state[i]);
-
-   if (drm_rect_calc_hscale([i], [i], 1, 1) != 1 ||
-   drm_rect_calc_vscale([i], [i], 1, 1) != 1) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "scaling is not supported in multirect mode\n");
-   return -EINVAL;
-   }
-
-   if (DPU_FORMAT_IS_YUV(fmt[i])) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "Unsupported format for multirect mode\n");
-   return -EINVAL;
-   }
-
-   /**
-* SSPP PD_MEM is split half - one for each RECT.
-* Tiled formats need 5 lines of buffering while fetching
-* whereas linear formats need only 2 lines.
-* So we cannot support more than half of the supported SSPP
-* width for tiled formats.
-*/
-   width_threshold = dpu_plane[i]->catalog->caps->max_linewidth;
-   if (has_tiled_rect)
-   width_threshold /= 2;
-
-   if (parallel_fetch_qualified &&
-   drm_rect_width([i]) > width_threshold)
-   parallel_fetch_qualified = false;
-
-   }
-
-   /* Validate RECT's and set the mode */
-
-   /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
-   if (parallel_fetch_qualified) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-
-   goto done;
-   }
-
-   /* TIME_MX Mode */
-   buffer_lines = 2 * max_tile_height;
-
-   if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
-   dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   } else {
-   DPU_ERROR(
-   "No multirect mode possible for the planes (%d - %d)\n",
-   drm_state[R0]->plane->base.id,
-   drm_state[R1]->plane->base.id);
-   return -EINVAL;
-   }
-
-done:
-   pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
-   pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
-
-   DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
-   pstate[R0]->pipe.multirect_mode, 
pstate[R0]->pipe.multirect_index);
-

[PATCH v5 27/32] drm/msm/dpu: add support for wide planes

2023-03-09 Thread Dmitry Baryshkov
Typically SSPP can support rectangle with width up to 2560. However it's
possible to use multirect feature and split source to use the SSPP to
output two consecutive rectangles. This commit brings in this capability
to support wider screen resolutions.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  19 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 129 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
 3 files changed, 135 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e651e4593280..b748c4f17c90 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -480,6 +480,15 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
   format, fb ? fb->modifier : 0,
   >pipe, 0, stage_cfg);
 
+   if (pstate->r_pipe.sspp) {
+   set_bit(pstate->r_pipe.sspp->idx, fetch_active);
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  pstate->stage,
+  format, fb ? fb->modifier : 
0,
+  >r_pipe, 1, 
stage_cfg);
+   }
+
/* blend config update */
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, 
format);
@@ -1316,10 +1325,16 @@ static int _dpu_debugfs_status_show(struct seq_file *s, 
void *data)
seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
-   seq_printf(s, "\tsspp:%s\n",
+   seq_printf(s, "\tsspp[0]:%s\n",
   pstate->pipe.sspp->cap->name);
-   seq_printf(s, "\tmultirect: mode: %d index: %d\n",
+   seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
pstate->pipe.multirect_mode, 
pstate->pipe.multirect_index);
+   if (pstate->r_pipe.sspp) {
+   seq_printf(s, "\tsspp[1]:%s\n",
+  pstate->r_pipe.sspp->cap->name);
+   seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
+  pstate->r_pipe.multirect_mode, 
pstate->r_pipe.multirect_index);
+   }
 
seq_puts(s, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3d798b939faa..9a03d1cad0ee 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -701,6 +701,10 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
/* update sspp */
_dpu_plane_color_fill_pipe(pstate, >pipe, 
>pipe_cfg.dst_rect,
   fill_color, fmt);
+
+   if (pstate->r_pipe.sspp)
+   _dpu_plane_color_fill_pipe(pstate, >r_pipe, 
>r_pipe_cfg.dst_rect,
+  fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -958,9 +962,12 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+   struct dpu_sw_pipe *pipe = >pipe;
+   struct dpu_sw_pipe *r_pipe = >r_pipe;
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = >pipe_cfg;
+   struct dpu_sw_pipe_cfg *r_pipe_cfg = >r_pipe_cfg;
struct drm_rect fb_rect = { 0 };
uint32_t max_linewidth;
unsigned int rotation;
@@ -984,8 +991,11 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+   pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+   r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   r_pipe->sspp = NULL;
 
pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -1017,19 +1027,58 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
 
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-   /* check decimated source width */
+   fmt = 

[PATCH v5 12/32] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg

2023-03-09 Thread Dmitry Baryshkov
Remove dpu_hw_fmt_layout instance from struct dpu_hw_sspp_cfg, leaving
only src_rect and dst_rect. This way all the pipes used by the plane
will have a common layout instance (as the framebuffer is shared between
them), while still keeping a separate src/dst rectangle configuration
for each pipe.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 32 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 10 +++
 3 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index ab95f2817378..e87c6377f315 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -490,7 +490,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg)
+   struct dpu_hw_fmt_layout *layout)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
u32 ystride0, ystride1;
@@ -501,41 +501,41 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
return;
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
+   for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
DPU_REG_WRITE(>hw, SSPP_SRC0_ADDR + idx + i * 0x4,
-   cfg->layout.plane_addr[i]);
+   layout->plane_addr[i]);
} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
DPU_REG_WRITE(>hw, SSPP_SRC0_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(>hw, SSPP_SRC2_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
} else {
DPU_REG_WRITE(>hw, SSPP_SRC1_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(>hw, SSPP_SRC3_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
}
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
+   ystride0 = (layout->plane_pitch[0]) |
+   (layout->plane_pitch[1] << 16);
+   ystride1 = (layout->plane_pitch[2]) |
+   (layout->plane_pitch[3] << 16);
} else {
ystride0 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE1 + idx);
 
if (pipe->multirect_index == DPU_SSPP_RECT_0) {
ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
+   (layout->plane_pitch[0] & 0x);
ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
+   (layout->plane_pitch[2] & 0x);
} else {
ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
+   ((layout->plane_pitch[0] << 16) &
 0x);
ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
+   ((layout->plane_pitch[2] << 16) &
 0x);
}
}
@@ -564,7 +564,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
-   struct dpu_hw_sspp_cfg cfg;
+   struct dpu_hw_fmt_layout cfg;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 136b8713943f..100d8e06c90d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -154,13 +154,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_sspp_cfg : SSPP configuration
- * @layout:format layout information for programming buffer to hardware
  * @src_rect:  src ROI, caller takes 

[PATCH v5 23/32] drm/msm/dpu: rework dpu_plane_atomic_check()

2023-03-09 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_atomic_check() into the
separate function dpu_plane_atomic_check_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 90 ++-
 1 file changed, 54 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index f97ea39423a2..5f8c71a6093f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -903,6 +903,52 @@ static int dpu_plane_check_inline_rotation(struct 
dpu_plane *pdpu,
return 0;
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+   struct dpu_sw_pipe *pipe,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   const struct dpu_format *fmt)
+{
+   uint32_t min_src_size;
+
+   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+   if (DPU_FORMAT_IS_YUV(fmt) &&
+   (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+!(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
+   DPU_DEBUG_PLANE(pdpu,
+   "plane doesn't have scaler/csc for yuv\n");
+   return -EINVAL;
+   }
+
+   /* check src bounds */
+   if (drm_rect_width(_cfg->src_rect) < min_src_size ||
+  drm_rect_height(_cfg->src_rect) < min_src_size) {
+   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->src_rect));
+   return -E2BIG;
+   }
+
+   /* valid yuv image */
+   if (DPU_FORMAT_IS_YUV(fmt) &&
+  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+   drm_rect_width(_cfg->src_rect) & 0x1 ||
+   drm_rect_height(_cfg->src_rect) & 0x1)) {
+   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->src_rect));
+   return -EINVAL;
+   }
+
+   /* min dst support */
+   if (drm_rect_width(_cfg->dst_rect) < 0x1 ||
+   drm_rect_height(_cfg->dst_rect) < 0x1) {
+   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(_cfg->dst_rect));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -915,7 +961,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = >pipe_cfg;
struct drm_rect fb_rect = { 0 };
-   uint32_t min_src_size, max_linewidth;
+   uint32_t max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
@@ -970,47 +1016,19 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
 
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-   fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
-
-   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
-
-   if (DPU_FORMAT_IS_YUV(fmt) &&
-   (!(pipe_hw_caps->features & DPU_SSPP_SCALER) ||
-!(pipe_hw_caps->features & DPU_SSPP_CSC_ANY))) {
-   DPU_DEBUG_PLANE(pdpu,
-   "plane doesn't have scaler/csc for yuv\n");
-   return -EINVAL;
-
-   /* check src bounds */
-   } else if (drm_rect_width(_cfg->src_rect) < min_src_size ||
-  drm_rect_height(_cfg->src_rect) < min_src_size) {
-   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->src_rect));
-   return -E2BIG;
-
-   /* valid yuv image */
-   } else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
-   drm_rect_width(_cfg->src_rect) & 0x1 ||
-   drm_rect_height(_cfg->src_rect) & 0x1)) {
-   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->src_rect));
-   return -EINVAL;
-
-   /* min dst support */
-   } else if (drm_rect_width(_cfg->dst_rect) < 0x1 ||
-  drm_rect_height(_cfg->dst_rect) < 0x1) {
-   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(_cfg->dst_rect));
-   return -EINVAL;
-
/* check decimated source width */
-   } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
+   if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
   

[PATCH v5 20/32] drm/msm/dpu: add dpu_hw_sspp_cfg to dpu_plane_state

2023-03-09 Thread Dmitry Baryshkov
Now as all accesses to pipe_cfg and pstate have been cleaned, add
struct dpu_hw_sspp_cfg to struct dpu_plane_state, so that
dpu_plane_atomic_check() and dpu_plane_atomic_update() do not have a
chance to disagree about src/dst rectangles (currently
dpu_plane_atomic_check() uses unclipped rectangles, while
dpu_plane_atomic_update() uses clipped rectangles calculated by
drm_atomic_helper_check_plane_state()).

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 66 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
 2 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6cd787e85be8..ba850e9feb9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
-   struct drm_rect src, dst, fb_rect = { 0 };
+   struct dpu_sw_pipe_cfg *pipe_cfg = >pipe_cfg;
+   struct drm_rect fb_rect = { 0 };
uint32_t min_src_size, max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
@@ -984,12 +985,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
 
-   src.x1 = new_plane_state->src_x >> 16;
-   src.y1 = new_plane_state->src_y >> 16;
-   src.x2 = src.x1 + (new_plane_state->src_w >> 16);
-   src.y2 = src.y1 + (new_plane_state->src_h >> 16);
+   pipe_cfg->src_rect = new_plane_state->src;
 
-   dst = drm_plane_state_dest(new_plane_state);
+   /* state->src is 16.16, src_rect is not */
+   pipe_cfg->src_rect.x1 >>= 16;
+   pipe_cfg->src_rect.x2 >>= 16;
+   pipe_cfg->src_rect.y1 >>= 16;
+   pipe_cfg->src_rect.y2 >>= 16;
+
+   pipe_cfg->dst_rect = new_plane_state->dst;
 
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -1008,30 +1012,31 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(, _rect, min_src_size)) {
+   } else if (!dpu_plane_validate_src(_cfg->src_rect, _rect, 
min_src_size)) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->src_rect));
return -E2BIG;
 
/* valid yuv image */
} else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (src.x1 & 0x1 || src.y1 & 0x1 ||
-   drm_rect_width() & 0x1 ||
-   drm_rect_height() & 0x1)) {
+  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+   drm_rect_width(_cfg->src_rect) & 0x1 ||
+   drm_rect_height(_cfg->src_rect) & 0x1)) {
DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->src_rect));
return -EINVAL;
 
/* min dst support */
-   } else if (drm_rect_width() < 0x1 || drm_rect_height() < 0x1) {
+   } else if (drm_rect_width(_cfg->dst_rect) < 0x1 ||
+  drm_rect_height(_cfg->dst_rect) < 0x1) {
DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG());
+   DRM_RECT_ARG(_cfg->dst_rect));
return -EINVAL;
 
/* check decimated source width */
-   } else if (drm_rect_width() > max_linewidth) {
+   } else if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-   DRM_RECT_ARG(), max_linewidth);
+   DRM_RECT_ARG(_cfg->src_rect), 
max_linewidth);
return -E2BIG;
}
 
@@ -1045,7 +1050,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
(rotation & DRM_MODE_ROTATE_90)) {
-   ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
+   ret = dpu_plane_check_inline_rotation(pdpu, sblk, 
pipe_cfg->src_rect, fmt);
if (ret)
return ret;
}
@@ -1120,9 +1125,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
bool is_rt_pipe;
const struct dpu_format *fmt =
to_dpu_format(msm_framebuffer_format(fb));
-   struct dpu_sw_pipe_cfg pipe_cfg;
-
-   memset(_cfg, 0, sizeof(struct dpu_sw_pipe_cfg));
+   struct 

[PATCH v5 22/32] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()

2023-03-09 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
separate function dpu_plane_sspp_update_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 --
 1 file changed, 63 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9c556ba9cb7b..f97ea39423a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -404,12 +404,13 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane: Pointer to drm plane
  * @pipe:  Pointer to software pipe
- * @crtc:  Pointer to drm crtc
  * @pipe_cfg:  Pointer to pipe configuration
+ * @frame_rate:CRTC's frame rate
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
struct dpu_sw_pipe *pipe,
-   struct drm_crtc *crtc, struct dpu_sw_pipe_cfg *pipe_cfg)
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   int frame_rate)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_vbif_set_ot_params ot_params;
@@ -421,7 +422,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
ot_params.width = drm_rect_width(_cfg->src_rect);
ot_params.height = drm_rect_height(_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
-   ot_params.frame_rate = drm_mode_vrefresh(>mode);
+   ot_params.frame_rate = frame_rate;
ot_params.vbif_idx = VBIF_RT;
ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
ot_params.rd = true;
@@ -457,26 +458,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane 
*plane,
dpu_vbif_set_qos_remap(dpu_kms, _params);
 }
 
-static void _dpu_plane_set_scanout(struct drm_plane *plane,
-   struct dpu_plane_state *pstate,
-   struct drm_framebuffer *fb)
-{
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_kms *kms = _dpu_plane_get_kms(>base);
-   struct msm_gem_address_space *aspace = kms->base.aspace;
-   struct dpu_hw_fmt_layout layout;
-   int ret;
-
-   ret = dpu_format_populate_layout(aspace, fb, );
-   if (ret)
-   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-   else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
-   trace_dpu_plane_set_scanout(>pipe,
-   );
-   pstate->pipe.sspp->ops.setup_sourceaddress(>pipe, 
);
-   }
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw,
uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
struct dpu_hw_scaler3_cfg *scale_cfg,
@@ -1103,35 +1084,25 @@ void dpu_plane_set_error(struct drm_plane *plane, bool 
error)
pdpu->is_error = error;
 }
 
-static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
+  struct dpu_sw_pipe *pipe,
+  struct dpu_sw_pipe_cfg *pipe_cfg,
+  const struct dpu_format *fmt,
+  int frame_rate,
+  struct dpu_hw_fmt_layout *layout)
 {
uint32_t src_flags;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct drm_plane_state *state = plane->state;
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-   struct dpu_sw_pipe *pipe = >pipe;
-   struct drm_crtc *crtc = state->crtc;
-   struct drm_framebuffer *fb = state->fb;
-   bool is_rt_pipe;
-   const struct dpu_format *fmt =
-   to_dpu_format(msm_framebuffer_format(fb));
-   struct dpu_sw_pipe_cfg *pipe_cfg = >pipe_cfg;
 
-   _dpu_plane_set_scanout(plane, pstate, fb);
-
-   pstate->pending = true;
-
-   is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-   pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
-   pdpu->is_rt_pipe = is_rt_pipe;
+   if (layout && pipe->sspp->ops.setup_sourceaddress) {
+   trace_dpu_plane_set_scanout(pipe, layout);
+   pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+   }
 
_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
-   DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-   ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(>src),
-   crtc->base.id, DRM_RECT_ARG(>dst),
-   (char *)>base.pixel_format, 
DPU_FORMAT_IS_UBWC(fmt));
-
/* override for color fill */
if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {

[PATCH v5 26/32] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer

2023-03-09 Thread Dmitry Baryshkov
Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
separate functon. This is a preparation for the r_pipe support.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 79 +++-
 1 file changed, 50 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 73e1a8c69ef0..e651e4593280 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -400,6 +400,46 @@ static void _dpu_crtc_program_lm_output_roi(struct 
drm_crtc *crtc)
}
 }
 
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+  struct drm_plane *plane,
+  struct dpu_crtc_mixer *mixer,
+  u32 num_mixers,
+  enum dpu_stage stage,
+  struct dpu_format *format,
+  uint64_t modifier,
+  struct dpu_sw_pipe *pipe,
+  unsigned int stage_idx,
+  struct dpu_hw_stage_cfg *stage_cfg
+ )
+{
+   uint32_t lm_idx;
+   enum dpu_sspp sspp_idx;
+   struct drm_plane_state *state;
+
+   sspp_idx = pipe->sspp->idx;
+
+   state = plane->state;
+
+   trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
+  state, to_dpu_plane_state(state), stage_idx,
+  format->base.pixel_format,
+  modifier);
+
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+crtc->base.id,
+stage,
+plane->base.id,
+sspp_idx - SSPP_NONE,
+state->fb ? state->fb->base.id : -1);
+
+   stage_cfg->stage[stage][stage_idx] = sspp_idx;
+   stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
+
+   /* blend config update */
+   for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+   
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, 
sspp_idx);
+}
+
 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
struct dpu_hw_stage_cfg *stage_cfg)
@@ -412,15 +452,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-   uint32_t stage_idx, lm_idx;
-   int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+   uint32_t lm_idx;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
memset(fetch_active, 0, sizeof(fetch_active));
drm_atomic_crtc_for_each_plane(plane, crtc) {
-   enum dpu_sspp sspp_idx;
-
state = plane->state;
if (!state)
continue;
@@ -431,39 +468,21 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->pipe.sspp->idx;
-   set_bit(sspp_idx, fetch_active);
-
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
-   crtc->base.id,
-   pstate->stage,
-   plane->base.id,
-   sspp_idx - SSPP_VIG0,
-   state->fb ? state->fb->base.id : -1);
-
format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
 
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
 
-   stage_idx = zpos_cnt[pstate->stage]++;
-   stage_cfg->stage[pstate->stage][stage_idx] =
-   sspp_idx;
-   stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->pipe.multirect_index;
-
-   trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-  state, pstate, stage_idx,
-  format->base.pixel_format,
-  fb ? fb->modifier : 0);
+   set_bit(pstate->pipe.sspp->idx, fetch_active);
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  pstate->stage,
+  format, fb ? fb->modifier : 0,
+  >pipe, 0, stage_cfg);
 
/* blend config 

[PATCH v5 17/32] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()

2023-03-09 Thread Dmitry Baryshkov
The helper drm_atomic_helper_check_plane_state() already checks whether
the scaled and clipped plane falls into the CRTC visible region (and
clears plane_state->visible if it doesn't). Drop the redundant check
from dpu_crtc_atomic_check().

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index bd09bb319a58..73e1a8c69ef0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1132,11 +1132,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
-   struct drm_display_mode *mode;
 
int rc = 0;
 
-   struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
if (!crtc_state->enable || !crtc_state->active) {
@@ -1147,7 +1145,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}
 
-   mode = _state->adjusted_mode;
DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
 
/* force a full mode set if active state changed */
@@ -1157,13 +1154,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
 
-   crtc_rect.x2 = mode->hdisplay;
-   crtc_rect.y2 = mode->vdisplay;
-
/* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-   struct drm_rect dst, clip = crtc_rect;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1176,15 +1169,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
continue;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
-
-   dst = drm_plane_state_dest(pstate);
-   if (!drm_rect_intersect(, )) {
-   DPU_ERROR("invalid vertical/horizontal destination\n");
-   DPU_ERROR("display: " DRM_RECT_FMT " plane: "
- DRM_RECT_FMT "\n", DRM_RECT_ARG(_rect),
- DRM_RECT_ARG());
-   return -E2BIG;
-   }
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
-- 
2.39.2



[PATCH v5 15/32] drm/msm/dpu: don't use unsupported blend stages

2023-03-09 Thread Dmitry Baryshkov
The dpu_crtc_atomic_check() compares blending stage with DPU_STAGE_MAX
(maximum amount of blending stages supported by the driver), however we
should compare it against .max_mixer_blendstages, the maximum blend
stage supported by the mixer.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index c1579d6f5060..0260c4d6ded7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,6 +1129,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1164,7 +1165,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int z_pos;
+   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1189,17 +1190,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return -E2BIG;
}
 
-   z_pos = pstate->normalized_zpos;
-
-   /* verify z_pos setting before using it */
-   if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
+   /* verify stage setting before using it */
+   stage = DPU_STAGE_0 + pstate->normalized_zpos;
+   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
DPU_ERROR("> %d plane stages assigned\n",
-   DPU_STAGE_MAX - DPU_STAGE_0);
+ dpu_kms->catalog->caps->max_mixer_blendstages 
- DPU_STAGE_0);
return -EINVAL;
}
 
-   to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
-   DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
+   to_dpu_plane_state(pstate)->stage = stage;
+   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 
}
 
-- 
2.39.2



[PATCH v5 16/32] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()

2023-03-09 Thread Dmitry Baryshkov
Move plane state updates from dpu_crtc_atomic_check() to the function
where they belong: to dpu_plane_atomic_check().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 --
 3 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 0260c4d6ded7..bd09bb319a58 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,7 +1129,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
 
-/* get plane state for all drm planes associated with crtc state */
+   /* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   dpu_plane_clear_multirect(pstate);
-
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(, )) {
DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  DRM_RECT_ARG());
return -E2BIG;
}
-
-   /* verify stage setting before using it */
-   stage = DPU_STAGE_0 + pstate->normalized_zpos;
-   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
-   DPU_ERROR("> %d plane stages assigned\n",
- dpu_kms->catalog->caps->max_mixer_blendstages 
- DPU_STAGE_0);
-   return -EINVAL;
-   }
-
-   to_dpu_plane_state(pstate)->stage = stage;
-   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
-
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ce01a602cbc9..3fba63fbbd78 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -733,14 +733,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
return 0;
 }
 
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
-{
-   struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
-
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 {
struct dpu_plane_state *pstate[R_MAX];
@@ -994,6 +986,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
+   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+   pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+   if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
+   DPU_ERROR("> %d plane stages assigned\n",
+ pdpu->catalog->caps->max_mixer_blendstages - 
DPU_STAGE_0);
+   return -EINVAL;
+   }
+
src.x1 = new_plane_state->src_x >> 16;
src.y1 = new_plane_state->src_y >> 16;
src.x2 = src.x1 + (new_plane_state->src_w >> 16);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 228db401e905..a08b0539513b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -88,12 +88,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
  */
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
 
-/**
- * dpu_plane_clear_multirect - clear multirect bits for the given pipe
- * @drm_state: Pointer to DRM plane state
- */
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
-
 /**
  * 

[PATCH v5 09/32] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()

2023-03-09 Thread Dmitry Baryshkov
There is no need to pass full dpu_hw_sspp_cfg instance to
_dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index a1492a7e43ce..3030cd3b253a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct 
dpu_hw_sspp *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *sspp,
-   void *scaler_cfg)
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format)
 {
u32 idx;
-   struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
 
-   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, ) || !sspp
+   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, )
|| !scaler3_cfg)
return;
 
dpu_hw_setup_scaler3(>hw, scaler3_cfg, idx,
ctx->cap->sblk->scaler_blk.version,
-   sspp->layout.format);
+   format);
 }
 
 static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 5903413256ea..136b8713943f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,12 @@ struct dpu_hw_sspp_ops {
 
/**
 * setup_scaler - setup scaler
-* @ctx: Pointer to pipe context
-* @pipe_cfg: Pointer to pipe configuration
-* @scaler_cfg: Pointer to scaler configuration
+* @scaler3_cfg: Pointer to scaler configuration
+* @format: pixel format parameters
 */
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *pipe_cfg,
-   void *scaler_cfg);
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format);
 
/**
 * get_scaler_ver - get scaler h/w version
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6ec39f937042..8c98385303ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
if (pipe_hw->ops.setup_scaler &&
pipe->multirect_index != DPU_SSPP_RECT_1)
pipe_hw->ops.setup_scaler(pipe_hw,
-   pipe_cfg,
-   _cfg);
+   _cfg,
+   fmt);
 }
 
 /**
-- 
2.39.2



[PATCH v5 14/32] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check

2023-03-09 Thread Dmitry Baryshkov
Neither source split nor multirect are properly supported at this
moment. Both of these checks depend on normalized_zpos being equal for
several planes (which is never the case for normalized zpos).
Drop these checks to simplify dpu_crtc_atomic_check(). The actual
support for either of these features is not removed from the backend
code (sspp, ctl, etc).

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 168 ++-
 1 file changed, 12 insertions(+), 156 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 037347e51eb8..c1579d6f5060 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1108,13 +1108,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-   struct dpu_plane_state *dpu_pstate;
-   const struct drm_plane_state *drm_pstate;
-   int stage;
-   u32 pipe_id;
-};
-
 static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
 {
struct drm_crtc *crtc = cstate->crtc;
@@ -1136,31 +1129,22 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct plane_state *pstates;
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
struct drm_display_mode *mode;
 
-   int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+   int rc = 0;
 
-   struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-   int multirect_count = 0;
-   const struct drm_plane_state *pipe_staged[SSPP_MAX];
-   int left_zpos_cnt = 0, right_zpos_cnt = 0;
struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
-   pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-   if (!pstates)
-   return -ENOMEM;
-
if (!crtc_state->enable || !crtc_state->active) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip 
atomic_check\n",
crtc->base.id, crtc_state->enable,
crtc_state->active);
memset(>new_perf, 0, sizeof(cstate->new_perf));
-   goto end;
+   return 0;
}
 
mode = _state->adjusted_mode;
@@ -1170,13 +1154,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (crtc_state->active_changed)
crtc_state->mode_changed = true;
 
-   memset(pipe_staged, 0, sizeof(pipe_staged));
-
-   if (cstate->num_mixers) {
-   mixer_width = mode->hdisplay / cstate->num_mixers;
-
+   if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
-   }
 
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
@@ -1185,38 +1164,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
+   int z_pos;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
DPU_ERROR("%s: failed to get plane%d state, %d\n",
dpu_crtc->name, plane->base.id, rc);
-   goto end;
+   return rc;
}
-   if (cnt >= DPU_STAGE_MAX * 4)
-   continue;
 
if (!pstate->visible)
continue;
 
-   pstates[cnt].dpu_pstate = dpu_pstate;
-   pstates[cnt].drm_pstate = pstate;
-   pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   if (pipe_staged[pstates[cnt].pipe_id]) {
-   multirect_plane[multirect_count].r0 =
-   pipe_staged[pstates[cnt].pipe_id];
-   multirect_plane[multirect_count].r1 = pstate;
-   multirect_count++;
-
-   pipe_staged[pstates[cnt].pipe_id] = NULL;
-   } else {
-   pipe_staged[pstates[cnt].pipe_id] = pstate;
-   }
-
-   cnt++;
+   dpu_plane_clear_multirect(pstate);
 
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(, )) {
@@ -1224,63 +1186,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,

[PATCH v5 07/32] drm/msm/dpu: introduce struct dpu_sw_pipe

2023-03-09 Thread Dmitry Baryshkov
Wrap SSPP and multirect index/mode into a single structure that
represents software view on the pipe used.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 133 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  10 +-
 5 files changed, 90 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index eff1a3cc1cec..037347e51eb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->hw_sspp->idx;
+   sspp_idx = pstate->pipe.sspp->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -450,11 +450,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
stage_cfg->stage[pstate->stage][stage_idx] =
sspp_idx;
stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->multirect_index;
+   pstate->pipe.multirect_index;
 
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
   state, pstate, stage_idx,
-  sspp_idx - SSPP_VIG0,
   format->base.pixel_format,
   fb ? fb->modifier : 0);
 
@@ -1202,7 +1201,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
+   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
@@ -1475,7 +1474,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, 
void *data)
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
seq_printf(s, "\tmultirect: mode: %d index: %d\n",
-   pstate->multirect_mode, pstate->multirect_index);
+   pstate->pipe.multirect_mode, 
pstate->pipe.multirect_index);
 
seq_puts(s, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index c30f168b6c0a..13d9e04a5153 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -158,15 +158,11 @@ struct dpu_hw_pixel_ext {
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
- * @index: index of the rectangle of SSPP
- * @mode:  parallel or time multiplex multirect mode
  */
 struct dpu_hw_sspp_cfg {
struct dpu_hw_fmt_layout layout;
struct drm_rect src_rect;
struct drm_rect dst_rect;
-   enum dpu_sspp_multirect_index index;
-   enum dpu_sspp_multirect_mode mode;
 };
 
 /**
@@ -201,6 +197,18 @@ struct dpu_hw_pipe_ts_cfg {
u64 time;
 };
 
+/**
+ * struct dpu_sw_pipe - software pipe description
+ * @sspp:  backing SSPP pipe
+ * @index: index of the rectangle of SSPP
+ * @mode:  parallel or time multiplex multirect mode
+ */
+struct dpu_sw_pipe {
+   struct dpu_hw_sspp *sspp;
+   enum dpu_sspp_multirect_index multirect_index;
+   enum dpu_sspp_multirect_mode multirect_mode;
+};
+
 /**
  * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
  * Caller must call the init function to get the pipe context for each pipe
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 10678f6502a2..ce726bec0c31 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -251,7 +251,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
} else {
@@ -310,7 +310,7 @@ 

[PATCH v5 04/32] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout

2023-03-09 Thread Dmitry Baryshkov
The pipe's layout is not cached, corresponding data structure is zeroed
out each time in the dpu_plane_sspp_atomic_update(), right before the
call to _dpu_plane_set_scanout() -> dpu_format_populate_layout().

Drop plane_addr comparison against previous layout and corresponding
EAGAIN handling.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 +---
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index d95540309d4d..ec1001e10f4f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -918,8 +918,7 @@ int dpu_format_populate_layout(
struct drm_framebuffer *fb,
struct dpu_hw_fmt_layout *layout)
 {
-   uint32_t plane_addr[DPU_MAX_PLANES];
-   int i, ret;
+   int ret;
 
if (!fb || !layout) {
DRM_ERROR("invalid arguments\n");
@@ -940,9 +939,6 @@ int dpu_format_populate_layout(
if (ret)
return ret;
 
-   for (i = 0; i < DPU_MAX_PLANES; ++i)
-   plane_addr[i] = layout->plane_addr[i];
-
/* Populate the addresses given the fb */
if (DPU_FORMAT_IS_UBWC(layout->format) ||
DPU_FORMAT_IS_TILE(layout->format))
@@ -950,10 +946,6 @@ int dpu_format_populate_layout(
else
ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
 
-   /* check if anything changed */
-   if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
-   ret = -EAGAIN;
-
return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 2b0ebdd4c207..d6518ef1beb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,9 +476,7 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
int ret;
 
ret = dpu_format_populate_layout(aspace, fb, _cfg->layout);
-   if (ret == -EAGAIN)
-   DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
-   else if (ret)
+   if (ret)
DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
-- 
2.39.2



[PATCH v5 13/32] drm/msm/dpu: rename dpu_hw_sspp_cfg to dpu_sw_pipe_cfg

2023-03-09 Thread Dmitry Baryshkov
As struct dpu_hw_sspp_cfg describes only the source and destination
rectangles, it is a software pipe configuration now. Rename it
accordingly.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index e87c6377f315..6e5b62f3276f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -447,7 +447,7 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp 
*ctx)
  * dpu_hw_sspp_setup_rects()
  */
 static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg)
+   struct dpu_sw_pipe_cfg *cfg)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 100d8e06c90d..e73d6ac863ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -153,12 +153,12 @@ struct dpu_hw_pixel_ext {
 };
 
 /**
- * struct dpu_hw_sspp_cfg : SSPP configuration
+ * struct dpu_sw_pipe_cfg : software pipe configuration
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
  */
-struct dpu_hw_sspp_cfg {
+struct dpu_sw_pipe_cfg {
struct drm_rect src_rect;
struct drm_rect dst_rect;
 };
@@ -228,7 +228,7 @@ struct dpu_hw_sspp_ops {
 * @cfg: Pointer to pipe config structure
 */
void (*setup_rects)(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg);
+   struct dpu_sw_pipe_cfg *cfg);
 
/**
 * setup_pe - setup pipe pixel extension
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4ae70d21c37a..ce01a602cbc9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -136,7 +136,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane 
*plane)
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
struct drm_framebuffer *fb,
-   struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
@@ -191,7 +191,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_hw_sspp_cfg *pipe_cfg)
+static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
@@ -275,7 +275,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct drm_framebuffer *fb, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -421,7 +421,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-   struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct drm_crtc *crtc, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct 
dpu_plane *pdpu, cons
 
 static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, bool color_fill,
-   struct dpu_hw_sspp_cfg *pipe_cfg,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
unsigned int rotation)
 {
struct dpu_hw_sspp *pipe_hw = pipe->sspp;
@@ -694,7 +694,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
const struct dpu_format *fmt;
const struct drm_plane *plane = >base;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   struct dpu_hw_sspp_cfg pipe_cfg;
+   struct dpu_sw_pipe_cfg pipe_cfg;
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -1130,9 +1130,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
bool is_rt_pipe;
   

[PATCH v5 08/32] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks

2023-03-09 Thread Dmitry Baryshkov
Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_sspp and
multirect_index/_mode arguments.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 73 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 84 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 3e65bfd65b62..a1492a7e43ce 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
-   enum dpu_sspp_multirect_index index,
-   enum dpu_sspp_multirect_mode mode)
+static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
u32 mode_mask;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
return;
 
-   if (index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
/**
 * if rect index is RECT_SOLO, we cannot expect a
 * virtual plane sharing the same SSPP id. So we go
@@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp 
*ctx,
mode_mask = 0;
} else {
mode_mask = DPU_REG_READ(>hw, SSPP_MULTIRECT_OPMODE + idx);
-   mode_mask |= index;
-   if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
+   mode_mask |= pipe->multirect_index;
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
mode_mask |= BIT(2);
else
mode_mask &= ~BIT(2);
@@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
-   const struct dpu_format *fmt, u32 flags,
-   enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, u32 flags)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 chroma_samp, unpack, src_format;
u32 opmode = 0;
@@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp 
*ctx,
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ) || !fmt)
return;
 
-   if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
op_mode_off = SSPP_SRC_OP_MODE;
unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
format_off = SSPP_SRC_FORMAT;
@@ -447,10 +447,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct 
dpu_hw_sspp *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *cfg,
-   enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+   struct dpu_hw_sspp_cfg *cfg)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
@@ -461,7 +461,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
 
c = >hw;
 
-   if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
src_size_off = SSPP_SRC_SIZE;
src_xy_off = SSPP_SRC_XY;
out_size_off = SSPP_OUT_SIZE;
@@ -482,7 +483,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
dst_size = (drm_rect_height(>dst_rect) << 16) |
drm_rect_width(>dst_rect);
 
-   if (rect_index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
ystride0 = (cfg->layout.plane_pitch[0]) |
(cfg->layout.plane_pitch[1] << 16);
ystride1 = (cfg->layout.plane_pitch[2]) |
@@ -491,7 +492,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
 
-   if (rect_index == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 

[PATCH v5 10/32] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill

2023-03-09 Thread Dmitry Baryshkov
Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
not be sure that the previous address is still valid.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 3030cd3b253a..0a43c5682b2b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
+   struct dpu_hw_sspp_cfg cfg;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
return;
 
+   /* cleanup source addresses */
+   memset(, 0, sizeof(cfg));
+   ctx->ops.setup_sourceaddress(pipe, );
+
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
pipe->multirect_index == DPU_SSPP_RECT_0)
DPU_REG_WRITE(>hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
-- 
2.39.2



[PATCH v5 11/32] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress

2023-03-09 Thread Dmitry Baryshkov
Move stride programming to dpu_hw_sspp_setup_sourceaddress(), so that
dpu_hw_sspp_setup_rects() programs only source and destination
rectangles.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 57 +++--
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 0a43c5682b2b..ab95f2817378 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
-   u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
+   u32 src_size, src_xy, dst_size, dst_xy;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
u32 idx;
 
@@ -482,44 +482,18 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
dst_size = (drm_rect_height(>dst_rect) << 16) |
drm_rect_width(>dst_rect);
 
-   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
-   } else {
-   ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
-   ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
-
-   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
-   ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
-   ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
-   } else {
-   ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
-0x);
-   ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
-0x);
-   }
-   }
-
/* rectangle register programming */
DPU_REG_WRITE(c, src_size_off + idx, src_size);
DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
DPU_REG_WRITE(c, out_size_off + idx, dst_size);
DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
-
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
struct dpu_hw_sspp_cfg *cfg)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
+   u32 ystride0, ystride1;
int i;
u32 idx;
 
@@ -541,6 +515,33 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
DPU_REG_WRITE(>hw, SSPP_SRC3_ADDR + idx,
cfg->layout.plane_addr[2]);
}
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+   ystride0 = (cfg->layout.plane_pitch[0]) |
+   (cfg->layout.plane_pitch[1] << 16);
+   ystride1 = (cfg->layout.plane_pitch[2]) |
+   (cfg->layout.plane_pitch[3] << 16);
+   } else {
+   ystride0 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE0 + idx);
+   ystride1 = DPU_REG_READ(>hw, SSPP_SRC_YSTRIDE1 + idx);
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+   ystride0 = (ystride0 & 0x) |
+   (cfg->layout.plane_pitch[0] & 0x);
+   ystride1 = (ystride1 & 0x)|
+   (cfg->layout.plane_pitch[2] & 0x);
+   } else {
+   ystride0 = (ystride0 & 0x) |
+   ((cfg->layout.plane_pitch[0] << 16) &
+0x);
+   ystride1 = (ystride1 & 0x) |
+   ((cfg->layout.plane_pitch[2] << 16) &
+0x);
+   }
+   }
+
+   DPU_REG_WRITE(>hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
+   DPU_REG_WRITE(>hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
-- 
2.39.2



[PATCH v5 06/32] drm/msm/dpu: drop dpu_plane_pipe function

2023-03-09 Thread Dmitry Baryshkov
There no more need for the dpu_plane_pipe() function, crtc code can
access pstate->pipe_hw.idx directly.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 7 ---
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f29a339a3705..eff1a3cc1cec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = dpu_plane_pipe(plane);
+   sspp_idx = pstate->hw_sspp->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1202,7 +1202,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = dpu_plane_pipe(plane);
+   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 546629232e3d..10678f6502a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1442,11 +1442,6 @@ static const struct drm_plane_helper_funcs 
dpu_plane_helper_funcs = {
.atomic_update = dpu_plane_atomic_update,
 };
 
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
-{
-   return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
uint32_t pipe, enum drm_plane_type type,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 08a4b6a99f51..25e261cabadc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,13 +59,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
-- 
2.39.2



[PATCH v5 05/32] drm/msm/dpu: move pipe_hw to dpu_plane_state

2023-03-09 Thread Dmitry Baryshkov
In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (variable, changes during runtime) rather
than part of a plane (ideally should be statically allocated during boot).

The sspp pointer is set at the dpu_plane_reset(), since this is the
function which allocates the state. Once we have fully virtual
plane<->SSPP relationship, the SSPP will be allocated dynamically in the
dpu_plane_atomic_check() function.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 107 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 2 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d6518ef1beb2..546629232e3d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
 
enum dpu_sspp pipe;
 
-   struct dpu_hw_sspp *pipe_hw;
uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
struct drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
@@ -310,7 +310,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
fmt ? (char *)>base.pixel_format : NULL,
pdpu->is_rt_pipe, total_fl, qos_lut);
 
-   pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+   pstate->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
 }
 
 /**
@@ -322,6 +322,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
struct drm_framebuffer *fb)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u32 danger_lut, safe_lut;
 
@@ -361,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
danger_lut,
safe_lut);
 
-   pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+   pstate->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
danger_lut, safe_lut);
 }
 
@@ -375,14 +376,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
bool enable, u32 flags)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-   pipe_qos_cfg.creq_vblank = 
pdpu->pipe_hw->cap->sblk->creq_vblank;
+   pipe_qos_cfg.creq_vblank = 
pstate->hw_sspp->cap->sblk->creq_vblank;
pipe_qos_cfg.danger_vblank =
-   pdpu->pipe_hw->cap->sblk->danger_vblank;
+   pstate->hw_sspp->cap->sblk->danger_vblank;
pipe_qos_cfg.vblank_en = enable;
}
 
@@ -408,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
pipe_qos_cfg.danger_vblank,
pdpu->is_rt_pipe);
 
-   pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+   pstate->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
_qos_cfg);
 }
 
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane 
*plane,
struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_vbif_set_ot_params ot_params;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
memset(_params, 0, sizeof(ot_params));
-   ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-   ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+   ot_params.xin_id = pstate->hw_sspp->cap->xin_id;
+   ot_params.num = pstate->hw_sspp->idx - SSPP_NONE;
ot_params.width = drm_rect_width(_cfg->src_rect);
ot_params.height = drm_rect_height(_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
ot_params.frame_rate = drm_mode_vrefresh(>mode);
ot_params.vbif_idx = VBIF_RT;
-   ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+   ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
ot_params.rd = true;
 
dpu_vbif_set_ot_limit(dpu_kms, _params);
@@ -446,14 +449,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane 
*plane,
 static void 

[PATCH v5 01/32] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)

2023-03-09 Thread Dmitry Baryshkov
For all hardware blocks except SSPP the corresponding struct is named
after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
change.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 49 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 53 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 
 3 files changed, 62 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 4246ab0b3bee..3e65bfd65b62 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -136,7 +136,7 @@
 #define TS_CLK 1920
 
 
-static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
+static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
int s_id,
u32 *idx)
 {
@@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
enum dpu_sspp_multirect_index index,
enum dpu_sspp_multirect_mode mode)
 {
@@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(>hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
 }
 
-static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(>hw, SSPP_VIG_OP_MODE + idx, opmode);
 }
 
-static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -239,7 +239,7 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
const struct dpu_format *fmt, u32 flags,
enum dpu_sspp_multirect_index rect_mode)
 {
@@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
 }
 
-static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
struct dpu_hw_pixel_ext *pe_ext)
 {
struct dpu_hw_blk_reg_map *c;
@@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe 
*ctx,
tot_req_pixels[3]);
 }
 
-static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *sspp,
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *sspp,
void *scaler_cfg)
 {
u32 idx;
@@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe 
*ctx,
sspp->layout.format);
 }
 
-static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
+static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 {
u32 idx;
 
@@ -447,8 +447,8 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe 
*ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *cfg,
+static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *cfg,
enum dpu_sspp_multirect_index rect_index)
 {
struct dpu_hw_blk_reg_map *c;
@@ -516,8 +516,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *cfg,
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *cfg,
enum dpu_sspp_multirect_index rect_mode)
 {
int i;
@@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_hw_pipe *ctx,
}
 }
 
-static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
const struct dpu_csc_cfg *data)
 {
u32 idx;
@@ -560,7 +560,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
dpu_hw_csc_setup(>hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, 
enum
+static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, 
enum
dpu_sspp_multirect_index rect_index)
 {
u32 

[PATCH v5 03/32] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c

2023-03-09 Thread Dmitry Baryshkov
As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
SSPP debugfs creation from dpu_plane to dpu_kms. We are going to break
the 1:1 correspondence between planes and SSPPs, so it makes no sense
anymore to create SSPP debugfs entries in dpu_plane.c

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index bbff908e6dbe..c30f168b6c0a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,7 +388,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
  struct dentry *entry);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index a683bd9b5a04..0d2ef83c38ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t 
mode,
debugfs_create_file(name, mode, parent, regset, _regset32_fops);
 }
 
+static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
+{
+   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
+   int i;
+
+   if (IS_ERR(entry))
+   return;
+
+   for (i = SSPP_NONE; i < SSPP_MAX; i++) {
+   struct dpu_hw_sspp *hw = dpu_rm_get_sspp(_kms->rm, i);
+
+   if (!hw)
+   continue;
+
+   _dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
+   }
+}
+
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
 {
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b054055f120b..2b0ebdd4c207 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1399,22 +1399,6 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane 
*plane, bool enable)
_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
pm_runtime_put_sync(_kms->pdev->dev);
 }
-
-/* SSPP live inside dpu_plane private data only. Enumerate them here. */
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
-{
-   struct drm_plane *plane;
-   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
-
-   if (IS_ERR(entry))
-   return;
-
-   drm_for_each_plane(plane, dpu_kms->dev) {
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-   _dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
-   }
-}
 #endif
 
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
-- 
2.39.2



[PATCH v5 02/32] drm/msm/dpu: move SSPP allocation to the RM

2023-03-09 Thread Dmitry Baryshkov
Follow the example of all other hw blocks and initialize SSPP blocks in
Resource Manager.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 22 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 12 
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5a4578ab62a6..b054055f120b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1275,8 +1275,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
/* this will destroy the states as well */
drm_plane_cleanup(plane);
 
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
kfree(pdpu);
}
 }
@@ -1482,14 +1480,10 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pdpu->pipe = pipe;
 
/* initialize underlying h/w driver */
-   pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
-   if (IS_ERR(pdpu->pipe_hw)) {
-   DPU_ERROR("[%u]SSPP init failed\n", pipe);
-   ret = PTR_ERR(pdpu->pipe_hw);
+   pdpu->pipe_hw = dpu_rm_get_sspp(>rm, pipe);
+   if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) 
{
+   DPU_ERROR("[%u]SSPP is invalid\n", pipe);
goto clean_plane;
-   } else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
-   DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-   goto clean_sspp;
}
 
format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1499,7 +1493,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
format_list, num_formats,
supported_format_modifiers, type, NULL);
if (ret)
-   goto clean_sspp;
+   goto clean_plane;
 
pdpu->catalog = kms->catalog;
 
@@ -1532,9 +1526,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pipe, plane->base.id);
return plane;
 
-clean_sspp:
-   if (pdpu && pdpu->pipe_hw)
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
 clean_plane:
kfree(pdpu);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 396429e63756..53c644ca52ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -8,6 +8,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_pingpong.h"
+#include "dpu_hw_sspp.h"
 #include "dpu_hw_intf.h"
 #include "dpu_hw_wb.h"
 #include "dpu_hw_dspp.h"
@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]);
 
+   for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
+   dpu_hw_sspp_destroy(rm->hw_sspp[i]);
+
return 0;
 }
 
@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->dsc_blks[dsc->id - DSC_0] = >base;
}
 
+   for (i = 0; i < cat->sspp_count; i++) {
+   struct dpu_hw_sspp *hw;
+   const struct dpu_sspp_cfg *sspp = >sspp[i];
+
+   if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
+   DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
+   continue;
+   }
+
+   hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+   if (IS_ERR(hw)) {
+   rc = PTR_ERR(hw);
+   DPU_ERROR("failed sspp object creation: err %d\n", rc);
+   goto fail;
+   }
+   rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+   }
+
return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 59de72b381f9..d62c2edb2460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -21,6 +21,7 @@ struct dpu_global_state;
  * @hw_intf: array of intf hardware resources
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
  */
 struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -31,6 +32,7 @@ struct dpu_rm {
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+   struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
 };
 
 /**
@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct 
dpu_rm *rm, enum dpu_wb wb_
return rm->hw_wb[wb_idx - WB_0];
 }
 
+/**
+ * dpu_rm_get_sspp - Return a 

[PATCH v5 00/32] drm/msm/dpu: wide planes support

2023-03-09 Thread Dmitry Baryshkov
This patchset brings in multirect usage to support using two SSPP
rectangles for a single plane. Full virtual planes support is omitted
from this pull request, it will come later.

Changes since v4:
- Incorporate two fixes and two cleanup patches from Abhinav

Changes since v3:

- moved if (!pipe->sspp) checks back to the calling site, the caller
  should know if there is a backing SSPP or not.
- Restored state_idx argument of trace_dpu_crtc_setup_mixer trace point
- Removed .smart_dma_rev from dpu_caps
- Added cleaning of multirect to _dpu_plane_atomic_disable()
- Per Abhinavs request split the SmartDMA enablement patch into the
  "verified by me" and "the rest of the platforms" patches, which is not
  supposed to be merged in. Users of other platforms are supposed to
  verify multirect support on their platforms and then send patches
  enabling SmartDMA for their SoC.
- Expanded several commit messages

Changes since v2:

- Renamed dpu_hw_pipe_cfg to dpu_hw_sspp_cfg
- Added a patch to clean up src add / layout for the solid fill planes
- Fixed several comments and commit messages which caused confusion
- Added documentation for new dpu_plane_state members
- Slightly reworked dpu_plane_atomic_check() to make it more logical and 
obvious.

Changes since v1 (which was ages ago):
- Rebased on top of 6.2-rc1
- Dropped the controversial _dpu_crtc_blend_setup() split patch
- Renamed dpu_hw_pipe to dpu_hw_sspp
- Other misc changes

Abhinav Kumar (2):
  drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe
  drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function

Dmitry Baryshkov (30):
  drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  drm/msm/dpu: move SSPP allocation to the RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid
fill
  drm/msm/dpu: move stride programming to
dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
  drm/msm/dpu: rename dpu_hw_sspp_cfg to dpu_sw_pipe_cfg
  drm/msm/dpu: drop src_split and multirect check from
dpu_crtc_atomic_check
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: drop redundant plane dst check from
dpu_crtc_atomic_check()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
and dpu_format
  drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  drm/msm/dpu: add dpu_hw_sspp_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rework dpu_plane_atomic_check()
  drm/msm/dpu: rework plane CSC setting
  drm/msm/dpu: rework static color fill code
  drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  drm/msm/dpu: add support for wide planes
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: enable SmartDMA for the rest of the platforms
  drm/msm/dpu: drop smart_dma_rev from dpu_caps

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 290 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |  10 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  23 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 169 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   | 111 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  18 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 849 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  30 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c|  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  19 +-
 12 files changed, 711 insertions(+), 844 deletions(-)

-- 
2.39.2



[PATCH 2/4] drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function

2023-03-09 Thread Abhinav Kumar
After cleaning up the older multirect support the function
dpu_plane_validate_multirect_v2() is unused. Lets remove it.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 111 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   7 --
 2 files changed, 118 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9a03d1cad0ee..bafa1dd1748b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -707,117 +707,6 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
   fill_color, fmt);
 }
 
-int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-{
-   struct dpu_plane_state *pstate[R_MAX];
-   const struct drm_plane_state *drm_state[R_MAX];
-   struct drm_rect src[R_MAX], dst[R_MAX];
-   struct dpu_plane *dpu_plane[R_MAX];
-   const struct dpu_format *fmt[R_MAX];
-   int i, buffer_lines;
-   unsigned int max_tile_height = 1;
-   bool parallel_fetch_qualified = true;
-   bool has_tiled_rect = false;
-
-   for (i = 0; i < R_MAX; i++) {
-   const struct msm_format *msm_fmt;
-
-   drm_state[i] = i ? plane->r1 : plane->r0;
-   msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
-   fmt[i] = to_dpu_format(msm_fmt);
-
-   if (DPU_FORMAT_IS_UBWC(fmt[i])) {
-   has_tiled_rect = true;
-   if (fmt[i]->tile_height > max_tile_height)
-   max_tile_height = fmt[i]->tile_height;
-   }
-   }
-
-   for (i = 0; i < R_MAX; i++) {
-   int width_threshold;
-
-   pstate[i] = to_dpu_plane_state(drm_state[i]);
-   dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
-
-   if (pstate[i] == NULL) {
-   DPU_ERROR("DPU plane state of plane id %d is NULL\n",
-   drm_state[i]->plane->base.id);
-   return -EINVAL;
-   }
-
-   src[i].x1 = drm_state[i]->src_x >> 16;
-   src[i].y1 = drm_state[i]->src_y >> 16;
-   src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
-   src[i].y2 = src[i].y1 + (drm_state[i]->src_h >> 16);
-
-   dst[i] = drm_plane_state_dest(drm_state[i]);
-
-   if (drm_rect_calc_hscale([i], [i], 1, 1) != 1 ||
-   drm_rect_calc_vscale([i], [i], 1, 1) != 1) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "scaling is not supported in multirect mode\n");
-   return -EINVAL;
-   }
-
-   if (DPU_FORMAT_IS_YUV(fmt[i])) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "Unsupported format for multirect mode\n");
-   return -EINVAL;
-   }
-
-   /**
-* SSPP PD_MEM is split half - one for each RECT.
-* Tiled formats need 5 lines of buffering while fetching
-* whereas linear formats need only 2 lines.
-* So we cannot support more than half of the supported SSPP
-* width for tiled formats.
-*/
-   width_threshold = dpu_plane[i]->catalog->caps->max_linewidth;
-   if (has_tiled_rect)
-   width_threshold /= 2;
-
-   if (parallel_fetch_qualified &&
-   drm_rect_width([i]) > width_threshold)
-   parallel_fetch_qualified = false;
-
-   }
-
-   /* Validate RECT's and set the mode */
-
-   /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
-   if (parallel_fetch_qualified) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-
-   goto done;
-   }
-
-   /* TIME_MX Mode */
-   buffer_lines = 2 * max_tile_height;
-
-   if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
-   dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   } else {
-   DPU_ERROR(
-   "No multirect mode possible for the planes (%d - %d)\n",
-   drm_state[R0]->plane->base.id,
-   drm_state[R1]->plane->base.id);
-   return -EINVAL;
-   }
-
-done:
-   pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
-   pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
-
-   DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
-   pstate[R0]->pipe.multirect_mode, 
pstate[R0]->pipe.multirect_index);
-   

[PATCH 3/4] drm/msm/dpu: call _dpu_crtc_blend_setup_pipe for r_pipe

2023-03-09 Thread Abhinav Kumar
_dpu_crtc_blend_setup_mixer() should call _dpu_crtc_blend_setup_pipe()
to stage the rectangles of the sspp for both the left and right
halves.

However, it incorrectly invokes it only for the left half causing
basic wide planes to not work and only half the screen is shown
on the display.

This was validated using a 2560x1440 DP monitor on sc7280 as
the max_linewidth is 2400 on sc7280.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 03034ec8ed1b..b748c4f17c90 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -486,7 +486,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
   mixer, cstate->num_mixers,
   pstate->stage,
   format, fb ? fb->modifier : 
0,
-  >pipe, 1, stage_cfg);
+  >r_pipe, 1, 
stage_cfg);
}
 
/* blend config update */
-- 
2.7.4



[PATCH 4/4] drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe

2023-03-09 Thread Abhinav Kumar
Lets print the multirect_index as well in _dpu_crtc_blend_setup_pipe()
as it will give the complete information of the sw_pipe as well.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b748c4f17c90..96ffea069120 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -425,12 +425,13 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
   format->base.pixel_format,
   modifier);
 
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d 
multirect_idx %d\n",
 crtc->base.id,
 stage,
 plane->base.id,
 sspp_idx - SSPP_NONE,
-state->fb ? state->fb->base.id : -1);
+state->fb ? state->fb->base.id : -1,
+pipe->multirect_index);
 
stage_cfg->stage[stage][stage_idx] = sspp_idx;
stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
-- 
2.7.4



[PATCH 1/4] drm/msm/dpu: avoid checking uninitialized plane format

2023-03-09 Thread Abhinav Kumar
dpu_plane_atomic_check() checks for the format to make sure its
not YUV before using multirect.

However the format is not initialized before this. This causes
a compilation issue and also would not work if YUV content
is tried.

Fix it by setting the format before the check.

Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 06fbe5ef7ff2..9a03d1cad0ee 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1027,6 +1027,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
+   fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
if (drm_rect_width(_cfg->src_rect) > max_linewidth) {
/* struct dpu_crtc_state *cstate = 
to_dpu_crtc_state(crtc_state); */
 
@@ -1067,8 +1069,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
}
 
-   fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
-
ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
if (ret)
return ret;
-- 
2.7.4



[PATCH 0/4] drm/msm/dpu: wide planes fixes

2023-03-09 Thread Abhinav Kumar
While validating the DPU wide planes series [1], some issues were seen
so decided to send this out in a separate series.

Changes include compilation fixes, critical bug fixes and cleanups.

These can easily be absorbed into that series as well but for the sake
of having a clean series and also to have a placeholder to push anymore
fixes/cleanups while I continue to validate , sending this out separately.

With this, wide planes works on basic homescreen and some of the testing
done on sc7280. While I continue the validation and find more issues, will
continue sending out more revisions to this series.

[1]: https://patchwork.freedesktop.org/series/99909/

Abhinav Kumar (4):
  drm/msm/dpu: avoid checking uninitialized plane format
  drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function
  drm/msm/dpu: call _dpu_crtc_blend_setup_pipe for r_pipe
  drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |   7 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 115 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   7 --
 3 files changed, 6 insertions(+), 123 deletions(-)

-- 
2.7.4



[PATCH RESEND] drm/armada: Fill in GEM object for each color plane

2023-03-09 Thread Doug Brown
This driver uses a single GEM object even when there are multiple
planes. Starting with commit 746b9c62cc86 ("drm/gem: Ignore color planes
that are unused by framebuffer format"), multiple plane support was
broken on armada because the object pointers for the additional planes
were empty and drm_gem_plane_helper_prepare_fb was returning -EINVAL.

Restore functionality by pointing to the same GEM object on all planes.

Signed-off-by: Doug Brown 
---
 drivers/gpu/drm/armada/armada_fb.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_fb.c 
b/drivers/gpu/drm/armada/armada_fb.c
index b87c71703c85..341ad4d422de 100644
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ b/drivers/gpu/drm/armada/armada_fb.c
@@ -21,9 +21,10 @@ static const struct drm_framebuffer_funcs armada_fb_funcs = {
 struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
const struct drm_mode_fb_cmd2 *mode, struct armada_gem_object *obj)
 {
+   const struct drm_format_info *info = drm_get_format_info(dev, mode);
struct armada_framebuffer *dfb;
uint8_t format, config;
-   int ret;
+   int ret, i;
 
switch (mode->pixel_format) {
 #define FMT(drm, fmt, mod) \
@@ -63,7 +64,8 @@ struct armada_framebuffer *armada_framebuffer_create(struct 
drm_device *dev,
 
dfb->fmt = format;
dfb->mod = config;
-   dfb->fb.obj[0] = >obj;
+   for (i = 0; i < info->num_planes; i++)
+   dfb->fb.obj[i] = >obj;
 
drm_helper_mode_fill_fb_struct(dev, >fb, mode);
 
@@ -79,7 +81,8 @@ struct armada_framebuffer *armada_framebuffer_create(struct 
drm_device *dev,
 * the above call, but the caller will drop their reference
 * to it.  Hence we need to take our own reference.
 */
-   drm_gem_object_get(>obj);
+   for (i = 0; i < info->num_planes; i++)
+   drm_gem_object_get(>obj);
 
return dfb;
 }
-- 
2.34.1



Re: [PATCH] drm/msm: Check for the GPU IOMMU during bind

2023-03-09 Thread Dmitry Baryshkov

On 10/03/2023 00:20, Jordan Crouse wrote:

While booting with amd,imageon on a headless target the GPU probe was
failing with -ENOSPC in get_pages() from msm_gem.c.

Investigation showed that the driver was using the default 16MB VRAM
carveout because msm_use_mmu() was returning false since headless devices
use a dummy parent device. Avoid this by extending the existing is_a2xx
priv member to check the GPU IOMMU state on all platforms and use that
check in msm_use_mmu().


I wonder if we can fix this by setting 'dummy_dev'->of_node to adreno's 
of_node. Did you check that possibility?




This works for memory allocations but it doesn't prevent the VRAM carveout
from being created because that happens before we have a chance to check
the GPU IOMMU state in adreno_bind.

There are a number of possible options to resolve this but none of them are
very clean. The easiest way is to likely specify vram=0 as module parameter
on headless devices so that the memory doesn't get wasted.

Signed-off-by: Jordan Crouse 
---

  drivers/gpu/drm/msm/adreno/adreno_device.c | 6 +-
  drivers/gpu/drm/msm/msm_drv.c  | 7 +++
  drivers/gpu/drm/msm/msm_drv.h  | 2 +-
  3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 36f062c7582f..4f19da28f80f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -539,7 +539,11 @@ static int adreno_bind(struct device *dev, struct device 
*master, void *data)
DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major,
config.rev.minor, config.rev.patchid);
  
-	priv->is_a2xx = config.rev.core == 2;

+   /*
+* A2xx has a built in IOMMU and all other IOMMU enabled targets will
+* have an ARM IOMMU attached
+*/
+   priv->has_gpu_iommu = config.rev.core == 2 || device_iommu_mapped(dev);
priv->has_cached_coherent = config.rev.core >= 6;
  
  	gpu = info->init(drm);

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index aca48c868c14..a125a351ec90 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -318,11 +318,10 @@ bool msm_use_mmu(struct drm_device *dev)
struct msm_drm_private *priv = dev->dev_private;
  
  	/*

-* a2xx comes with its own MMU
-* On other platforms IOMMU can be declared specified either for the
-* MDP/DPU device or for its parent, MDSS device.
+* Return true if the GPU or the MDP/DPU or parent MDSS device has an
+* IOMMU
 */
-   return priv->is_a2xx ||
+   return priv->has_gpu_iommu ||
device_iommu_mapped(dev->dev) ||
device_iommu_mapped(dev->dev->parent);


It is not a problem of you patch, of course, but this check now looks 
strange to me. We mix the GPU check and MDP/DPU checks. Consider msm8x60 
(a220, mdp4) and, for example, no system level MMU.



  }
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9f0c184b02a0..f33f94acd1b9 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -126,7 +126,7 @@ struct msm_drm_private {
struct msm_gpu *gpu;
  
  	/* gpu is only set on open(), but we need this info earlier */

-   bool is_a2xx;
+   bool has_gpu_iommu;
bool has_cached_coherent;
  
  	struct drm_fb_helper *fbdev;


--
With best wishes
Dmitry



Re: [PATCH v3 2/2] drm/panel: Add driver for Novatek NT36523

2023-03-09 Thread Konrad Dybcio


[...]
= of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
> + if (!dsi1) {
> + dev_err(dev, "cannot get secondary DSI node.\n");
> + return -ENODEV;
> + }
> +
> + dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
> + of_node_put(dsi1);
 Shouldn't you put the reference only if it's found?
>>> thanks for spot it.
Apparently not.. please don't change this

Konrad

> + if (!dsi1_host) {
> + dev_err(dev, "cannot get secondary DSI host\n");
> + return -EPROBE_DEFER;
 dev_err_probe, here and in neighbouring exit return paths?
>>> Acked.


 Konrad


Re: [PATCH v2] drm/format-helper: Make conversion_buf_size() support sub-byte pixel fmts

2023-03-09 Thread Maíra Canal

On 3/7/23 18:50, Javier Martinez Canillas wrote:

There are DRM fourcc formats that have pixels smaller than a byte, but the
conversion_buf_size() function assumes that pixels are a multiple of bytes
and use the struct drm_format_info .cpp field to calculate the dst_pitch.

Instead, calculate it by using the bits per pixel (bpp) and divide it by 8
to account for formats that have sub-byte pixels.

Signed-off-by: Javier Martinez Canillas 


Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal


---
Tested by making sure that the following command still succeeds:

./tools/testing/kunit/kunit.py run \
--kunitconfig=drivers/gpu/drm/tests/.kunitconfig

Changes in v2:
- Drop an unused variable, that was pointed out by the kernel robot.

  drivers/gpu/drm/tests/drm_format_helper_test.c | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 9536829c6e3a..84b5cc29c8fc 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -409,12 +409,15 @@ static size_t conversion_buf_size(u32 dst_format, 
unsigned int dst_pitch,
  const struct drm_rect *clip)
  {
const struct drm_format_info *dst_fi = drm_format_info(dst_format);
+   unsigned int bpp;
  
  	if (!dst_fi)

return -EINVAL;
  
-	if (!dst_pitch)

-   dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
+   if (!dst_pitch) {
+   bpp = drm_format_info_bpp(dst_fi, 0);
+   dst_pitch = DIV_ROUND_UP(drm_rect_width(clip) * bpp, 8);
+   }
  
  	return dst_pitch * drm_rect_height(clip);

  }


Re: [PATCH] drm/i915/mtl: Disable stolen memory backed FB for A0

2023-03-09 Thread Andi Shyti
Hi Nirmoy,

On Thu, Mar 09, 2023 at 05:49:05PM +0100, Nirmoy Das wrote:
> Stolen memory is not usable for MTL A0 stepping beyond
> certain access size and we have no control over userspace
> access size of /dev/fb which can be backed by stolen memory.
> So disable stolen memory backed fb by setting i915->dsm.usable_size
> to zero.
> 
> Cc: Matthew Auld 
> Cc: Andi Shyti 
> Cc: Daniele Ceraolo Spurio 
> Cc: Lucas De Marchi 
> 

Can you please remove this blank line from the tag space?

> Signed-off-by: Nirmoy Das 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> index d8e06e783e30..56ccfcbdbce1 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> @@ -535,6 +535,16 @@ static int i915_gem_init_stolen(struct 
> intel_memory_region *mem)
>   /* Basic memrange allocator for stolen space. */
>   drm_mm_init(>mm.stolen, 0, i915->dsm.usable_size);
>  
> + /*
> +  * Access to stolen lmem beyond certain size for MTL A0 stepping
> +  * would crash the machine. Disable stolen lmem for userspace access
> +  * by setting usable_size to zero.
> +  * hsdes: 22016134735

Please, remove this reference, as well.

With the above:

Reviewed-by: Andi Shyti 

Thanks,
Andi

> +  */
> + if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
> + IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
> + i915->dsm.usable_size = 0;
> +
>   return 0;
>  }
>  
> -- 
> 2.39.0


Re: [PATCH RFC 03/18] rust: drm: file: Add File abstraction

2023-03-09 Thread Asahi Lina
On 10/03/2023 06.16, Faith Ekstrand wrote:
> On Tue, 2023-03-07 at 23:25 +0900, Asahi Lina wrote:
>> A DRM File is the DRM counterpart to a kernel file structure,
>> representing an open DRM file descriptor. Add a Rust abstraction to
>> allow drivers to implement their own File types that implement the
>> DriverFile trait.
>>
>> Signed-off-by: Asahi Lina 
>> ---
>>  rust/bindings/bindings_helper.h |   1 +
>>  rust/kernel/drm/drv.rs  |   7 ++-
>>  rust/kernel/drm/file.rs | 113
>> 
>>  rust/kernel/drm/mod.rs  |   1 +
>>  4 files changed, 120 insertions(+), 2 deletions(-)
>>
>> diff --git a/rust/bindings/bindings_helper.h
>> b/rust/bindings/bindings_helper.h
>> index 2a999138c4ae..7d7828faf89c 100644
>> --- a/rust/bindings/bindings_helper.h
>> +++ b/rust/bindings/bindings_helper.h
>> @@ -8,6 +8,7 @@
>>  
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> diff --git a/rust/kernel/drm/drv.rs b/rust/kernel/drm/drv.rs
>> index 29a465515dc9..1dcb651e1417 100644
>> --- a/rust/kernel/drm/drv.rs
>> +++ b/rust/kernel/drm/drv.rs
>> @@ -144,6 +144,9 @@ pub trait Driver {
>>  /// Should be either `drm::gem::Object` or
>> `drm::gem::shmem::Object`.
>>  type Object: AllocImpl;
>>  
>> +    /// The type used to represent a DRM File (client)
>> +    type File: drm::file::DriverFile;
>> +
>>  /// Driver metadata
>>  const INFO: DriverInfo;
>>  
>> @@ -213,8 +216,8 @@ macro_rules! drm_device_register {
>>  impl Registration {
>>  const VTABLE: bindings::drm_driver = drm_legacy_fields! {
>>  load: None,
>> -    open: None, // TODO: File abstraction
>> -    postclose: None, // TODO: File abstraction
>> +    open: Some(drm::file::open_callback::),
>> +    postclose: Some(drm::file::postclose_callback::),
>>  lastclose: None,
>>  unload: None,
>>  release: None,
>> diff --git a/rust/kernel/drm/file.rs b/rust/kernel/drm/file.rs
>> new file mode 100644
>> index ..48751e93c38a
>> --- /dev/null
>> +++ b/rust/kernel/drm/file.rs
>> @@ -0,0 +1,113 @@
>> +// SPDX-License-Identifier: GPL-2.0 OR MIT
>> +
>> +//! DRM File objects.
>> +//!
>> +//! C header:
>> [`include/linux/drm/drm_file.h`](../../../../include/linux/drm/drm_fi
>> le.h)
>> +
>> +use crate::{bindings, drm, error::Result};
>> +use alloc::boxed::Box;
>> +use core::marker::PhantomData;
>> +use core::ops::Deref;
>> +
>> +/// Trait that must be implemented by DRM drivers to represent a DRM
>> File (a client instance).
>> +pub trait DriverFile {
>> +    /// The parent `Driver` implementation for this `DriverFile`.
>> +    type Driver: drm::drv::Driver;
>> +
>> +    /// Open a new file (called when a client opens the DRM device).
>> +    fn open(device: ::device::Device) ->
>> Result>;
>> +}
>> +
>> +/// An open DRM File.
>> +///
>> +/// # Invariants
>> +/// `raw` is a valid pointer to a `drm_file` struct.
>> +#[repr(transparent)]
>> +pub struct File {
>> +    raw: *mut bindings::drm_file,
>> +    _p: PhantomData,
>> +}
>> +
>> +pub(super) unsafe extern "C" fn open_callback(
>> +    raw_dev: *mut bindings::drm_device,
>> +    raw_file: *mut bindings::drm_file,
>> +) -> core::ffi::c_int {
>> +    let drm = core::mem::ManuallyDrop::new(unsafe {
>> drm::device::Device::from_raw(raw_dev) });
> 
> Maybe you can help educate me a bit here... This feels like a really
> sketchy pattern.  We're creating a Device from a pointer, an operation
> which inherently consumes a reference but then marking it ManuallyDrop
> so drm_device_put() never gets called.  It took me a while but I think
> I figured out what you're trying to do: Make it so all the Rust stuff
> works with Device, not drm_device but it still feels really wrong.  It
> works, it just feels like there's a lot of unsafe abstraction juggling
> happening here and I expect this operation is going to be pretty common
> in the Rust abstraction layer.

So I think this is going to be a pretty common pattern in this kind of
abstraction. The problem is that, of course, in C there is no
distinction between an owned reference and a borrowed one. Here we have
a borrowed reference to a struct drm_device, and we need to turn it into
a  (which is the Rust equivalent type). But for  to exist
we need a Device to exist in the first place, and Device normally
implies ownership of the underlying drm_device.

We could just acquire a reference here, but then we're needlessly
grabbing a ref only to drop it at the end of the function, which is
pointless when the caller is holding another reference for us while the
callback runs. And of course Rust likes to claim to offer zero-cost
abstractions, so it would be kind of sad to have to do that... ^^

Just doing drm::device::Device::from_raw(raw_dev) is a ticking time
bomb, because we haven't acquired a reference (which would normally be
required). If that Device ever gets dropped, we've messed up the
refcounting and stolen the 

Re: [PATCH] drm/meson: fix missing component unbind on bind errors

2023-03-09 Thread Martin Blumenstingl
Hi Johan,

thanks for your patch!

On Mon, Mar 6, 2023 at 11:35 AM Johan Hovold  wrote:
[...]
> @@ -325,23 +325,23 @@ static int meson_drv_bind_master(struct device *dev, 
> bool has_components)
>
> ret = meson_encoder_hdmi_init(priv);
I'm wondering if component_bind_all() can be moved further down.
Right now it's between meson_encoder_cvbs_init() and
meson_encoder_hdmi_init(). So it seems that encoders don't rely on
component registration.

Unfortunately I am also not familiar with this and I'm hoping that
Neil can comment on this.


Best regards,
Martin


Re: [PATCH] drm/meson: dw-hdmi: Fix devm_regulator_*get_enable*() conversion again

2023-03-09 Thread Martin Blumenstingl
On Thu, Mar 9, 2023 at 4:24 PM Marek Szyprowski
 wrote:
>
> devm_regulator_get_enable_optional() returns -ENODEV if requested
> optional regulator is not present. Adjust code for that, because in the
> 67d0a30128c9 I've incorrectly assumed that it also returns 0 when
> regulator is not present.
>
> Reported-by: Ricardo Cañuelo 
> Fixes: 67d0a30128c9 ("drm/meson: dw-hdmi: Fix devm_regulator_*get_enable*() 
> conversion")
> Signed-off-by: Marek Szyprowski 
Acked-by: Martin Blumenstingl 


[PATCH] drm/amd/display: use a more accurate check in dm_helpers_dp_read_dpcd()

2023-03-09 Thread Hamza Mahfooz
We should be checking if drm_dp_dpcd_read() returns the size that we are
asking it to read instead of just checking if it is greater than zero.
Also, we should WARN_ON() here since this condition is only ever met, if
there is an issue worth investigating. So, compare the return value of
drm_dp_dpcd_read() to size and WARN_ON() if they aren't equal.

Signed-off-by: Hamza Mahfooz 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 8d598b322e5b..ed2ed7b1d869 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -511,8 +511,8 @@ bool dm_helpers_dp_read_dpcd(
return false;
}
 
-   return drm_dp_dpcd_read(>dm_dp_aux.aux, address,
-   data, size) > 0;
+   return !WARN_ON(drm_dp_dpcd_read(>dm_dp_aux.aux, address,
+data, size) != size);
 }
 
 bool dm_helpers_dp_write_dpcd(
-- 
2.39.2



Re: [PATCH RFC 03/18] rust: drm: file: Add File abstraction

2023-03-09 Thread Faith Ekstrand
On Tue, 2023-03-07 at 23:25 +0900, Asahi Lina wrote:
> A DRM File is the DRM counterpart to a kernel file structure,
> representing an open DRM file descriptor. Add a Rust abstraction to
> allow drivers to implement their own File types that implement the
> DriverFile trait.
> 
> Signed-off-by: Asahi Lina 
> ---
>  rust/bindings/bindings_helper.h |   1 +
>  rust/kernel/drm/drv.rs  |   7 ++-
>  rust/kernel/drm/file.rs | 113
> 
>  rust/kernel/drm/mod.rs  |   1 +
>  4 files changed, 120 insertions(+), 2 deletions(-)
> 
> diff --git a/rust/bindings/bindings_helper.h
> b/rust/bindings/bindings_helper.h
> index 2a999138c4ae..7d7828faf89c 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -8,6 +8,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/rust/kernel/drm/drv.rs b/rust/kernel/drm/drv.rs
> index 29a465515dc9..1dcb651e1417 100644
> --- a/rust/kernel/drm/drv.rs
> +++ b/rust/kernel/drm/drv.rs
> @@ -144,6 +144,9 @@ pub trait Driver {
>  /// Should be either `drm::gem::Object` or
> `drm::gem::shmem::Object`.
>  type Object: AllocImpl;
>  
> +    /// The type used to represent a DRM File (client)
> +    type File: drm::file::DriverFile;
> +
>  /// Driver metadata
>  const INFO: DriverInfo;
>  
> @@ -213,8 +216,8 @@ macro_rules! drm_device_register {
>  impl Registration {
>  const VTABLE: bindings::drm_driver = drm_legacy_fields! {
>  load: None,
> -    open: None, // TODO: File abstraction
> -    postclose: None, // TODO: File abstraction
> +    open: Some(drm::file::open_callback::),
> +    postclose: Some(drm::file::postclose_callback::),
>  lastclose: None,
>  unload: None,
>  release: None,
> diff --git a/rust/kernel/drm/file.rs b/rust/kernel/drm/file.rs
> new file mode 100644
> index ..48751e93c38a
> --- /dev/null
> +++ b/rust/kernel/drm/file.rs
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +
> +//! DRM File objects.
> +//!
> +//! C header:
> [`include/linux/drm/drm_file.h`](../../../../include/linux/drm/drm_fi
> le.h)
> +
> +use crate::{bindings, drm, error::Result};
> +use alloc::boxed::Box;
> +use core::marker::PhantomData;
> +use core::ops::Deref;
> +
> +/// Trait that must be implemented by DRM drivers to represent a DRM
> File (a client instance).
> +pub trait DriverFile {
> +    /// The parent `Driver` implementation for this `DriverFile`.
> +    type Driver: drm::drv::Driver;
> +
> +    /// Open a new file (called when a client opens the DRM device).
> +    fn open(device: ::device::Device) ->
> Result>;
> +}
> +
> +/// An open DRM File.
> +///
> +/// # Invariants
> +/// `raw` is a valid pointer to a `drm_file` struct.
> +#[repr(transparent)]
> +pub struct File {
> +    raw: *mut bindings::drm_file,
> +    _p: PhantomData,
> +}
> +
> +pub(super) unsafe extern "C" fn open_callback(
> +    raw_dev: *mut bindings::drm_device,
> +    raw_file: *mut bindings::drm_file,
> +) -> core::ffi::c_int {
> +    let drm = core::mem::ManuallyDrop::new(unsafe {
> drm::device::Device::from_raw(raw_dev) });

Maybe you can help educate me a bit here... This feels like a really
sketchy pattern.  We're creating a Device from a pointer, an operation
which inherently consumes a reference but then marking it ManuallyDrop
so drm_device_put() never gets called.  It took me a while but I think
I figured out what you're trying to do: Make it so all the Rust stuff
works with Device, not drm_device but it still feels really wrong.  It
works, it just feels like there's a lot of unsafe abstraction juggling
happening here and I expect this operation is going to be pretty common
in the Rust abstraction layer.

Am I missing something?

~Faith


> +    // SAFETY: This reference won't escape this function
> +    let file = unsafe {  *raw_file };
> +
> +    let inner = match T::open() {
> +    Err(e) => {
> +    return e.to_kernel_errno();
> +    }
> +    Ok(i) => i,
> +    };
> +
> +    file.driver_priv = Box::into_raw(inner) as *mut _;
> +
> +    0
> +}
> +
> +pub(super) unsafe extern "C" fn postclose_callback(
> +    _dev: *mut bindings::drm_device,
> +    raw_file: *mut bindings::drm_file,
> +) {
> +    // SAFETY: This reference won't escape this function
> +    let file = unsafe { &*raw_file };
> +
> +    // Drop the DriverFile
> +    unsafe { Box::from_raw(file.driver_priv as *mut T) };
> +}
> +
> +impl File {
> +    // Not intended to be called externally, except via
> declare_drm_ioctls!()
> +    #[doc(hidden)]
> +    pub unsafe fn from_raw(raw_file: *mut bindings::drm_file) ->
> File {
> +    File {
> +    raw: raw_file,
> +    _p: PhantomData,
> +    }
> +    }
> +
> +    #[allow(dead_code)]
> +    /// Return the raw pointer to the underlying `drm_file`.
> +    pub(super) fn raw() -> *const bindings::drm_file {
> +    self.raw

[PATCH v8 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
Add the ability for the Mediatek DRM driver to control the bit depth register.
If the DTS indicates the device supports 10-bit overlays and the current format
has a fourcc of AR30, BA30, or RA30, we set the bit depth register to 10 bit.

The next patch in the series actually enables 10-bit overlays for MT8195
devices, but this current patch should be a no-op. This patch was tested by
simply running Chrome on an MT8195 and looking for regressions.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,7 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701   0x0040
+#define DISP_REG_OVL_CLRFMT_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n) 
+ 0x04)
@@ -61,6 +62,10 @@
0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
+#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
+#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
+#define OVL_CON_CLRFMT_8_BIT   0x00
+#define OVL_CON_CLRFMT_10_BIT  0x01
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
struct cmdq_pkt *cmdq_pkt
   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
+static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
+ struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
+   unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
+
+   if (!ovl->data->supports_clrfmt_ext)
+   return;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
+
+   if (format == DRM_FORMAT_RGBA1010102 ||
+   format == DRM_FORMAT_BGRA1010102 ||
+   format == DRM_FORMAT_ARGB2101010)
+   bit_depth = OVL_CON_CLRFMT_10_BIT;
+
+   reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
+
+   mtk_ddp_write(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_CLRFMT_EXT);
+}
+
 void mtk_ovl_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >cmdq_reg, ovl->regs, 
DISP_REG_OVL_PITCH_MSB(idx));
}
 
+   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v8 1/3] drm/mediatek: Refactor pixel format logic

2023-03-09 Thread Justin Green
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 mt8173_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   const u32 *formats;
+   size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data 
mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data 
mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data 
mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data 

[PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
Add the ability for the Mediatek DRM driver to control the bit depth register.
If the DTS indicates the device supports 10-bit overlays and the current format
has a fourcc of AR30, BA30, or RA30, we set the bit depth register to 10 bit.

The next patch in the series actually enables 10-bit overlays for MT8195
devices, but this current patch should be a no-op. This patch was tested by
simply running Chrome on an MT8195 and looking for regressions.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,7 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701   0x0040
+#define DISP_REG_OVL_CLRFMT_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n) 
+ 0x04)
@@ -61,6 +62,10 @@
0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
+#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
+#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
+#define OVL_CON_CLRFMT_8_BIT   0x00
+#define OVL_CON_CLRFMT_10_BIT  0x01
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
struct cmdq_pkt *cmdq_pkt
   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
+static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
+ struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
+   unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
+
+   if (!ovl->data->supports_clrfmt_ext)
+   return;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
+
+   if (format == DRM_FORMAT_RGBA1010102 ||
+   format == DRM_FORMAT_BGRA1010102 ||
+   format == DRM_FORMAT_ARGB2101010)
+   bit_depth = OVL_CON_CLRFMT_10_BIT;
+
+   reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
+
+   mtk_ddp_write(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_CLRFMT_EXT);
+}
+
 void mtk_ovl_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >cmdq_reg, ovl->regs, 
DISP_REG_OVL_PITCH_MSB(idx));
}
 
+   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
Hi Chun-Kuang,
Thanks for the review! This patch was tested like the previous one, by
running Chrome on an MT8195 and looking for regressions. I'll post a
new series with the updated patch descriptions.

Regards,
Justin

On Wed, Mar 8, 2023 at 6:34 PM Chun-Kuang Hu  wrote:
>
> Hi, Justin:
>
> Justin Green  於 2023年3月8日 週三 下午11:34寫道:
> >
> > Tested using "modetest -P" on an MT8195 device.
>
> I think you could not test this when only apply the first two patches
> of this series, so move the test information to the third patch. In
> this patch, you could describe more about what and why this patch
> does. The other modification looks good to me.
>
> Regards,
> Chun-Kuang.
>
> >
> > Signed-off-by: Justin Green 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
> >  1 file changed, 33 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 8743c8047dc9..a6255e847104 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -41,6 +41,7 @@
> >  #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
> >  #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
> >  #define DISP_REG_OVL_ADDR_MT2701   0x0040
> > +#define DISP_REG_OVL_CLRFMT_EXT0x02D0
> >  #define DISP_REG_OVL_ADDR_MT8173   0x0f40
> >  #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * 
> > (n))
> >  #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * 
> > (n) + 0x04)
> > @@ -61,6 +62,10 @@
> > 0 : OVL_CON_CLRFMT_RGB)
> >  #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
> > OVL_CON_CLRFMT_RGB : 0)
> > +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
> > +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
> > +#define OVL_CON_CLRFMT_8_BIT   0x00
> > +#define OVL_CON_CLRFMT_10_BIT  0x01
> >  #defineOVL_CON_AEN BIT(8)
> >  #defineOVL_CON_ALPHA   0xff
> >  #defineOVL_CON_VIRT_FLIP   BIT(9)
> > @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
> > bool supports_afbc;
> > const u32 *formats;
> > size_t num_formats;
> > +   bool supports_clrfmt_ext;
> >  };
> >
> >  /*
> > @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
> > struct cmdq_pkt *cmdq_pkt
> >DISP_REG_OVL_DATAPATH_CON, 
> > OVL_LAYER_AFBC_EN(idx));
> >  }
> >
> > +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
> > + struct cmdq_pkt *cmdq_pkt)
> > +{
> > +   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> > +   unsigned int reg;
> > +   unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
> > +
> > +   if (!ovl->data->supports_clrfmt_ext)
> > +   return;
> > +
> > +   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
> > +   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
> > +
> > +   if (format == DRM_FORMAT_RGBA1010102 ||
> > +   format == DRM_FORMAT_BGRA1010102 ||
> > +   format == DRM_FORMAT_ARGB2101010)
> > +   bit_depth = OVL_CON_CLRFMT_10_BIT;
> > +
> > +   reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
> > +
> > +   mtk_ddp_write(cmdq_pkt, reg, >cmdq_reg,
> > + ovl->regs, DISP_REG_OVL_CLRFMT_EXT);
> > +}
> > +
> >  void mtk_ovl_config(struct device *dev, unsigned int w,
> > unsigned int h, unsigned int vrefresh,
> > unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> > @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct 
> > mtk_disp_ovl *ovl, unsigned int fmt)
> > return OVL_CON_CLRFMT_ARGB;
> > case DRM_FORMAT_BGRX:
> > case DRM_FORMAT_BGRA:
> > +   case DRM_FORMAT_BGRA1010102:
> > return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
> > case DRM_FORMAT_XRGB:
> > case DRM_FORMAT_ARGB:
> > +   case DRM_FORMAT_ARGB2101010:
> > return OVL_CON_CLRFMT_RGBA;
> > case DRM_FORMAT_XBGR:
> > case DRM_FORMAT_ABGR:
> > @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
> > int idx,
> >   >cmdq_reg, ovl->regs, 
> > DISP_REG_OVL_PITCH_MSB(idx));
> > }
> >
> > +   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
> > mtk_ovl_layer_on(dev, idx, cmdq_pkt);
> >  }
> >
> > --
> > 2.39.1.456.gfc5497dd1b-goog
> >


[PATCH v8 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195

2023-03-09 Thread Justin Green
Modify the overlay driver data for MT8195 to enable bit depth control and
enable support for AR30 and BA30 framebuffer formats. This patch in
combination with the previous two patches in the series will allow MT8195
devices to scanout AR30 and BA30 framebuffers.

Tested using "modetest -P" on an MT8195 device. The test pattern displays
correctly for both AR30 and BA30 formats.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a6255e847104..7d26f7055751 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = {
DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
-   .formats = mt8173_formats,
-   .num_formats = ARRAY_SIZE(mt8173_formats),
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
+   .supports_clrfmt_ext = true,
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v8 0/3] drm/mediatek: Add support for 10-bit overlays

2023-03-09 Thread Justin Green
This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
lay the groundwork for supporting more 10-bit formats on more devices.

1. Refactor plane initialization logic to allow individual DDP components to
provide their supported pixel formats.

2. Add AR30 and BA30 support to overlay driver.

3. Enable AR30 and BA30 overlays on MT8195.


Version history:
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.
v7:
 * Gate setting OVL_CLRFMT_EXT register on compatibility.
 * Split patches for adding 10-bit support and enabling 10-bit support on
   MT8195.
v8:
 * Updated descriptions for patches 2 and 3 in the series.


Justin Green (3):
  drm/mediatek: Refactor pixel format logic
  drm/mediatek: Add support for AR30 and BA30 overlays
  drm/mediatek: Enable AR30 and BA30 overlays on MT8195

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 173 insertions(+), 18 deletions(-)

-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH RFC 01/18] rust: drm: ioctl: Add DRM ioctl abstraction

2023-03-09 Thread Karol Herbst
On Thu, Mar 9, 2023 at 9:24 PM Faith Ekstrand
 wrote:
>
> On Thu, 2023-03-09 at 15:04 +0900, Asahi Lina wrote:
> > On 08/03/2023 02.34, Björn Roy Baron wrote:
> > > > +// SAFETY: This is just the ioctl
> > > > argument, which hopefully has the right type
> > > > +// (we've done our best checking the
> > > > size).
> > >
> > > In the rust tree there is the ReadableFromBytes [1] trait which
> > > indicates that it is safe to read arbitrary bytes into the type.
> > > Maybe you could add it as bound on the argument type when it lands
> > > in rust-next? This way you can't end up with for example a struct
> > > containing a bool with the byte value 2, which is UB.
> >
> > There's actually a much bigger story here, because that trait isn't
> > really very useful without a way to auto-derive it. I need the same
> > kind
> > of guarantee for all the GPU firmware structs...
> >
> > There's one using only declarative macros [1] and one using proc
> > macros
> > [2]. And then, since ioctl arguments are declared in C UAPI header
> > files, we need a way to be able to derive those traits for them...
> > which
> > I guess means bindgen changes?
>
> It'd be cool to be able to auto-verify that uAPI structs are all
> tightly packed and use the right subset of types.  Maybe not possible
> this iteration but it'd be cool to see in future.  I'd like to see it
> for C as well, ideally.
>
> ~Faith
>

I'm sure that with a macro you could verify that a struct definition
doesn't contain any gaps, just not sure on how one would enforce that.
Could add a trait which can only be implemented through a proc_macro?
Maybe we can have a proc_macro ensuring no gaps? Would be cool tech to
have indeed.



Re: [PATCH RFC 01/18] rust: drm: ioctl: Add DRM ioctl abstraction

2023-03-09 Thread Faith Ekstrand
On Thu, 2023-03-09 at 15:04 +0900, Asahi Lina wrote:
> On 08/03/2023 02.34, Björn Roy Baron wrote:
> > > +    // SAFETY: This is just the ioctl
> > > argument, which hopefully has the right type
> > > +    // (we've done our best checking the
> > > size).
> > 
> > In the rust tree there is the ReadableFromBytes [1] trait which
> > indicates that it is safe to read arbitrary bytes into the type.
> > Maybe you could add it as bound on the argument type when it lands
> > in rust-next? This way you can't end up with for example a struct
> > containing a bool with the byte value 2, which is UB.
> 
> There's actually a much bigger story here, because that trait isn't
> really very useful without a way to auto-derive it. I need the same
> kind
> of guarantee for all the GPU firmware structs...
> 
> There's one using only declarative macros [1] and one using proc
> macros
> [2]. And then, since ioctl arguments are declared in C UAPI header
> files, we need a way to be able to derive those traits for them...
> which
> I guess means bindgen changes?

It'd be cool to be able to auto-verify that uAPI structs are all
tightly packed and use the right subset of types.  Maybe not possible
this iteration but it'd be cool to see in future.  I'd like to see it
for C as well, ideally.

~Faith


Re: [PATCH v3 02/17] drm/connector: Add enum documentation to drm_colorspace

2023-03-09 Thread Sebastian Wick
On Thu, Mar 9, 2023 at 11:03 AM Pekka Paalanen  wrote:
>
> On Thu, 9 Mar 2023 01:56:11 +0100
> Sebastian Wick  wrote:
>
> > On Wed, Mar 8, 2023 at 9:59 AM Pekka Paalanen  wrote:
> > >
> > > On Tue, 7 Mar 2023 10:10:52 -0500
> > > Harry Wentland  wrote:
> > >
> > > > From: Joshua Ashton 
> > > >
> > > > To match the other enums, and add more information about these values.
> > > >
> > > > v2:
> > > >  - Specify where an enum entry comes from
> > > >  - Clarify DEFAULT and NO_DATA behavior
> > > >  - BT.2020 CYCC is "constant luminance"
> > > >  - correct type for BT.601
> > > >
> > > > Signed-off-by: Joshua Ashton 
> > > > Signed-off-by: Harry Wentland 
> > > > Reviewed-by: Harry Wentland 
> > >
> > > Hi,
> > >
> > > this effort is really good, but of course I still find things to
> > > nitpick about. If there is no answer to my questions, then I would
> > > prefer the documentation to spell out the unknowns and ambiguities.
> > >
> > > > Cc: Pekka Paalanen 
> > > > Cc: Sebastian Wick 
> > > > Cc: vitaly.pros...@amd.com
> > > > Cc: Uma Shankar 
> > > > Cc: Ville Syrjälä 
> > > > Cc: Joshua Ashton 
> > > > Cc: dri-devel@lists.freedesktop.org
> > > > Cc: amd-...@lists.freedesktop.org
> > > > ---
> > > >  include/drm/drm_connector.h | 67 +++--
> > > >  1 file changed, 65 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > > > index 6d6a53a6b010..bb078666dc34 100644
> > > > --- a/include/drm/drm_connector.h
> > > > +++ b/include/drm/drm_connector.h
> > > > @@ -363,13 +363,76 @@ enum drm_privacy_screen_status {
> > > >   PRIVACY_SCREEN_ENABLED_LOCKED,
> > > >  };
> > > >
> > > > -/*
> > > > - * This is a consolidated colorimetry list supported by HDMI and
> > > > +/**
> > > > + * enum drm_colorspace - color space
> > > > + *
> > > > + * This enum is a consolidated colorimetry list supported by HDMI and
> > > >   * DP protocol standard. The respective connectors will register
> > > >   * a property with the subset of this list (supported by that
> > > >   * respective protocol). Userspace will set the colorspace through
> > > >   * a colorspace property which will be created and exposed to
> > > >   * userspace.
> > > > + *
> > > > + * DP definitions come from the DP v2.0 spec
> > > > + * HDMI definitions come from the CTA-861-H spec
> > > > + *
> > > > + * @DRM_MODE_COLORIMETRY_DEFAULT:
> > > > + *   Driver specific behavior.
> > > > + *   For DP:
> > > > + *   RGB encoded: sRGB (IEC 61966-2-1)
> > > > + *   YCbCr encoded: ITU-R BT.601 colorimetry format
> > >
> > > Does this mean that HDMI behavior is driver-specific while DP behavior
> > > is as defined?
> > >
> > > Is it intentional that YCbCr encoding also uses different RGB-primaries
> > > than RGB-encoded signal? (BT.601 vs. BT.709/sRGB)
> > >
> > > Or do you need to be more explicit on which parts of each spec apply
> > > (ColourPrimaries vs. TransferCharacteristics vs. MatrixCoefficients in
> > > CICP parlance)?
> > >
> > > E.g. BT.709/sRGB ColourPrimaries with BT.601 MatrixCoefficients.
> >
> > Yeah, just adding to this: The Default Colorspace is something well
> > defined. CTA-861 says:
> >
> > "If bits C0 and C1 are zero, the colorimetry shall correspond to the
> > default colorimetry defined in Section 5.1"
> >
> > and in Section 5.1
> >
> > "In all cases described above, the RGB color space used should be the
> > RGB color space the Sink declares in the Basic Display Parameters and
> > Feature Block of its EDID."
> >
> > If I set DRM_MODE_COLORIMETRY_DEFAULT, I expect the Colorimetry the
> > EDID reports to be in effect and not some driver specific nonsense.
>
> Does that also define the MatrixCoefficients for YCbCr signal with
> DRM_MODE_COLORIMETRY_DEFAULT?

Good question. It doesn't seem like it does, which would make
supporting YCC with the default color space impossible.

> Not that userspace would even care, since RGB-to-YCbCr is all
> driver-internal.
>
> It is interesting you point that out. I guess it means that the basic
> colorimetry from EDID is supposed to be really only the default
> colorimetry and might not have anything to do with the actual panel
> primaries.
>
>
> Thanks,
> pq



Re: [PATCH RFC 11/18] drm/scheduler: Clean up jobs when the scheduler is torn down

2023-03-09 Thread Faith Ekstrand
On Thu, 2023-03-09 at 18:43 +0900, Asahi Lina wrote:
> On 09/03/2023 17.42, Christian König wrote:
> > Am 08.03.23 um 20:37 schrieb Asahi Lina:
> > > On 09/03/2023 03.12, Christian König wrote:
> > > > Am 08.03.23 um 18:32 schrieb Asahi Lina:
> > > > > [SNIP]
> > > > > Yes but... none of this cleans up jobs that are already
> > > > > submitted by the
> > > > > scheduler and in its pending list, with registered completion
> > > > > callbacks,
> > > > > which were already popped off of the entities.
> > > > > 
> > > > > *That* is the problem this patch fixes!
> > > > Ah! Yes that makes more sense now.
> > > > 
> > > > > > We could add a warning when users of this API doesn't do
> > > > > > this
> > > > > > correctly, but cleaning up incorrect API use is clearly
> > > > > > something we
> > > > > > don't want here.
> > > > > It is the job of the Rust abstractions to make incorrect API
> > > > > use that
> > > > > leads to memory unsafety impossible. So even if you don't
> > > > > want that in
> > > > > C, it's my job to do that for Rust... and right now, I just
> > > > > can't
> > > > > because drm_sched doesn't provide an API that can be safely
> > > > > wrapped
> > > > > without weird bits of babysitting functionality on top (like
> > > > > tracking
> > > > > jobs outside or awkwardly making jobs hold a reference to the
> > > > > scheduler
> > > > > and defer dropping it to another thread).
> > > > Yeah, that was discussed before but rejected.
> > > > 
> > > > The argument was that upper layer needs to wait for the hw to
> > > > become
> > > > idle before the scheduler can be destroyed anyway.
> > > Unfortunately, that's not a requirement you can encode in the
> > > Rust type
> > > system easily as far as I know, and Rust safety rules mean we
> > > need to
> > > make it safe even if the upper layer doesn't do this... (or else
> > > we have
> > > to mark the entire drm_sched abstraction unsafe, but that would
> > > be a pity).
> > 
> > Yeah, that should really not be something we should do.
> > 
> > But you could make the scheduler depend on your fw context object,
> > don't 
> > you?
> 
> Yes, and that would fix the problem for this driver, but it wouldn't
> make the abstraction safe. The thing is we have to make it
> *impossible*
> to misuse drm_sched in such a way that it crashes, at the Rust
> abstraction level. If we start depending on the driver following
> rules
> like that, that means the drm_sched abstraction has to be marked
> unsafe.
> 
> > Detaching the scheduler from the underlying hw fences is certainly 
> > possible, but we removed that functionality because some people
> > people 
> > tried to force push some Windows recovery module into Linux. We are
> > in 
> > the process of reverting that and cleaning things up once more, but
> > that 
> > will take a while.
> 
> Okay, but I don't see why that should block the Rust abstractions...
> I
> don't even need a new API to do that, all I need is to know that
> drm_sched_fini() will do it so it won't crash when the hw fences
> complete later, as this patch does.
> 
> > Instead of detaching you could also block for the hw to become
> > idle, but 
> > if you do that synchronous on process termination you run into
> > trouble 
> > as well.
> 
> Yes, but again this something that can only be done at the driver
> level
> so it doesn't solve the safe abstraction problem...
> 
> > > The firmware queue is itself reference counted and any firmware
> > > queue
> > > that has acquired an event notification resource (that is, which
> > > is busy
> > > with running or upcoming jobs) hands off a reference to itself
> > > into the
> > > event subsystem, so it can get notified of job completions by the
> > > firmware. Then once it becomes idle it unregisters itself, and at
> > > that
> > > point if it has no owning userspace queue, that would be the last
> > > reference and it gets dropped. So we don't tear down firmware
> > > queues
> > > until they are idle.
> > 
> > And could those fw queue not reference the scheduler?
> 
> Yes but again, that rule can't be encoded in the abstraction... so
> that
> makes it unsafe. The goal is to have a safe abstraction, which means
> that all the rules that you need to follow to avoid memory safety
> issues
> are checked by the Rust compiler.
> 
> > > I actually don't know of any way to actively abort jobs on the
> > > firmware,
> > > so this is pretty much the only option I have. I've even seen
> > > long-running compute jobs on macOS run to completion even if you
> > > kill
> > > the submitting process, so there might be no way to do this at
> > > all.
> > > Though in practice since we unmap everything from the VM anyway
> > > when the
> > > userspace stuff gets torn down, almost any normal GPU work is
> > > going to
> > > immediately fault at that point (macOS doesn't do this because
> > > macOS
> > > effectively does implicit sync with BO tracking at the kernel
> > > level...).
> > 
> > Oh, that is an interesting 

[pull] drm/msm: drm-msm-fixes-2023-03-09 for v6.3-rc2

2023-03-09 Thread Rob Clark
Hi Dave,

A few fixes for v6.3.  Summary below.  There is a back-merge of
last-cycles -fixes to avoid a merge conflict in commit 6153c44392b0
("drm/msm/adreno: fix runtime PM imbalance at unbind")

The following changes since commit 92dd0575729a423aa5524d89055e34295152a2dd:

  Merge tag 'drm-msm-fixes-2023-01-16' into msm-fixes (2023-02-22
11:20:41 -0800)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git tags/drm-msm-fixes-2023-03-09

for you to fetch changes up to a722511b18268bd1f7084eee243af416b85f288f:

  drm/msm: DEVFREQ_GOV_SIMPLE_ONDEMAND is no longer needed (2023-03-08
11:55:30 -0800)


msm-fixes for v6.3-rc2

- Fix for possible invalid ptr free in submit ioctl syncobj cleanup path.
- Synchronize GMU removal in driver teardown path
- a5xx preemption fixes
- Fix runpm imbalance at unbind
- DPU hw catalog fixes:
 - set DPU_MDP_PERIPH_0_REMOVED for sc8280xp as this is another chipset
   where the PERIPH_0 block of registers is not there
 - fix the DPU features supported in QCM2290 by comparing it with the
   downstream device tree
 - fix the length of registers in the sc7180_ctl from 0xe4 to 0x1dc
 - fix the max mixer line width for sm6115 and qcm2290 chipsets in the
   DPU catalog
 - fix the scaler version on sm8550, sc8280xp, sm8450, sm8250, sm8350
   and sm6115. This was incorrectly populated on the SW version of the
   scaler library and  not the scaler HW version
 - Drop dim layer support for msm8998 as its not indicated to be
   supported in the downstream DTSI
 - fix the DPU_CLK_CTRL bits for msm 8998 sspp blocks
 - Use DPU_CLK_CTRL_DMA* prefix instead of DPU_CLK_CTRL_CURSOR*
   for all chipsets for the DMA sspp blocks
 - fix the ping-pong block base address for sc7280 in the DPU HW catalog
- Fix stack corruption issue in the dpu_hw_ctl_setup_blendstage() function
  as it was causing a negative left shift by protecting against an invalid
  index
- Clear the DSPP reservations in dpu_rm_release(). This was missed out and
  as as result the DSPP was not released from the resource manager global
  state.


Dmitry Baryshkov (18):
  drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register
  drm/msm/a5xx: fix highest bank bit for a530
  drm/msm/a5xx: fix the emptyness check in the preempt code
  drm/msm/a5xx: fix context faults during ring switch
  drm/msm/dpu: set DPU_MDP_PERIPH_0_REMOVED for sc8280xp
  drm/msm/dpu: disable features unsupported by QCM2290
  drm/msm/dpu: fix typo in in sm8550's dma_sblk_5
  drm/msm/dpu: fix len of sc7180 ctl blocks
  drm/msm/dpu: fix sm6115 and qcm2290 mixer width limits
  drm/msm/dpu: correct sm8550 scaler
  drm/msm/dpu: correct sc8280xp scaler
  drm/msm/dpu: correct sm8450 scaler
  drm/msm/dpu: correct sm8250 and sm8350 scaler
  drm/msm/dpu: correct sm6115 scaler
  drm/msm/dpu: drop DPU_DIM_LAYER from MIXER_MSM8998_MASK
  drm/msm/dpu: fix clocks settings for msm8998 SSPP blocks
  drm/msm/dpu: don't use DPU_CLK_CTRL_CURSORn for DMA SSPP clocks
  drm/msm/dpu: fix stack smashing in dpu_hw_ctl_setup_blendstage

Douglas Anderson (1):
  drm/msm/a6xx: Make GPU destroy a bit safer

Johan Hovold (1):
  drm/msm/adreno: fix runtime PM imbalance at unbind

Kalyan Thota (1):
  drm/msm/dpu: clear DSPP reservations in rm release

Kuogee Hsieh (1):
  drm/msm/disp/dpu: fix sc7280_pp base offset

Randy Dunlap (1):
  drm/msm: DEVFREQ_GOV_SIMPLE_ONDEMAND is no longer needed

Rob Clark (1):
  drm/msm: Fix potential invalid ptr free

Thomas Zimmermann (1):
  drm/msm: Fix possible uninitialized access in fbdev

 drivers/gpu/drm/msm/Kconfig|   1 -
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c  |   6 +-
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c  |   4 +-
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c  |   2 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |   2 +
 drivers/gpu/drm/msm/adreno/adreno_device.c |   3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 166 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c |   4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c |   2 +
 drivers/gpu/drm/msm/msm_fbdev.c|   4 +-
 drivers/gpu/drm/msm/msm_gem_submit.c   |   5 +-
 12 files changed, 103 insertions(+), 98 deletions(-)


Re: [PATCH] drm/tests: helpers: Drop empty platform remove function

2023-03-09 Thread Maíra Canal

On 2/24/23 19:14, Uwe Kleine-König wrote:

A remove callback just returning 0 is equivalent to no remove callback
at all. So drop the useless function.

Signed-off-by: Uwe Kleine-König 


Applied to drm-misc-next.

Best Regards,
- Maíra Canal


---
Hello,

the remove function was introduced in commit 57a84a97bbda ("drm/tests:
helpers: Make sure the device is bound").

Best regards
Uwe

  drivers/gpu/drm/tests/drm_kunit_helpers.c | 6 --
  1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index e98b4150f556..4df47071dc88 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -19,14 +19,8 @@ static int fake_probe(struct platform_device *pdev)
return 0;
  }
  
-static int fake_remove(struct platform_device *pdev)

-{
-   return 0;
-}
-
  static struct platform_driver fake_platform_driver = {
.probe  = fake_probe,
-   .remove = fake_remove,
.driver = {
.name   = KUNIT_DEVICE_NAME,
},


Re: [PATCH RFC 10/18] drm/scheduler: Add can_run_job callback

2023-03-09 Thread Faith Ekstrand
Jumping in here quick... (Sorry, I was out yesterday and was ignoring
my e-mail on Tuesday so I could finally type some compiler code.)

On Thu, 2023-03-09 at 18:14 +0900, Asahi Lina wrote:
> On 09/03/2023 17.05, Christian König wrote:
> > Am 09.03.23 um 07:30 schrieb Asahi Lina:
> > > On 09/03/2023 05.14, Christian König wrote:
> > > > > I think you mean wake_up_interruptible(). That would be
> > > > > drm_sched_job_done(), on the fence callback when a job
> > > > > completes, which
> > > > > as I keep saying is the same logic used for
> > > > > hw_rq_count/hw_submission_limit tracking.
> > > > As the documentation to wait_event says:
> > > > 
> > > >    * wake_up() has to be called after changing any variable
> > > > that could
> > > >    * change the result of the wait condition.
> > > > 
> > > > So what you essentially try to do here is to skip that and say
> > > > drm_sched_job_done() would call that anyway, but when you read
> > > > any
> > > > variable to determine that state then as far as I can see
> > > > nothing is
> > > > guarantying that order.
> > > The driver needs to guarantee that any changes to that state
> > > precede a
> > > job completion fence signal of course, that's the entire idea of
> > > the
> > > API. It's supposed to represent a check for per-scheduler (or
> > > more
> > > specific, but not more global) resources that are released on job
> > > completion. Of course if you misuse the API you could cause a
> > > problem,
> > > but what I'm trying to say is that the API as designed and when
> > > used as
> > > intended does work properly.
> > > 
> > > Put another way: job completions always need to cause the sched
> > > main
> > > loop to run an iteration anyway (otherwise we wouldn't make
> > > forward
> > > progress), and job completions are exactly the signal that the
> > > can_run_job() condition may have changed.
> > > 
> > > > The only other possibility how you could use the callback
> > > > correctly
> > > > would be to call drm_fence_is_signaled() to query the state of
> > > > your hw
> > > > submission from the same fence which is then signaled. But then
> > > > the
> > > > question is once more why you don't give that fence directly to
> > > > the
> > > > scheduler?
> > > But the driver is supposed to guarantee that the ordering is
> > > always 1.
> > > resources freed, 2. fence signaled. So you don't need to check
> > > for the
> > > fence, you can just check for the resource state.
> > 
> > Yeah, but this is exactly what the dma_fence framework tried to
> > prevent. 
> > We try very hard to avoid such side channel signaling :)
> 
> Right, and it's fine, I can use the fences directly easily enough.
> I'm
> just trying to explain why my original idea works too, even if it's
> not
> the best solution for other reasons!
> 
> Of course I don't have the context of what other drivers are doing or
> did historically and what the pitfalls are, so I can't know what the
> "right" solution for any of this is in that context. I did my best to
> understand the drm_sched code and come up with a solution that works
> (which it does) without any more info. When I saw the hw submission
> limit stuff, I thought "okay, I need the same thing but with slightly
> more complex logic, so let's add a callback so the driver can
> customize
> it and do its own inflight counting".

So, I think there's a difference here between "impossible to implement
correctly", "likely to be implemented correctly", and "impossible to
implement incorrectly".  It's obviously possible to implement
correctly.  You can just always return true or do exactly the same
check or do some simple thing where you can guarantee that it will only
ever return false when there's a bunch of other stuff in the queue. 
That doesn't mean that it's likely to be implemented correctly by some
other driver.  Some idiot will come along and try to take advantage of
it and cause themselves horrible problems.

And, to be clear, for the purposes of this discussion, we're ALL
idiots, myself included.  If there's one thing the DRM community has
learned over the years, it's that drivers are so complex that we all
turn into idiots at some point, relative to the complexity of the code
and hardware behavior.  That's why things like dma_fence are written so
incredibly defensively and why we're so harsh about the rules.  It's
the rules and not our individual smarts that keep us from making
mistakes.  (Kinda like Rust, in a way.)  So while I appreciate the
frustration of "I'm just trying to do something that's clearly correct
here", that doesn't mean that then next person to come by and fix a bug
by tweaking that callback isn't going to screw it up irreparably.  That
person may even be you in 6 to 12 months after this e-mail thread is a
distant memory.

So, yes, does the implementation you have today work without deadlocks
or starvation?  Maybe it does.  I've not verified.  Is the suggested
callback a giant foot-gun in the already treacherous 

Re: [pull] amdgpu, amdkfd drm-fixes-6.3

2023-03-09 Thread Chen, Xiaogang



On 3/9/2023 11:32 AM, Alex Deucher wrote:

Caution: This message originated from an External Source. Use proper caution 
when opening attachments, clicking links, or responding.


On Thu, Mar 9, 2023 at 12:16 PM Felix Kuehling  wrote:


Am 2023-03-08 um 23:38 schrieb Alex Deucher:

Hi Dave, Daniel,

Fixes for 6.3.

The following changes since commit 66305069eb6d17d9190cbcd196f3f7487df47ae8:

Merge tag 'drm-misc-fixes-2023-02-23' of 
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2023-03-07 05:42:34 
+1000)

are available in the Git repository at:

https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-6.3-2023-03-08

for you to fetch changes up to 41f95a0e40903fcf70463fcc060b7faf761b23f6:

drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4 (2023-03-08 
14:39:09 -0500)


amd-drm-fixes-6.3-2023-03-08:

amdgpu:
- Misc display fixes
- UMC 8.10 fixes
- Driver unload fixes
- NBIO 7.3.0 fix
- Error checking fixes for soc15, nv, soc21 read register interface
- Fix video cap query for VCN 4.0.4

amdkfd:
- Fix BO offset for multi-VMA page migration
- Fix return check in doorbell handling


Alex Deucher (3):
drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc21
drm/amdgpu: fix error checking in amdgpu_read_mm_registers for nv

Candice Li (2):
drm/amdgpu: Support umc node harvest config on umc v8_10
drm/amd/pm: Enable ecc_info table support for smu v13_0_10

Harry Wentland (2):
drm/display: Don't block HDR_OUTPUT_METADATA on unknown EOTF
drm/connector: print max_requested_bpc in state debugfs

Mario Limonciello (1):
drm/amd: Fix initialization mistake for NBIO 7.3.0

Shashank Sharma (1):
drm/amdgpu: fix return value check in kfd

Swapnil Patel (1):
drm/amd/display: Update clock table to include highest clock setting

Veerabadhran Gopalakrishnan (1):
drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4

Xiaogang Chen (1):
drm/amdkfd: Fix BO offset for multi-VMA page migration

This patch introduced a regression. Xiaogang is working on a followup
fix. I would recommend not to merge it yet.

Xiaogang, please add a Fixes tag to your follow-up patch to make the
connection clear.

Thanks.  If it lands today, I'll send an updated PR with the fix.  If
not, I'll send an updated PR with this patch dropped.

Alex


Will do it today and let you know.

Xiaogang


Thanks,
Felix



lyndonli (2):
drm/amdgpu: Fix call trace warning and hang when removing amdgpu device
drm/amdgpu: Fix the warning info when removing amdgpu device

   drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c  | 10 ++-
   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  2 +-
   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 17 +
   drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h|  7 +-
   drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c |  1 -
   drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 14 ++--
   drivers/gpu/drm/amd/amdgpu/nv.c|  7 +-
   drivers/gpu/drm/amd/amdgpu/soc15.c |  5 +-
   drivers/gpu/drm/amd/amdgpu/soc21.c |  8 ++-
   drivers/gpu/drm/amd/amdgpu/umc_v8_10.h |  4 +-
   drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c  |  2 +-
   drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   | 17 +++--
   .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 19 +-
   .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   | 75 
++
   drivers/gpu/drm/display/drm_hdmi_helper.c  |  6 +-
   drivers/gpu/drm/drm_atomic.c   |  1 +
   16 files changed, 146 insertions(+), 49 deletions(-)


Re: [PATCH v2] drm/format-helper: Make conversion_buf_size() support sub-byte pixel fmts

2023-03-09 Thread Arthur Grillo Queiroz Cabral


Hi,

On 07/03/23 18:50, Javier Martinez Canillas wrote:
> There are DRM fourcc formats that have pixels smaller than a byte, but the
> conversion_buf_size() function assumes that pixels are a multiple of bytes
> and use the struct drm_format_info .cpp field to calculate the dst_pitch.
> 
> Instead, calculate it by using the bits per pixel (bpp) and divide it by 8
> to account for formats that have sub-byte pixels.
> 
> Signed-off-by: Javier Martinez Canillas 
> ---
> Tested by making sure that the following command still succeeds:
> 
> ./tools/testing/kunit/kunit.py run \
> --kunitconfig=drivers/gpu/drm/tests/.kunitconfig
> 
> Changes in v2:
> - Drop an unused variable, that was pointed out by the kernel robot.
> 
>  drivers/gpu/drm/tests/drm_format_helper_test.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
> b/drivers/gpu/drm/tests/drm_format_helper_test.c
> index 9536829c6e3a..84b5cc29c8fc 100644
> --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
> @@ -409,12 +409,15 @@ static size_t conversion_buf_size(u32 dst_format, 
> unsigned int dst_pitch,
> const struct drm_rect *clip)
>  {
>   const struct drm_format_info *dst_fi = drm_format_info(dst_format);
> + unsigned int bpp;
>  
>   if (!dst_fi)
>   return -EINVAL;
>  
> - if (!dst_pitch)
> - dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
> + if (!dst_pitch) {
> + bpp = drm_format_info_bpp(dst_fi, 0);
> + dst_pitch = DIV_ROUND_UP(drm_rect_width(clip) * bpp, 8);
> + }
>  
>   return dst_pitch * drm_rect_height(clip);
>  }

Ran it on UML, arm and powerpc with my patch above it, All looks good
:).

Reviewed-by: Arthur Grillo 

Thanks,
Grillo


Re: [PATCH] drm/amdkfd: fix potential kgd_mem UAFs

2023-03-09 Thread Felix Kuehling

Am 2023-03-08 um 16:37 schrieb Chia-I Wu:

kgd_mem should be accessed with p->mutex locked, or it could have been
freed by kfd_ioctl_free_memory_of_gpu.


Thank you for the patch. It's not just about accessing kgd_mem with 
p->mutex held. It's also about holding the mutex continuously. I'd 
update the description to be more explicit about the invariant being 
broken here:


kgd_mem pointers returned by kfd_process_device_translate_handle are 
only guaranteed to be valid while p->mutex is held. As soon as the mutex 
is unlocked, another thread can free the BO.


I can update the description and submit the patch.

Reviewed-by: Felix Kuehling 

Regards,
  Felix




Signed-off-by: Chia-I Wu 
---
  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 16 ++--
  1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 6d291aa6386bd..3c630114210d6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1293,14 +1293,14 @@ static int kfd_ioctl_map_memory_to_gpu(struct file 
*filep,
args->n_success = i+1;
}
  
-	mutex_unlock(>mutex);

-
err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) 
mem, true);
if (err) {
pr_debug("Sync memory failed, wait interrupted by user 
signal\n");
goto sync_memory_failed;
}
  
+	mutex_unlock(>mutex);

+
/* Flush TLBs after waiting for the page table updates to complete */
for (i = 0; i < args->n_devices; i++) {
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
@@ -1316,9 +1316,9 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
  bind_process_to_device_failed:
  get_mem_obj_from_handle_failed:
  map_memory_to_gpu_failed:
+sync_memory_failed:
mutex_unlock(>mutex);
  copy_from_user_failed:
-sync_memory_failed:
kfree(devices_arr);
  
  	return err;

@@ -1332,6 +1332,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file 
*filep,
void *mem;
long err = 0;
uint32_t *devices_arr = NULL, i;
+   bool flush_tlb;
  
  	if (!args->n_devices) {

pr_debug("Device IDs array empty\n");
@@ -1384,16 +1385,19 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file 
*filep,
}
args->n_success = i+1;
}
-   mutex_unlock(>mutex);
  
-	if (kfd_flush_tlb_after_unmap(pdd->dev)) {

+   flush_tlb = kfd_flush_tlb_after_unmap(pdd->dev);
+   if (flush_tlb) {
err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev,
(struct kgd_mem *) mem, true);
if (err) {
pr_debug("Sync memory failed, wait interrupted by user 
signal\n");
goto sync_memory_failed;
}
+   }
+   mutex_unlock(>mutex);
  
+	if (flush_tlb) {

/* Flush TLBs after waiting for the page table updates to 
complete */
for (i = 0; i < args->n_devices; i++) {
peer_pdd = kfd_process_device_data_by_id(p, 
devices_arr[i]);
@@ -1409,9 +1413,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file 
*filep,
  bind_process_to_device_failed:
  get_mem_obj_from_handle_failed:
  unmap_memory_from_gpu_failed:
+sync_memory_failed:
mutex_unlock(>mutex);
  copy_from_user_failed:
-sync_memory_failed:
kfree(devices_arr);
return err;
  }


Re: [pull] amdgpu, amdkfd drm-fixes-6.3

2023-03-09 Thread Alex Deucher
On Thu, Mar 9, 2023 at 12:16 PM Felix Kuehling  wrote:
>
>
> Am 2023-03-08 um 23:38 schrieb Alex Deucher:
> > Hi Dave, Daniel,
> >
> > Fixes for 6.3.
> >
> > The following changes since commit 66305069eb6d17d9190cbcd196f3f7487df47ae8:
> >
> >Merge tag 'drm-misc-fixes-2023-02-23' of 
> > git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2023-03-07 
> > 05:42:34 +1000)
> >
> > are available in the Git repository at:
> >
> >https://gitlab.freedesktop.org/agd5f/linux.git 
> > tags/amd-drm-fixes-6.3-2023-03-08
> >
> > for you to fetch changes up to 41f95a0e40903fcf70463fcc060b7faf761b23f6:
> >
> >drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4 (2023-03-08 
> > 14:39:09 -0500)
> >
> > 
> > amd-drm-fixes-6.3-2023-03-08:
> >
> > amdgpu:
> > - Misc display fixes
> > - UMC 8.10 fixes
> > - Driver unload fixes
> > - NBIO 7.3.0 fix
> > - Error checking fixes for soc15, nv, soc21 read register interface
> > - Fix video cap query for VCN 4.0.4
> >
> > amdkfd:
> > - Fix BO offset for multi-VMA page migration
> > - Fix return check in doorbell handling
> >
> > 
> > Alex Deucher (3):
> >drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
> >drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc21
> >drm/amdgpu: fix error checking in amdgpu_read_mm_registers for nv
> >
> > Candice Li (2):
> >drm/amdgpu: Support umc node harvest config on umc v8_10
> >drm/amd/pm: Enable ecc_info table support for smu v13_0_10
> >
> > Harry Wentland (2):
> >drm/display: Don't block HDR_OUTPUT_METADATA on unknown EOTF
> >drm/connector: print max_requested_bpc in state debugfs
> >
> > Mario Limonciello (1):
> >drm/amd: Fix initialization mistake for NBIO 7.3.0
> >
> > Shashank Sharma (1):
> >drm/amdgpu: fix return value check in kfd
> >
> > Swapnil Patel (1):
> >drm/amd/display: Update clock table to include highest clock setting
> >
> > Veerabadhran Gopalakrishnan (1):
> >drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4
> >
> > Xiaogang Chen (1):
> >drm/amdkfd: Fix BO offset for multi-VMA page migration
>
> This patch introduced a regression. Xiaogang is working on a followup
> fix. I would recommend not to merge it yet.
>
> Xiaogang, please add a Fixes tag to your follow-up patch to make the
> connection clear.

Thanks.  If it lands today, I'll send an updated PR with the fix.  If
not, I'll send an updated PR with this patch dropped.

Alex


>
> Thanks,
>Felix
>
>
> >
> > lyndonli (2):
> >drm/amdgpu: Fix call trace warning and hang when removing amdgpu 
> > device
> >drm/amdgpu: Fix the warning info when removing amdgpu device
> >
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c  | 10 ++-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  2 +-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 17 +
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h|  7 +-
> >   drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c |  1 -
> >   drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 14 ++--
> >   drivers/gpu/drm/amd/amdgpu/nv.c|  7 +-
> >   drivers/gpu/drm/amd/amdgpu/soc15.c |  5 +-
> >   drivers/gpu/drm/amd/amdgpu/soc21.c |  8 ++-
> >   drivers/gpu/drm/amd/amdgpu/umc_v8_10.h |  4 +-
> >   drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c  |  2 +-
> >   drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   | 17 +++--
> >   .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 19 +-
> >   .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   | 75 
> > ++
> >   drivers/gpu/drm/display/drm_hdmi_helper.c  |  6 +-
> >   drivers/gpu/drm/drm_atomic.c   |  1 +
> >   16 files changed, 146 insertions(+), 49 deletions(-)


Re: [pull] amdgpu, amdkfd drm-fixes-6.3

2023-03-09 Thread Felix Kuehling



Am 2023-03-08 um 23:38 schrieb Alex Deucher:

Hi Dave, Daniel,

Fixes for 6.3.

The following changes since commit 66305069eb6d17d9190cbcd196f3f7487df47ae8:

   Merge tag 'drm-misc-fixes-2023-02-23' of 
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2023-03-07 05:42:34 
+1000)

are available in the Git repository at:

   https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-6.3-2023-03-08

for you to fetch changes up to 41f95a0e40903fcf70463fcc060b7faf761b23f6:

   drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4 (2023-03-08 
14:39:09 -0500)


amd-drm-fixes-6.3-2023-03-08:

amdgpu:
- Misc display fixes
- UMC 8.10 fixes
- Driver unload fixes
- NBIO 7.3.0 fix
- Error checking fixes for soc15, nv, soc21 read register interface
- Fix video cap query for VCN 4.0.4

amdkfd:
- Fix BO offset for multi-VMA page migration
- Fix return check in doorbell handling


Alex Deucher (3):
   drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
   drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc21
   drm/amdgpu: fix error checking in amdgpu_read_mm_registers for nv

Candice Li (2):
   drm/amdgpu: Support umc node harvest config on umc v8_10
   drm/amd/pm: Enable ecc_info table support for smu v13_0_10

Harry Wentland (2):
   drm/display: Don't block HDR_OUTPUT_METADATA on unknown EOTF
   drm/connector: print max_requested_bpc in state debugfs

Mario Limonciello (1):
   drm/amd: Fix initialization mistake for NBIO 7.3.0

Shashank Sharma (1):
   drm/amdgpu: fix return value check in kfd

Swapnil Patel (1):
   drm/amd/display: Update clock table to include highest clock setting

Veerabadhran Gopalakrishnan (1):
   drm/amdgpu/soc21: Add video cap query support for VCN_4_0_4

Xiaogang Chen (1):
   drm/amdkfd: Fix BO offset for multi-VMA page migration


This patch introduced a regression. Xiaogang is working on a followup 
fix. I would recommend not to merge it yet.


Xiaogang, please add a Fixes tag to your follow-up patch to make the 
connection clear.


Thanks,
  Felix




lyndonli (2):
   drm/amdgpu: Fix call trace warning and hang when removing amdgpu device
   drm/amdgpu: Fix the warning info when removing amdgpu device

  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c  | 10 ++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 17 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h|  7 +-
  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c |  1 -
  drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 14 ++--
  drivers/gpu/drm/amd/amdgpu/nv.c|  7 +-
  drivers/gpu/drm/amd/amdgpu/soc15.c |  5 +-
  drivers/gpu/drm/amd/amdgpu/soc21.c |  8 ++-
  drivers/gpu/drm/amd/amdgpu/umc_v8_10.h |  4 +-
  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c  |  2 +-
  drivers/gpu/drm/amd/amdkfd/kfd_migrate.c   | 17 +++--
  .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 19 +-
  .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   | 75 ++
  drivers/gpu/drm/display/drm_hdmi_helper.c  |  6 +-
  drivers/gpu/drm/drm_atomic.c   |  1 +
  16 files changed, 146 insertions(+), 49 deletions(-)


Re: [PATCH] backlight: apple_bl: Use acpi_video_get_backlight_type()

2023-03-09 Thread Daniel Thompson
On Tue, Mar 07, 2023 at 01:05:40PM +0100, Hans de Goede wrote:
> On some MacBooks both the apple_bl and the apple-gmux backlight drivers
> may be able to export a /sys/class/backlight device.
>
> To avoid having 2 backlight devices for one LCD panel until now
> the apple-gmux driver has been calling apple_bl_unregister() to move
> the apple_bl backlight device out of the way when it loads.
>
> Similar problems exist on other x86 laptops and all backlight drivers
> which may be used on x86 laptops have moved to using
> acpi_video_get_backlight_type() to determine whether they should load
> or not.
>
> Switch apple_bl to this model too, so that it is consistent with all
> the other x86 backlight drivers.
> [snip]
> Signed-off-by: Hans de Goede 

Reviewed-by: Daniel Thompson 

but...

> ---
> A note to the backlight class / subsystem maintainers, this change
> applies on top of a similar patch for drivers/platform/x86/apple-gmux.c
> which makes that driver use acpi_video_get_backlight_type(). See:
> https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
>
> I believe it is easiest to also merge this patch through
> the platform-drivers-x86 tree, may I please have your Ack for this ?
> ---

... please don't treat above as an ack. Lee Jones will hopefully be
along shortly to discuss that!


Daniel.


[PATCH] drm/i915/mtl: Disable stolen memory backed FB for A0

2023-03-09 Thread Nirmoy Das
Stolen memory is not usable for MTL A0 stepping beyond
certain access size and we have no control over userspace
access size of /dev/fb which can be backed by stolen memory.
So disable stolen memory backed fb by setting i915->dsm.usable_size
to zero.

Cc: Matthew Auld 
Cc: Andi Shyti 
Cc: Daniele Ceraolo Spurio 
Cc: Lucas De Marchi 

Signed-off-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index d8e06e783e30..56ccfcbdbce1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -535,6 +535,16 @@ static int i915_gem_init_stolen(struct intel_memory_region 
*mem)
/* Basic memrange allocator for stolen space. */
drm_mm_init(>mm.stolen, 0, i915->dsm.usable_size);
 
+   /*
+* Access to stolen lmem beyond certain size for MTL A0 stepping
+* would crash the machine. Disable stolen lmem for userspace access
+* by setting usable_size to zero.
+* hsdes: 22016134735
+*/
+   if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
+   IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
+   i915->dsm.usable_size = 0;
+
return 0;
 }
 
-- 
2.39.0



Re: [PATCH 3/7] drm/i915/hwmon: Power PL1 limit and TDP setting

2023-03-09 Thread Guenter Roeck
On Tue, Feb 28, 2023 at 01:18:55PM -0800, Dixit, Ashutosh wrote:
> On Fri, 12 Aug 2022 11:06:58 -0700, Guenter Roeck wrote:
> >
> 
> Hi Guenter/linux-hwmon,
> 
> 
> > On 8/12/22 10:37, Badal Nilawar wrote:
> > > From: Dale B Stimson 
> > >
> > > Use i915 HWMON to display/modify dGfx power PL1 limit and TDP setting.
> > >
> 
> /snip/
> 
> >
> > Acked-by: Guenter Roeck 
> >
> > > ---
> > >   .../ABI/testing/sysfs-driver-intel-i915-hwmon |  20 ++
> > >   drivers/gpu/drm/i915/i915_hwmon.c | 176 +-
> > >   drivers/gpu/drm/i915/i915_reg.h   |  16 ++
> > >   drivers/gpu/drm/i915/intel_mchbar_regs.h  |   7 +
> > >   4 files changed, 217 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon 
> > > b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
> > > index 24c4b7477d51..9a2d10edfce8 100644
> > > --- a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
> > > +++ b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
> > > @@ -5,3 +5,23 @@ Contact: dri-devel@lists.freedesktop.org
> > >   Description:RO. Current Voltage in millivolt.
> > >   Only supported for particular Intel i915 graphics
> > > platforms.
> > > +
> > > +What:/sys/devices/.../hwmon/hwmon/power1_max
> > > +Date:June 2022
> > > +KernelVersion:   5.19
> > > +Contact: dri-devel@lists.freedesktop.org
> > > +Description: RW. Card reactive sustained  (PL1/Tau) power limit in 
> > > microwatts.
> > > +
> > > + The power controller will throttle the operating frequency
> > > + if the power averaged over a window (typically seconds)
> > > + exceeds this limit.
> 
> We exposed this as 'power1_max' previously. However this is a "power
> limit".
> 
> https://github.com/torvalds/linux/blob/master/Documentation/hwmon/sysfs-interface.rst
> 
> says power1_max is "Maximum power". On the other hand, power1_cap is "If
> power use rises above this limit, the system should take action to reduce
> power use". So it would seem we should have chosen power1_cap for this
> power limit instead of power1_max? So do you think we should change this to
> power1_cap instead? Though even power1_max has an associated alarm so it
> also seems to be a sort of limit.
> 
> Is there any guidance as to how these different power limits should be
> used? Generally speaking is: power1_max <= power1_cap <= power1_crit, or is
> it arbitrary or something else?
> 

Nothing should ever be "arbitrary" but have some reason. Arbitrary is
if you glue all the possible attributes onto a wall and then select the
ones to use by throwing darts at it.

powerX_min, powerX_max and powerX_crit are typically hard limits which
can not actively be influenced without drastic measures such as turning
off some hardware. powerX_cap is supposed to be more flexible; the
assumption is that the hardware or firmware has some means to control power
such that it does not exceed powerX_cap (while maintaining operational
status), for example by modifying operational frequencies.

Nowadays everything may be a bit more flexible; for example, one could
imagine that a modern system could (via software) reduce the operational
frequency of the system if power consumption exceeds powerX_max or
powerX_crit. The distinction would be that with powerX_cap, the hardware
or firmware would in general be in control, while with powerX_max
and powerX_crit the host software would be in control.

> Also, only power1_cap seems to have power1_cap_min and power1_cap_max (in
> case we wanted to use min/max values for the limits), not the others.

powerX_min is supported by the infrastructure. It not being documented
is an oversight.

Guenter

> 
> Separately, we have already used up power1_crit (which is the other limit
> in official hwmon power limits) so we can't use that.
> 
> Thanks.
> --
> Ashutosh


Re: [PATCH] drm/meson: dw-hdmi: Fix devm_regulator_*get_enable*() conversion again

2023-03-09 Thread Neil Armstrong

On 09/03/2023 16:24, Marek Szyprowski wrote:

devm_regulator_get_enable_optional() returns -ENODEV if requested
optional regulator is not present. Adjust code for that, because in the
67d0a30128c9 I've incorrectly assumed that it also returns 0 when
regulator is not present.

Reported-by: Ricardo Cañuelo 
Fixes: 67d0a30128c9 ("drm/meson: dw-hdmi: Fix devm_regulator_*get_enable*() 
conversion")
Signed-off-by: Marek Szyprowski 
---
  drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c 
b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 534621a13a34..3d046878ce6c 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -718,7 +718,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct 
device *master,
dw_plat_data = _dw_hdmi->dw_plat_data;
  
  	ret = devm_regulator_get_enable_optional(dev, "hdmi");

-   if (ret < 0)
+   if (ret < 0 && ret != -ENODEV)
return ret;
  
  	meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,


Acked-by: Neil Armstrong 


[Bug 217168] New: mmap length not validated in drm_gem_dma_mmap()

2023-03-09 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=217168

Bug ID: 217168
   Summary: mmap length not validated in drm_gem_dma_mmap()
   Product: Drivers
   Version: 2.5
Kernel Version: 6.2
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: m...@maintech.de
Regression: No

In the drm_gem_dma_mmap() function (drm_gem_cma_mmap() for kernel versions
before 6.1), the length of the requested mapping does not get validated against
the length of the GEM buffer object. Therefore the user can gain full access to
the physical memory after the GEM buffer by just mmap-ing the buffer with a
larger length.


I *think* the correct way to fix this issue is to pass the actual size of the
buffer as 'size' argument to the dma_mmap_wc/dma_mmap_pages function, instead
of the user-requested length. (=> replace "vma->vm_end - vma->vm_start" by
"dma_obj->base.size"). These functions then will validate the requested length
against the buffer size and return -ENXIO if the length is too large. But I am
in no means an expert in this area, so somebody with more experience should
definitely confirm this. 


I have discovered this issue by using mmap on on an fbdev (/dev/fb0) created by
the Xilinx 'ZynqMP DisplayPort Subsystem' DRM driver
(/drivers/gpu/drm/xlnx/zynqmp_dpsub.c) and validated that I can actually use
this to gain access to the physical memory behind the framebuffer. But as this
is an generic helper function of the DRM GEM framework used by many different
DRM drivers, I assume other DRM drivers are affected in a similar way.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[PATCH v2 088/101] fbdev/uvesafb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/uvesafb.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index ff8f511a00c2..13bd8503a06b 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -9,6 +9,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -1809,16 +1810,14 @@ static struct platform_driver uvesafb_driver = {
 static struct platform_device *uvesafb_device;
 
 #ifndef MODULE
-static int uvesafb_setup(char *options)
+static int uvesafb_setup(const char *options)
 {
+   struct option_iter iter;
char *this_opt;
 
-   if (!options || !*options)
-   return 0;
-
-   while ((this_opt = strsep(, ",")) != NULL) {
-   if (!*this_opt) continue;
+   option_iter_init(, options);
 
+   while (option_iter_next(, _opt)) {
if (!strcmp(this_opt, "redraw"))
ypan = 0;
else if (!strcmp(this_opt, "ypan"))
@@ -1860,6 +1859,8 @@ static int uvesafb_setup(char *options)
}
}
 
+   option_iter_release();
+
if (mtrr != 3 && mtrr != 0)
pr_warn("uvesafb: mtrr should be set to 0 or 3; %d is 
unsupported", mtrr);
 
-- 
2.39.2



[PATCH v2 090/101] fbdev/valkyriefb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/valkyriefb.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index b166b7cfe0e5..3c20f392370a 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -39,6 +39,7 @@
  *  more details.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -90,7 +91,7 @@ struct fb_info_valkyrie {
u32 pseudo_palette[16];
 };
 
-static int valkyriefb_setup(char*);
+static int valkyriefb_setup(const char *options);
 
 static int valkyriefb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
@@ -545,14 +546,14 @@ static int __init valkyrie_init_info(struct fb_info *info,
 /*
  * Parse user specified options (`video=valkyriefb:')
  */
-static int __init valkyriefb_setup(char *options)
+static int __init valkyriefb_setup(const char *options)
 {
+   struct option_iter iter;
char *this_opt;
 
-   if (!options || !*options)
-   return 0;
+   option_iter_init(, options);
 
-   while ((this_opt = strsep(, ",")) != NULL) {
+   while (option_iter_next(, _opt)) {
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
@@ -571,6 +572,9 @@ static int __init valkyriefb_setup(char *options)
}
}
}
+
+   option_iter_release();
+
return 0;
 }
 
-- 
2.39.2



[PATCH v2 070/101] fbdev/savagefb: Duplicate video-mode option string

2023-03-09 Thread Thomas Zimmermann
Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/savage/savagefb_driver.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/savage/savagefb_driver.c 
b/drivers/video/fbdev/savage/savagefb_driver.c
index 4a27b68798bf..0ca5894114c9 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -65,6 +65,7 @@
 /* - */
 
 
+static char *mode_option_buf;
 static char *mode_option = NULL;
 
 #ifdef MODULE
@@ -2530,6 +2531,7 @@ static void __exit savage_done(void)
 {
DBG("savage_done");
pci_unregister_driver(_driver);
+   kfree(mode_option_buf);
 }
 
 
@@ -2544,7 +2546,9 @@ static int __init savagefb_setup(char *options)
return 0;
 
while ((this_opt = strsep(, ",")) != NULL) {
-   mode_option = this_opt;
+   kfree(mode_option_buf);
+   mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // ignore 
errors
+   mode_option = mode_option_buf;
}
 #endif /* !MODULE */
return 0;
-- 
2.39.2



[PATCH v2 003/101] fbdev/68328fb: Remove unused option string

2023-03-09 Thread Thomas Zimmermann
The option string is unused. Remove the variable and a related
helper function. No functional change.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/68328fb.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c
index 7fe56ecbe4e6..f2d70df4104b 100644
--- a/drivers/video/fbdev/68328fb.c
+++ b/drivers/video/fbdev/68328fb.c
@@ -400,13 +400,6 @@ static int mc68x328fb_mmap(struct fb_info *info, struct 
vm_area_struct *vma)
 #endif
 }
 
-static int __init mc68x328fb_setup(char *options)
-{
-   if (!options || !*options)
-   return 1;
-   return 1;
-}
-
 /*
  *  Initialisation
  */
@@ -414,11 +407,8 @@ static int __init mc68x328fb_setup(char *options)
 static int __init mc68x328fb_init(void)
 {
 #ifndef MODULE
-   char *option = NULL;
-
-   if (fb_get_options("68328fb", ))
+   if (fb_get_options("68328fb", NULL))
return -ENODEV;
-   mc68x328fb_setup(option);
 #endif
/*
 *  initialize the default mode from the LCD controller registers
-- 
2.39.2



[PATCH v2 082/101] fbdev/tgafb: Duplicate video-mode option string

2023-03-09 Thread Thomas Zimmermann
Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/tgafb.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index 14d37c49633c..cf00b8a91bfb 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -59,6 +59,7 @@ static int tgafb_pan_display(struct fb_var_screeninfo *var, 
struct fb_info *info
 static int tgafb_register(struct device *dev);
 static void tgafb_unregister(struct device *dev);
 
+static const char *mode_option_buf;
 static const char *mode_option;
 static const char *mode_option_pci = "640x480@60";
 static const char *mode_option_tc = "1280x1024@72";
@@ -1568,6 +1569,7 @@ static void tgafb_exit(void)
 {
tc_unregister_driver(_tc_driver);
pci_unregister_driver(_pci_driver);
+   kfree(mode_option_buf);
 }
 
 #ifndef MODULE
@@ -1579,9 +1581,11 @@ static int tgafb_setup(char *arg)
while ((this_opt = strsep(, ","))) {
if (!*this_opt)
continue;
-   if (!strncmp(this_opt, "mode:", 5))
-   mode_option = this_opt+5;
-   else
+   if (!strncmp(this_opt, "mode:", 5)) {
+   kfree(mode_option_buf);
+   mode_option_buf = kstrdup(this_opt, 
GFP_KERNEL); // ignore errors
+   mode_option = mode_option_buf;
+   } else
printk(KERN_ERR
   "tgafb: unknown parameter %s\n",
   this_opt);
-- 
2.39.2



[PATCH v2 086/101] fbdev/tridentfb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/tridentfb.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index dbde64aef91f..3299806c0f58 100644
--- a/drivers/video/fbdev/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
@@ -17,6 +17,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1775,14 +1776,14 @@ static struct pci_driver tridentfb_pci_driver = {
  * video=trident:800x600,bpp=16,noaccel
  */
 #ifndef MODULE
-static int __init tridentfb_setup(char *options)
+static int __init tridentfb_setup(const char *options)
 {
+   struct option_iter iter;
char *opt;
-   if (!options || !*options)
-   return 0;
-   while ((opt = strsep(, ",")) != NULL) {
-   if (!*opt)
-   continue;
+
+   option_iter_init(, options);
+
+   while (option_iter_next(, )) {
if (!strncmp(opt, "noaccel", 7))
noaccel = 1;
else if (!strncmp(opt, "fp", 2))
@@ -1807,6 +1808,9 @@ static int __init tridentfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+   option_iter_release();
+
return 0;
 }
 #endif
-- 
2.39.2



[PATCH v2 077/101] fbdev/sstfb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/sstfb.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c
index f422b1882950..b509020fed74 100644
--- a/drivers/video/fbdev/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
@@ -81,6 +81,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1274,16 +1275,14 @@ static void sst_shutdown(struct fb_info *info)
 /*
  * Interface to the world
  */
-static int sstfb_setup(char *options)
+static int sstfb_setup(const char *options)
 {
+   struct option_iter iter;
char *this_opt;
 
-   if (!options || !*options)
-   return 0;
-
-   while ((this_opt = strsep(, ",")) != NULL) {
-   if (!*this_opt) continue;
+   option_iter_init(, options);
 
+   while (option_iter_next(, _opt)) {
f_ddprintk("option %s\n", this_opt);
 
if (!strcmp(this_opt, "vganopass"))
@@ -1308,6 +1307,9 @@ static int sstfb_setup(char *options)
mode_option = mode_option_buf;
}
}
+
+   option_iter_release();
+
return 0;
 }
 
-- 
2.39.2



[PATCH v2 089/101] fbdev/valkyriefb: Remove trailing whitespaces

2023-03-09 Thread Thomas Zimmermann
Fix coding style. No functional changes.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/valkyriefb.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 1007023a5e88..b166b7cfe0e5 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -1,7 +1,7 @@
 /*
  *  valkyriefb.c -- frame buffer device for the PowerMac 'valkyrie' display
  *
- *  Created 8 August 1998 by 
+ *  Created 8 August 1998 by
  *  Martin Costabel  and Kevin Schoedel
  *
  *  Vmode-switching changes and vmode 15/17 modifications created 29 August
@@ -77,13 +77,13 @@ struct fb_info_valkyrie {
struct fb_par_valkyrie  par;
struct cmap_regs__iomem *cmap_regs;
unsigned long   cmap_regs_phys;
-   
+
struct valkyrie_regs__iomem *valkyrie_regs;
unsigned long   valkyrie_regs_phys;
-   
+
__u8__iomem *frame_buffer;
unsigned long   frame_buffer_phys;
-   
+
int sense;
unsigned long   total_vram;
 
@@ -244,7 +244,7 @@ static inline int valkyrie_vram_reqd(int video_mode, int 
color_mode)
 {
int pitch;
struct valkyrie_regvals *init = valkyrie_reg_init[video_mode-1];
-   
+
if ((pitch = init->pitch[color_mode]) == 0)
pitch = 2 * init->pitch[0];
return init->vres * pitch;
@@ -467,7 +467,7 @@ static int valkyrie_var_to_par(struct fb_var_screeninfo 
*var,
printk(KERN_ERR "valkyriefb: vmode %d not valid.\n", vmode);
return -EINVAL;
}
-   
+
if (cmode != CMODE_8 && cmode != CMODE_16) {
printk(KERN_ERR "valkyriefb: cmode %d not valid.\n", cmode);
return -EINVAL;
@@ -516,7 +516,7 @@ static void valkyrie_init_fix(struct fb_fix_screeninfo 
*fix, struct fb_info_valk
fix->ywrapstep = 0;
fix->ypanstep = 0;
fix->xpanstep = 0;
-   
+
 }
 
 /* Fix must already be inited above */
-- 
2.39.2



[PATCH v2 075/101] fbdev/sm712fb: Duplicate video-mode option string

2023-03-09 Thread Thomas Zimmermann
Assume that the driver does not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in the module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/sm712fb.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index b528776c7612..a83f48fce5b1 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -831,6 +831,7 @@ static const struct modeinit vgamode[] = {
 
 static struct screen_info smtc_scr_info;
 
+static char *mode_option_buf;
 static char *mode_option;
 
 /* process command line options, get vga parameter */
@@ -1761,8 +1762,12 @@ static int __init sm712fb_init(void)
 
if (fb_get_options("sm712fb", ))
return -ENODEV;
-   if (option && *option)
-   mode_option = option;
+
+   if (option && *option) {
+   mode_option_buf = kstrdup(option, GFP_KERNEL); // ignore errors
+   mode_option = mode_option_buf;
+   }
+
sm7xx_vga_setup(mode_option);
 
return pci_register_driver(_driver);
@@ -1773,6 +1778,7 @@ module_init(sm712fb_init);
 static void __exit sm712fb_exit(void)
 {
pci_unregister_driver(_driver);
+   kfree(mode_option_buf);
 }
 
 module_exit(sm712fb_exit);
-- 
2.39.2



[PATCH v2 011/101] fbdev/aty: Duplicate video-mode option string

2023-03-09 Thread Thomas Zimmermann
Assume that the drivers do not own the option string or its substrings
and hence duplicate the option string for the video mode. Allocate the
copy's memory with kstrdup() and free it in each module's exit function.

Done in preparation of switching the driver to struct option_iter and
constifying the option string.

v2:
* replace static memory with kstrdup()/kfree() (Geert)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/aty/aty128fb.c| 8 +++-
 drivers/video/fbdev/aty/atyfb_base.c  | 9 +++--
 drivers/video/fbdev/aty/radeon_base.c | 9 +++--
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/aty/aty128fb.c 
b/drivers/video/fbdev/aty/aty128fb.c
index 36a9ac05a340..0e725a6eb40b 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -383,6 +383,7 @@ static const struct fb_fix_screeninfo aty128fb_fix = {
.accel  = FB_ACCEL_ATI_RAGE128,
 };
 
+static char *mode_option_buf;
 static char *mode_option = NULL;
 
 #ifdef CONFIG_PPC_PMAC
@@ -1723,7 +1724,11 @@ static int aty128fb_setup(char *options)
continue;
}
 #endif /* CONFIG_PPC_PMAC */
-   mode_option = this_opt;
+   {
+   kfree(mode_option_buf);
+   mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // 
ignore errors
+   mode_option = mode_option_buf;
+   }
}
return 0;
 }
@@ -2518,6 +2523,7 @@ static int aty128fb_init(void)
 static void __exit aty128fb_exit(void)
 {
pci_unregister_driver(_driver);
+   kfree(mode_option_buf);
 }
 
 module_init(aty128fb_init);
diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index b02e4e645035..d83b3dae795b 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -326,6 +326,7 @@ static int pll;
 static int mclk;
 static int xclk;
 static int comp_sync = -1;
+static char *mode_buf;
 static char *mode;
 static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);
 
@@ -3896,8 +3897,11 @@ static int __init atyfb_setup(char *options)
}
}
 #endif
-   else
-   mode = this_opt;
+   else {
+   kfree(mode_buf);
+   mode_buf = kstrdup(this_opt, GFP_KERNEL); // ignore 
errors
+   mode = mode_buf;
+   }
}
return 0;
 }
@@ -3995,6 +3999,7 @@ static void __exit atyfb_exit(void)
 #ifdef CONFIG_PCI
pci_unregister_driver(_driver);
 #endif
+   kfree(mode_buf);
 }
 
 module_init(atyfb_init);
diff --git a/drivers/video/fbdev/aty/radeon_base.c 
b/drivers/video/fbdev/aty/radeon_base.c
index 657064227de8..dc2657ae96f2 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -257,6 +257,7 @@ static reg_val common_regs[] = {
  * globals
  */
 
+static char *mode_option_buf;
 static char *mode_option;
 static char *monitor_layout;
 static bool noaccel = 0;
@@ -2596,8 +2597,11 @@ static int __init radeonfb_setup (char *options)
} else if (!strncmp(this_opt, "ignore_devlist", 14)) {
ignore_devlist = 1;
 #endif
-   } else
-   mode_option = this_opt;
+   } else {
+   kfree(mode_option_buf);
+   mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // 
ignore errors
+   mode_option = mode_option_buf;
+   }
}
return 0;
 }
@@ -2624,6 +2628,7 @@ static int __init radeonfb_init (void)
 static void __exit radeonfb_exit (void)
 {
pci_unregister_driver (_driver);
+   kfree(mode_option_buf);
 }
 
 module_init(radeonfb_init);
-- 
2.39.2



[PATCH v2 065/101] fbdev/pxafb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/pxafb.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index c46ed78298ae..d2db9c20d515 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -32,6 +32,7 @@
  *   All Rights Reserved
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -2011,23 +2012,26 @@ static int parse_opt(struct device *dev, char *this_opt,
return 0;
 }
 
-static int pxafb_parse_options(struct device *dev, char *options,
+static int pxafb_parse_options(struct device *dev, const char *options,
   struct pxafb_mach_info *inf)
 {
+   struct option_iter iter;
char *this_opt;
int ret;
 
-   if (!options || !*options)
-   return 0;
-
dev_dbg(dev, "options are \"%s\"\n", options ? options : "null");
 
-   /* could be made table driven or similar?... */
-   while ((this_opt = strsep(, ",")) != NULL) {
+   option_iter_init(, options);
+
+   while (option_iter_next(, _opt)) {
+   /* could be made table driven or similar?... */
ret = parse_opt(dev, this_opt, inf);
if (ret)
return ret;
}
+
+   option_iter_release();
+
return 0;
 }
 
-- 
2.39.2



[PATCH v2 056/101] fbdev/platinumfb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/platinumfb.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index c7172174c1b7..33bf75309815 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -19,6 +19,7 @@
 
 #undef DEBUG
 
+#include 
 #include 
 #include 
 #include 
@@ -486,14 +487,14 @@ static int platinum_var_to_par(struct fb_var_screeninfo 
*var,
 /*
  * Parse user specified options (`video=platinumfb:')
  */
-static int __init platinumfb_setup(char *options)
+static int __init platinumfb_setup(const char *options)
 {
+   struct option_iter iter;
char *this_opt;
 
-   if (!options || !*options)
-   return 0;
+   option_iter_init(, options);
 
-   while ((this_opt = strsep(, ",")) != NULL) {
+   while (option_iter_next(, _opt)) {
if (!strncmp(this_opt, "vmode:", 6)) {
int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
@@ -516,6 +517,9 @@ static int __init platinumfb_setup(char *options)
}
}
}
+
+   option_iter_release();
+
return 0;
 }
 
-- 
2.39.2



[PATCH v2 083/101] fbdev/tgafb: Parse option string with struct option_iter

2023-03-09 Thread Thomas Zimmermann
Use struct option_iter to walk over the individual options in the
driver's option string. Replaces the hand-written strsep() loop with
a clean interface. The helpers for struct option_iter handle empty
option strings and empty options transparently. The struct's _init
and _release functions duplicate and release the option string's
memory buffer as needed.

Done in preparation of constifying the option string.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/tgafb.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index cf00b8a91bfb..0862d9a54aef 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1573,25 +1574,24 @@ static void tgafb_exit(void)
 }
 
 #ifndef MODULE
-static int tgafb_setup(char *arg)
+static int tgafb_setup(const char *arg)
 {
+   struct option_iter iter;
char *this_opt;
 
-   if (arg && *arg) {
-   while ((this_opt = strsep(, ","))) {
-   if (!*this_opt)
-   continue;
-   if (!strncmp(this_opt, "mode:", 5)) {
-   kfree(mode_option_buf);
-   mode_option_buf = kstrdup(this_opt, 
GFP_KERNEL); // ignore errors
-   mode_option = mode_option_buf;
-   } else
-   printk(KERN_ERR
-  "tgafb: unknown parameter %s\n",
-  this_opt);
-   }
+   option_iter_init(, arg);
+
+   while (option_iter_next(, _opt)) {
+   if (!strncmp(this_opt, "mode:", 5)) {
+   kfree(mode_option_buf);
+   mode_option_buf = kstrdup(this_opt, GFP_KERNEL); // 
ignore errors
+   mode_option = mode_option_buf;
+   } else
+   printk(KERN_ERR "tgafb: unknown parameter %s\n", 
this_opt);
}
 
+   option_iter_release();
+
return 0;
 }
 #endif /* !MODULE */
-- 
2.39.2



  1   2   3   4   >