Re: [Freedreno] [PATCH v6 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-01-18 Thread Johan Hovold
On Wed, Jan 18, 2023 at 07:30:13PM +, Mark Yacoub wrote:
> From: Sean Paul 
> 
> This patch adds the bindings for the MSM DisplayPort HDCP registers
> which are required to write the HDCP key into the display controller as
> well as the registers to enable HDCP authentication/key
> exchange/encryption.
> 
> We'll use a new compatible string for this since the fields are optional.
> 
> Cc: Rob Herring 
> Cc: Stephen Boyd 
> Reviewed-by: Rob Herring 
> Signed-off-by: Sean Paul 
> Signed-off-by: Mark Yacoub 

Just a drive-by comment: Your mail address is missing an 'm' here.

Perhaps check the rest of the series as well (checkpatch should catch
this).

Johan


[Freedreno] [PATCH v3] drm/msm/dpu: add the regdma entries to .dma_cfg of these chipsets

2023-01-18 Thread Jiapeng Chong
Variables 'sc8280xp_regdma' and 'sm8350_regdma' are defined in the
dpu_hw_catalog.c file, but not used elsewhere, so adding the regdma
entries to .dma_cfg of these chipsets.

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2029:37: warning: unused
variable 'sc8280xp_regdma'.
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2053:37: warning: unused
variable 'sm8350_regdma'.

Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3722
Fixes: 4a352c2fc15a ("drm/msm/dpu: Introduce SC8280XP")
Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog")
Reported-by: Abaci Robot 
Signed-off-by: Jiapeng Chong 
---
Changes in v3:
  -Add Fixes tag and change the title.

 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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 0f3da480b066..3318e1d18a0e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -2677,6 +2677,8 @@ static const struct dpu_mdss_cfg sc8280xp_dpu_cfg = {
.intf = sc8280xp_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
+   .reg_dma_count = 1,
+   .dma_cfg = &sc8280xp_regdma,
.perf = &sc8280xp_perf_data,
.mdss_irqs = IRQ_SC8280XP_MASK,
 };
@@ -2732,7 +2734,7 @@ static const struct dpu_mdss_cfg sm8350_dpu_cfg = {
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
.reg_dma_count = 1,
-   .dma_cfg = &sm8250_regdma,
+   .dma_cfg = &sm8350_regdma,
.perf = &sm8350_perf_data,
.mdss_irqs = IRQ_SM8350_MASK,
 };
-- 
2.20.1.7.g153144c



Re: [Freedreno] (subset) [PATCH v5 0/4] dt-bindings: display/msm: convert MDP5 schema to YAML format

2023-01-18 Thread Bjorn Andersson
On Mon, 9 Jan 2023 07:01:48 +0200, Dmitry Baryshkov wrote:
> This patch concludes the conversion of display/msm schema from txt files
> to YAML format.
> 
> The per-SoC compat (new addition) is required to ease migrating platform
> support between mdp5 and dpu drivers.
> 
> Changes since v4:
> - Adjust qcom,mdss.yaml to follow the addition of per-SoC compatibles
> 
> [...]

Applied, thanks!

[3/4] ARM: dts: qcom-msm8974: add SoC specific compat string to mdp5 node
  commit: 11691dab82e135c9a13cda49234ff3e76bba48d3

Best regards,
-- 
Bjorn Andersson 


Re: [Freedreno] (subset) [PATCH 0/6] dt-bindings: display/msm: rename mdss and mdp nodes

2023-01-18 Thread Bjorn Andersson
On Mon, 9 Jan 2023 07:13:56 +0200, Dmitry Baryshkov wrote:
> Finish the process of renaming display-related nodes on Qualcomm
> systems. Fix it in the schema that MDSS (Mobile Display SubSystem)
> devices are named `display-subsystem' and both MDP (Mobile Display
> Processor) and DPU (Display Processor Unit) nodes are named
> `display-controller'.
> 
> Dmitry Baryshkov (6):
>   dt-bindings: display/msm: rename mdss nodes to display-sybsystem
>   dt-bindings: display/msm: rename mdp nodes to display-controller
>   arm64: dts: qcom: rename mdss nodes to display-subsystem
>   ARM: dts: qcom-msm8974: rename mdss node to display-subsystem
>   arm64: dts: qcom: rename mdp nodes to display-controller
>   ARM: dts: qcom: rename mdp nodes to display-controller
> 
> [...]

Applied, thanks!

[4/6] ARM: dts: qcom-msm8974: rename mdss node to display-subsystem
  commit: 19230930286005d7c733a5cb0ed8ebce9cad4423
[6/6] ARM: dts: qcom: rename mdp nodes to display-controller
  commit: 858b0d4b04ead05cdfec094a1e4b18865f28cedc

Best regards,
-- 
Bjorn Andersson 


Re: [Freedreno] [PATCH v3] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Abhinav Kumar




On 1/18/2023 3:38 PM, Jessica Zhang wrote:

Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied if the LM/DSPP
blocks were reallocated during modeset or after a suspend/resume.

Changes in V2:
- Fixed commit message

Changes in V3:
- Added mention of suspend/resume case back to commit message

Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 


Reviewed-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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
  
  
-	if (!state->color_mgmt_changed)

+   if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
  
  	for (i = 0; i < cstate->num_mixers; i++) {


Re: [Freedreno] [PATCH v6 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-01-18 Thread Abhinav Kumar

Hi Mark

On 1/18/2023 11:30 AM, Mark Yacoub wrote:

From: Sean Paul 

This patch adds the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller. Now that these are supported, change the
compatible string to "dp-hdcp".

Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-14-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-14-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-10-s...@poorly.run
 #v5

Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream

---
  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
  1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 178efaaa89ec..6f6fe5cb6563 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -817,6 +817,14 @@ &mdss_dp {
pinctrl-names = "default";
pinctrl-0 = <&dp_hot_plug_det>;
data-lanes = <0 1>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x175>,
+ <0 0x0aee1000 0 0x2c>;
  };


Can you pls point me to which tree you rebased this on top of?

The mdss_dp node looks different here: 
https://gitlab.com/linux-kernel/linux-next/-/blob/master/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi#L815


For the TZ regs the second entry is fine but any reason for the size of 
the first register space to be 0x175 instead of 0x174?




  
  &pm6150_adc {


Re: [Freedreno] [PATCH v6 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 19:30:13 +, Mark Yacoub wrote:
> From: Sean Paul 
> 
> This patch adds the bindings for the MSM DisplayPort HDCP registers
> which are required to write the HDCP key into the display controller as
> well as the registers to enable HDCP authentication/key
> exchange/encryption.
> 
> We'll use a new compatible string for this since the fields are optional.
> 
> Cc: Rob Herring 
> Cc: Stephen Boyd 
> Reviewed-by: Rob Herring 
> Signed-off-by: Sean Paul 
> Signed-off-by: Mark Yacoub 
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-13-s...@poorly.run
>  #v1
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-13-s...@poorly.run
>  #v2
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-13-s...@poorly.run
>  #v3
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-13-s...@poorly.run
>  #v4
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/2025202153.117244-1-s...@poorly.run
>  #v4.5
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-9-s...@poorly.run
>  #v5
> 
> Changes in v2:
> -Drop register range names (Stephen)
> -Fix yaml errors (Rob)
> Changes in v3:
> -Add new compatible string for dp-hdcp
> -Add descriptions to reg
> -Add minItems/maxItems to reg
> -Make reg depend on the new hdcp compatible string
> Changes in v4:
> -Rebase on Bjorn's multi-dp patchset
> Changes in v4.5:
> -Remove maxItems from reg (Rob)
> -Remove leading zeros in example (Rob)
> Changes in v5:
> -None
> Changes in v6:
> -Rebased: modify minItems instead of adding it as new line.
> 
> ---
>  .../devicetree/bindings/display/msm/dp-controller.yaml| 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dp-controller.example.dtb:
 displayport-controller@ae9: reg: [[183042048, 512], [183042560, 512], 
[183043072, 3072], [183046144, 1024], [183047168, 1024], [183308288, 372], 
[183373824, 44]] is too long
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.example.dtb:
 edp@aea: reg: [[183107584, 512], [183108096, 512], [183108608, 3072], 
[183111680, 1024]] is too short
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dp-controller.yaml

doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230118193015.911074-9-markyac...@google.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



[Freedreno] [PATCH v3] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Jessica Zhang
Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied if the LM/DSPP
blocks were reallocated during modeset or after a suspend/resume.

Changes in V2:
- Fixed commit message

Changes in V3:
- Added mention of suspend/resume case back to commit message

Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 
---
 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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
 
 
-   if (!state->color_mgmt_changed)
+   if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
 
for (i = 0; i < cstate->num_mixers; i++) {
-- 
2.39.0



Re: [Freedreno] [PATCH v2] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Jessica Zhang




On 1/18/2023 11:29 AM, Abhinav Kumar wrote:



On 1/18/2023 8:41 AM, Jessica Zhang wrote:

Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied if the LM/DSPP
blocks were reallocated during modeset.


This was in addition to the suspend/resume case.

So CTM needs to be reapplied in case of suspend/resume OR LM/DSPP block 
reallocation.


To cover both of these we are adding the needs_modeset check


Hi Abhinav,

Acked. Will add back mention of suspend/resume case.

Thanks,

Jessica Zhang





Changes in V2:
- Fixed commit message

Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 
---
  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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct 
drm_crtc *crtc)

  int i;
-    if (!state->color_mgmt_changed)
+    if (!state->color_mgmt_changed && 
!drm_atomic_crtc_needs_modeset(state))

  return;
  for (i = 0; i < cstate->num_mixers; i++) {


Re: [Freedreno] [RFC PATCH v3 1/3] drm: Introduce solid fill property for drm plane

2023-01-18 Thread Jessica Zhang




On 1/18/2023 10:57 AM, Harry Wentland wrote:

On 1/4/23 18:40, Jessica Zhang wrote:

Add support for solid_fill property to drm_plane. In addition, add
support for setting and getting the values for solid_fill.

solid_fill holds data for supporting solid fill planes. The property
accepts an RGB323232 value and the driver data is formatted as such:

struct drm_solid_fill {
u32 r;
u32 g;
u32 b;
};


Rather than special-casing this would it make sense to define this
as a single pixel of a FOURCC property?

I.e., something like this:

struct drm_solid_fill_info {
u32 format; /* FOURCC value */
u64 value; /* FOURCC pixel value */
}

That removes some ambiguity how the value should be interpreted, i.e.,
it can be interpreted like a single pixel of the specified FOURCC format.

It might also make sense to let drivers advertise the supported
FOURCC formats for solid_fill planes.


Hi Harry,

The initial v1 of this RFC had support for taking in a format and such, 
but it was decided that just supporting RGB323232 would work too.


Here's the original thread discussing it [1], but to summarize, the work 
needed to convert the solid fill color to RGB is trivial (as it's just a 
single pixel of data). In addition, supporting various formats for 
solid_fill would add complexity as we'd have to communicate which 
formats are supported.


[1] 
https://lists.freedesktop.org/archives/dri-devel/2022-November/379148.html




Is there an implementation for this in a corresponding canonical
upstream userspace project, to satisfy [1]? If not, what is the plan
for this? If so, please point to the corresponding patches.


The use case we're trying to support here is the Android HWC SOLID_FILL 
hint [1], though it can also be used to address the Wayland single pixel 
FB protocol [2]. I'm also planning to add an IGT test to show an example 
of end to end usage.


[1] 
https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/master/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl#52


[2] 
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/104


Thanks,

Jessica Zhang



[1] 
https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements

Harry



To enable solid fill planes, userspace must assigned solid_fill to a
property blob containing the following information:

struct drm_solid_fill_info {
u8 version;
u32 r, g, b;
};

Changes in V2:
- Changed solid_fill property to a property blob (Simon, Dmitry)
- Added drm_solid_fill struct (Simon)
- Added drm_solid_fill_info struct (Simon)

Changes in V3:
- Corrected typo in drm_solid_fill struct documentation

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic_state_helper.c |  9 
  drivers/gpu/drm/drm_atomic_uapi.c | 59 +++
  drivers/gpu/drm/drm_blend.c   | 17 +++
  include/drm/drm_blend.h   |  1 +
  include/drm/drm_plane.h   | 43 +
  5 files changed, 129 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..c96fd1f2ad99 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -253,6 +253,11 @@ void __drm_atomic_helper_plane_state_reset(struct 
drm_plane_state *plane_state,
plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
  
+	if (plane_state->solid_fill_blob) {

+   drm_property_blob_put(plane_state->solid_fill_blob);
+   plane_state->solid_fill_blob = NULL;
+   }
+
if (plane->color_encoding_property) {
if (!drm_object_property_get_default_value(&plane->base,
   
plane->color_encoding_property,
@@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
drm_plane *plane,
if (state->fb)
drm_framebuffer_get(state->fb);
  
+	if (state->solid_fill_blob)

+   drm_property_blob_get(state->solid_fill_blob);
+
state->fence = NULL;
state->commit = NULL;
state->fb_damage_clips = NULL;
@@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct 
drm_plane_state *state)
drm_crtc_commit_put(state->commit);
  
  	drm_property_blob_put(state->fb_damage_clips);

+   drm_property_blob_put(state->solid_fill_blob);
  }
  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
  
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c

index c06d0639d552..8a1d2fb7a757 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -316,6 +316,55 @@ drm_atomic_set_crtc_for_connector(struct 
drm_connector_state *conn_state,
  }
  EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
  
+static voi

Re: [Freedreno] [PATCH v6 2/2] drm/msm/dp: enhance dp controller isr

2023-01-18 Thread Stephen Boyd
Quoting Doug Anderson (2023-01-18 10:29:59)
> Hi,
>
> On Tue, Dec 27, 2022 at 6:16 PM Kuogee Hsieh  wrote:
> > +
> > if (isr & DP_INTR_AUX_ERROR) {
> > aux->aux_error_num = DP_AUX_ERR_PHY;
> > dp_catalog_aux_clear_hw_interrupts(aux->catalog);
> > +   ret = IRQ_HANDLED;
> > }
>
> The end result of the above is a weird mix of "if" and "else if" for
> no apparent reason. All except one of them just updates the exact same
> variable so doing more than one is mostly useless. If you made it
> consistently with "else" then the whole thing could be much easier,
> like this (untested):

Totally agreed. I even asked that when I posted the RFC[1]!

"Can we also simplify the aux handlers to be a big pile of
if-else-if conditions that don't overwrite the 'aux_error_num'? That
would simplify the patch below."

> > @@ -425,17 +464,15 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
> >
> > /* no interrupts pending, return immediately */
> > if (!isr)
> > -   return;
> > +   return IRQ_NONE;
> >
> > if (!aux->cmd_busy)
> > -   return;
> > +   return IRQ_NONE;
> >
> > if (aux->native)
> > -   dp_aux_native_handler(aux, isr);
> > +   return dp_aux_native_handler(aux, isr);
> > else
> > -   dp_aux_i2c_handler(aux, isr);
> > -
> > -   complete(&aux->comp);
> > +   return dp_aux_i2c_handler(aux, isr);
>
> Personally, I wouldn't have done it this way. I guess that means I
> disagree with Stephen. I'm not dead-set against this way and it's fine
> if you want to continue with it. If I were doing it, though, then I
> would always return IRQ_HANDLED IF dp_catalog_aux_get_irq() returned
> anything non-zero. Why? Officially if dp_catalog_aux_get_irq() returns
> something non-zero then you know for sure that there was an interrupt
> for this device and officially you have "handled" it by acking it,
> since dp_catalog_aux_get_irq() acks all the bits that it returns. That
> means that even if dp_aux_native_handler() or dp_aux_i2c_handler()
> didn't do anything with the interrupt you at least know that it was
> for us (so if the IRQ is shared we properly report back to the IRQ
> subsystem) and that it won't keep firing over and over (because we
> acked it).

I'm primarily concerned with irq storms taking down the system. Can that
happen here? If not, then returning IRQ_NONE is not really useful. The
overall IRQ for DP looks to be level, because the driver requests the
IRQ that way. The aux interrupt status bits look to be edge style
interrupts though, because the driver acks them in the handler. I guess
that means the edges come in and latch into the interrupt status
register so the driver has to ack all of them to drop the IRQ level for
the overall DP interrupt? If the driver only acked the bits it looked at
instead of all interrupt bits in the register, then the level would
never go down for the IRQ if an unhandled interrupt bit was present like
'DP_INTR_PLL_UNLOCKED'. That would mean we would hit spurious IRQ
handling very quickly if that interrupt bit was ever seen.

But the driver is acking all interrupts, so probably trying to work
IRQ_NONE into this code is not very useful? The only thing it would
catch is DP_INTR_PLL_UNLOCKED being set over and over again, which seems
unlikely. Of course, why is this driver unmasking interrupt bits it
doesn't care about? That may be leading to useless interrupt handling in
this driver if some interrupt bit is unmasked but never looked at. Can
that be fixed in another patch?

>
> NOTE: I still like having the complete() call in
> dp_aux_native_handler() and dp_aux_i2c_handler() and, to me, that part
> of this patch is worthwhile. That makes it more obvious that the code
> is truly expecting that complete to be called for all error cases as
> well as transfer finished.
>

I think it may be required. We don't want to allow DP_INTR_PLL_UNLOCKED
to complete() the transfer.

[1] 
https://lore.kernel.org/all/CAE-0n5100eGC0c09oq4B3M=ahtkw5+wglgss1jm91scyz5w...@mail.gmail.com/


[Freedreno] [PATCH v6 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new HDCP
helpers.

Cc: Stephen Boyd 
Cc: Abhinav Kumar 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-15-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-15-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-11-s...@poorly.run
 #v5

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge

[1] 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run

---
 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c   |  48 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |   6 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  52 +++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 108 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |  16 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 456 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  29 ++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  20 +-
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  32 +-
 drivers/gpu/drm/msm/msm_atomic.c|  15 +
 14 files changed, 772 insertions(+), 21 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 61ca0c0757bc..9d9a66d9156c 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed..a73e7b858af2 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 5e35033ba3e4..e97d27edbb13 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"
 
 #define DEBUG_NAME "msm_dp"
 
@@ -25,6 +27,7 @@ struct dp_debug_private {
struct dp_link *link;
struct dp_panel *panel;
struct drm_connector *connector;
+   struct dp_hdcp *hdcp;
struct device *dev;
struct drm_device *drm_dev;
 
@@ -196,6 +199,35 @@ static int dp_test_active_open(struct inode *inode,
inode->i_private);
 }
 
+static ssize_t dp_hdcp_key_write(struct file *file, const char __user *ubuf,
+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret;
+   struct dp_debug_private *debug = file->private_data;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+ 

[Freedreno] [PATCH v6 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller. Now that these are supported, change the
compatible string to "dp-hdcp".

Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-14-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-14-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-10-s...@poorly.run
 #v5

Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream

---
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 178efaaa89ec..6f6fe5cb6563 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -817,6 +817,14 @@ &mdss_dp {
pinctrl-names = "default";
pinctrl-0 = <&dp_hot_plug_det>;
data-lanes = <0 1>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x175>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 &pm6150_adc {
-- 
2.39.0.246.g2a6d74b583-goog



[Freedreno] [PATCH v6 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

We'll use a new compatible string for this since the fields are optional.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-13-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-13-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-13-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-13-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/2025202153.117244-1-s...@poorly.run
 #v4.5
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-9-s...@poorly.run
 #v5

Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.

---
 .../devicetree/bindings/display/msm/dp-controller.yaml| 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index f2515af8256f..17d741f9af86 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -24,13 +24,15 @@ properties:
   - qcom,sm8350-dp
 
   reg:
-minItems: 4
+minItems: 5
 items:
   - description: ahb register block
   - description: aux register block
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -154,7 +156,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <&mdss>;
 interrupts = <12>;
 clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
-- 
2.39.0.246.g2a6d74b583-goog



[Freedreno] [PATCH v6 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-8-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-8-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-8-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-8-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-8-s...@poorly.run
 #v5

Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.

---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  60 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 348 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 952 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |  31 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 270 ++---
 8 files changed, 445 insertions(+), 1270 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 69ecf2a3d6c6..a4397f066a3e 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2909,6 +2910,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2925,12 +2930,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ &state->base,
+ &dig_port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -2976,7 +2979,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ &state->base,
+ &dig_port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3004,13 +3014,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   stru

[Freedreno] [PATCH v6 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

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-7-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-7-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-7-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-7-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-7-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased

---
 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7c7253a2541c..13a4153bb76e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -492,6 +492,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -499,8 +500,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, &hdcp_cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, &hdcp2_cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55..61a862ae1f28 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, &capable);
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, &capable);
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   

[Freedreno] [PATCH v6 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-6-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-6-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-6-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-6-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-6-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None

---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000a..0a20bc41be55 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = &connector->hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(&dev_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(&dev_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
drm_WARN_ON(&dev_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(&dig_port->hdcp_mutex);
mutex_unlock(&hdcp->mutex);
return ret;
-- 
2.39.0.246.g2a6d74b583-goog



[Freedreno] [PATCH v6 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Cc: Abhinav Kumar 
Acked-by: Jani Nikula 
Reviewed-by: Abhinav Kumar 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-5-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-5-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-5-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-5-s...@poorly.run
 #v5

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 

---
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1109 +
 include/drm/display/drm_hdcp.h|  168 +++-
 include/drm/display/drm_hdcp_helper.h |   30 +-
 3 files changed, 1305 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index ce92f1cac251..de8c006b9cda 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -512,3 +517,1107 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+ 

[Freedreno] [PATCH v6 03/10] drm/hdcp: Update property value on content type and user changes

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch updates the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

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-4-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-4-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-4-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-4-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-4-s...@poorly.run

Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c

---
 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index a3896b0904b5..ce92f1cac251 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -485,21 +485,30 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return true;
 
/*
-* 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
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((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)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
-- 
2.39.0.246.g2a6d74b583-goog



[Freedreno] [PATCH v6 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-01-18 Thread Mark Yacoub
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.
+   */
+   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)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 18f0

[Freedreno] [PATCH v6 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-01-18 Thread Mark Yacoub
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.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -482,9 +497,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 8a473199c4bf..a2067cbae2d5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -123,8 +123,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_atomic_check(conn, state);
-
if (!new_state->crtc)
return 0;
 
@@ -140,8 +138,8 @@ int intel_digital_connector_atomic_check(struct 
drm_connect

[Freedreno] [PATCH v6 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-01-18 Thread Mark Yacoub
From: Mark Yacoub 

Hello,

I rebased this series which is authored by Sean Paul.

A major rebase conflict was that drm/drm_hdcp was split to drm/display/drm_hdcp 
& drm/display/drm_hdcp_helper.

Another major one was in msm dp where drm_connector was no longer tracked, but 
it's replaced by msm_dp_bridge to carry over its functionalities.

The first 4 patches modify DRM. They've been reviewed.
Patches 5-7 are intel-only. Only patch 7 hasn't been reviewed.
Patches 8-10 are msm-only. Only patch 9 hasn't been reviewed.

Thanks,
Mark

Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |8 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1202 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   60 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  348 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1028 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   36 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  270 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   48 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   52 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |  108 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |   16 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  456 +++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   29 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   20 +-
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   32 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   15 +
 include/drm/display/drm_hdcp.h|  168 ++-
 include/drm/display/drm_hdcp_helper.h |   33 +-
 28 files changed, 2667 insertions(+), 1354 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.39.0.246.g2a6d74b583-goog



Re: [Freedreno] [PATCH v2] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Abhinav Kumar




On 1/18/2023 8:41 AM, Jessica Zhang wrote:

Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied if the LM/DSPP
blocks were reallocated during modeset.


This was in addition to the suspend/resume case.

So CTM needs to be reapplied in case of suspend/resume OR LM/DSPP block 
reallocation.


To cover both of these we are adding the needs_modeset check



Changes in V2:
- Fixed commit message

Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 
---
  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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
  
  
-	if (!state->color_mgmt_changed)

+   if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
  
  	for (i = 0; i < cstate->num_mixers; i++) {


Re: [Freedreno] [RFC PATCH v3 1/3] drm: Introduce solid fill property for drm plane

2023-01-18 Thread Harry Wentland
On 1/4/23 18:40, Jessica Zhang wrote:
> Add support for solid_fill property to drm_plane. In addition, add
> support for setting and getting the values for solid_fill.
> 
> solid_fill holds data for supporting solid fill planes. The property
> accepts an RGB323232 value and the driver data is formatted as such:
> 
> struct drm_solid_fill {
>   u32 r;
>   u32 g;
>   u32 b;
> };

Rather than special-casing this would it make sense to define this
as a single pixel of a FOURCC property?

I.e., something like this:

struct drm_solid_fill_info {
u32 format; /* FOURCC value */
u64 value; /* FOURCC pixel value */
}

That removes some ambiguity how the value should be interpreted, i.e.,
it can be interpreted like a single pixel of the specified FOURCC format.

It might also make sense to let drivers advertise the supported
FOURCC formats for solid_fill planes.

Is there an implementation for this in a corresponding canonical
upstream userspace project, to satisfy [1]? If not, what is the plan
for this? If so, please point to the corresponding patches.

[1] 
https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements

Harry

> 
> To enable solid fill planes, userspace must assigned solid_fill to a
> property blob containing the following information:
> 
> struct drm_solid_fill_info {
>   u8 version;
>   u32 r, g, b;
> };
> 
> Changes in V2:
> - Changed solid_fill property to a property blob (Simon, Dmitry)
> - Added drm_solid_fill struct (Simon)
> - Added drm_solid_fill_info struct (Simon)
> 
> Changes in V3:
> - Corrected typo in drm_solid_fill struct documentation
> 
> Signed-off-by: Jessica Zhang 
> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  9 
>  drivers/gpu/drm/drm_atomic_uapi.c | 59 +++
>  drivers/gpu/drm/drm_blend.c   | 17 +++
>  include/drm/drm_blend.h   |  1 +
>  include/drm/drm_plane.h   | 43 +
>  5 files changed, 129 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> b/drivers/gpu/drm/drm_atomic_state_helper.c
> index dfb57217253b..c96fd1f2ad99 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -253,6 +253,11 @@ void __drm_atomic_helper_plane_state_reset(struct 
> drm_plane_state *plane_state,
>   plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>   plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>  
> + if (plane_state->solid_fill_blob) {
> + drm_property_blob_put(plane_state->solid_fill_blob);
> + plane_state->solid_fill_blob = NULL;
> + }
> +
>   if (plane->color_encoding_property) {
>   if (!drm_object_property_get_default_value(&plane->base,
>  
> plane->color_encoding_property,
> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
> drm_plane *plane,
>   if (state->fb)
>   drm_framebuffer_get(state->fb);
>  
> + if (state->solid_fill_blob)
> + drm_property_blob_get(state->solid_fill_blob);
> +
>   state->fence = NULL;
>   state->commit = NULL;
>   state->fb_damage_clips = NULL;
> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct 
> drm_plane_state *state)
>   drm_crtc_commit_put(state->commit);
>  
>   drm_property_blob_put(state->fb_damage_clips);
> + drm_property_blob_put(state->solid_fill_blob);
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> b/drivers/gpu/drm/drm_atomic_uapi.c
> index c06d0639d552..8a1d2fb7a757 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -316,6 +316,55 @@ drm_atomic_set_crtc_for_connector(struct 
> drm_connector_state *conn_state,
>  }
>  EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>  
> +static void drm_atomic_convert_solid_fill_info(struct drm_solid_fill *out,
> + struct drm_solid_fill_info *in)
> +{
> + out->r = in->r;
> + out->g = in->g;
> + out->b = in->b;
> +}
> +
> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
> + struct drm_property_blob *blob)
> +{
> + int ret = 0;
> + int blob_version;
> +
> + if (blob == state->solid_fill_blob)
> + return 0;
> +
> + drm_property_blob_put(state->solid_fill_blob);
> + state->solid_fill_blob = NULL;
> +
> + memset(&state->solid_fill, 0, sizeof(state->solid_fill));
> +
> + if (blob) {
> + if (blob->length != sizeof(struct drm_solid_fill_info)) {
> + drm_dbg_atomic(state->plane->dev,
> + "[PLANE:%d:%s] bad solid fill blob 
> length: %zu\n",
> + state->plane->base.id, 
> state->plane->name,
> + blob

Re: [Freedreno] [RFC PATCH] drm/msm/dpu: enable DPU_MDP_AUDIO_SELECT for sc8180x

2023-01-18 Thread Abhinav Kumar




On 1/15/2023 6:00 AM, Dmitry Baryshkov wrote:

According to the discussion ([1]) on the mailing list, platforms before
sm8250 (and derivatives) should program HDMI_DP_CORE_SELECT register to
route audio to the DP ports. Enable DPU_MDP_AUDIO_SELECT on sc8180x to
program correponding register.

[1] 
https://lore.kernel.org/all/f86504ba-835a-6e30-6c30-8bb89b135...@quicinc.com/

Signed-off-by: Dmitry Baryshkov 


Yes, I confirm this is correct, hence

Reviewed-by: Abhinav Kumar 

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

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 2664fa3665b0..b94b0a772ca8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -550,7 +550,7 @@ static const struct dpu_mdp_cfg sc8180x_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
.base = 0x0, .len = 0x45C,
-   .features = 0,
+   .features = BIT(DPU_MDP_AUDIO_SELECT),
.highest_bank_bit = 0x3,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},


Re: [Freedreno] [PATCH v6 2/2] drm/msm/dp: enhance dp controller isr

2023-01-18 Thread Doug Anderson
Hi,

On Tue, Dec 27, 2022 at 6:16 PM Kuogee Hsieh  wrote:
>
> dp_display_irq_handler() is the main isr handler with the helps
> of two sub isr, dp_aux_isr and dp_ctrl_isr, to service all DP
> interrupts on every irq triggered. Current all three isr does
> not return IRQ_HANDLED if there are any interrupts it had
> serviced. This patch fix this ambiguity by having all isr
> return IRQ_HANDLED if there are interrupts had been serviced
> or IRQ_NONE otherwise.
>
> Changes in v5:
> -- move complete into dp_aux_native_handler()
> -- move complete into dp_aux_i2c_handler()
> -- restore null ctrl check at isr
> -- return IRQ_NODE directly
>
> Signed-off-by: Kuogee Hsieh 
> Suggested-by: Stephen Boyd 
> ---
>  drivers/gpu/drm/msm/dp/dp_aux.c | 95 
> ++---
>  drivers/gpu/drm/msm/dp/dp_aux.h |  2 +-
>  drivers/gpu/drm/msm/dp/dp_ctrl.c| 12 -
>  drivers/gpu/drm/msm/dp/dp_ctrl.h|  2 +-
>  drivers/gpu/drm/msm/dp/dp_display.c | 16 +--
>  5 files changed, 89 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
> index cc3efed..d01ff45 100644
> --- a/drivers/gpu/drm/msm/dp/dp_aux.c
> +++ b/drivers/gpu/drm/msm/dp/dp_aux.c
> @@ -162,45 +162,84 @@ static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private 
> *aux,
> return i;
>  }
>
> -static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
> +static irqreturn_t dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
>  {
> -   if (isr & DP_INTR_AUX_I2C_DONE)
> +   irqreturn_t ret = IRQ_NONE;
> +
> +   if (isr & DP_INTR_AUX_I2C_DONE) {
> aux->aux_error_num = DP_AUX_ERR_NONE;
> -   else if (isr & DP_INTR_WRONG_ADDR)
> +   ret = IRQ_HANDLED;
> +   } else if (isr & DP_INTR_WRONG_ADDR) {
> aux->aux_error_num = DP_AUX_ERR_ADDR;
> -   else if (isr & DP_INTR_TIMEOUT)
> +   ret = IRQ_HANDLED;
> +   } else if (isr & DP_INTR_TIMEOUT) {
> aux->aux_error_num = DP_AUX_ERR_TOUT;
> -   if (isr & DP_INTR_NACK_DEFER)
> +   ret = IRQ_HANDLED;
> +   }
> +
> +   if (isr & DP_INTR_NACK_DEFER) {
> aux->aux_error_num = DP_AUX_ERR_NACK;
> +   ret = IRQ_HANDLED;
> +   }
> +
> if (isr & DP_INTR_AUX_ERROR) {
> aux->aux_error_num = DP_AUX_ERR_PHY;
> dp_catalog_aux_clear_hw_interrupts(aux->catalog);
> +   ret = IRQ_HANDLED;
> }

The end result of the above is a weird mix of "if" and "else if" for
no apparent reason. All except one of them just updates the exact same
variable so doing more than one is mostly useless. If you made it
consistently with "else" then the whole thing could be much easier,
like this (untested):

static irqreturn_t dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
{
if (isr & DP_INTR_AUX_ERROR) {
aux->aux_error_num = DP_AUX_ERR_PHY;
dp_catalog_aux_clear_hw_interrupts(aux->catalog);
} else if (isr & DP_INTR_NACK_DEFER) {
aux->aux_error_num = DP_AUX_ERR_NACK;
} else if (isr & DP_INTR_AUX_I2C_DONE) {
aux->aux_error_num = DP_AUX_ERR_NONE;
} else if (isr & DP_INTR_WRONG_ADDR) {
aux->aux_error_num = DP_AUX_ERR_ADDR;
} else if (isr & DP_INTR_TIMEOUT) {
aux->aux_error_num = DP_AUX_ERR_TOUT;
} else {
return IRQ_NONE;
}

complete(&aux->comp);

return IRQ_HANDLED;
}

Note that I changed the order to make sure that the behavior was
exactly the same (previously later tests without the "if" would
override "aux_error_num" so I moved them first. Also previously
dp_catalog_aux_clear_hw_interrupts() would always be called for the
PHY error even if other errors were present so my new proposal
preserves this behavior.


> +
> +   if (ret == IRQ_HANDLED)
> +   complete(&aux->comp);
> +
> +   return ret;
>  }
>
> -static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
> +static irqreturn_t dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
>  {
> +   irqreturn_t ret = IRQ_NONE;
> +
> if (isr & DP_INTR_AUX_I2C_DONE) {
> if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER))
> aux->aux_error_num = DP_AUX_ERR_NACK;
> else
> aux->aux_error_num = DP_AUX_ERR_NONE;
> -   } else {
> -   if (isr & DP_INTR_WRONG_ADDR)
> -   aux->aux_error_num = DP_AUX_ERR_ADDR;
> -   else if (isr & DP_INTR_TIMEOUT)
> -   aux->aux_error_num = DP_AUX_ERR_TOUT;
> -   if (isr & DP_INTR_NACK_DEFER)
> -   aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
> -   if (isr & DP_INTR_I2C_NACK)
> -   aux->aux_error_num = DP_AUX_ERR_NACK;
> -   if (isr & DP_INTR_I2C_DEFER)
> -   aux->aux_error_num = DP_AUX_ERR_DEFER;

[Freedreno] [PATCH v9 2/2] dt-bindings: msm: dsi-controller-main: Document clocks on a per compatible basis

2023-01-18 Thread Bryan O'Donoghue
Each compatible has a different set of clocks which are associated with it.
Add in the list of clocks for each compatible.

Acked-by: Rob Herring 
Acked-by: Krzysztof Kozlowski 
Signed-off-by: Bryan O'Donoghue 
---
 .../display/msm/dsi-controller-main.yaml  | 218 --
 1 file changed, 201 insertions(+), 17 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 35668caa190c4..ad1ba15b74c19 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -9,9 +9,6 @@ title: Qualcomm Display DSI controller
 maintainers:
   - Krishna Manikandan 
 
-allOf:
-  - $ref: "../dsi-controller.yaml#"
-
 properties:
   compatible:
 oneOf:
@@ -50,22 +47,23 @@ properties:
 maxItems: 1
 
   clocks:
-items:
-  - description: Display byte clock
-  - description: Display byte interface clock
-  - description: Display pixel clock
-  - description: Display core clock
-  - description: Display AHB clock
-  - description: Display AXI clock
+description: |
+  Several clocks are used, depending on the variant. Typical ones are::
+   - bus:: Display AHB clock.
+   - byte:: Display byte clock.
+   - byte_intf:: Display byte interface clock.
+   - core:: Display core clock.
+   - core_mss:: Core MultiMedia SubSystem clock.
+   - iface:: Display AXI clock.
+   - mdp_core:: MDP Core clock.
+   - mnoc:: MNOC clock
+   - pixel:: Display pixel clock.
+minItems: 3
+maxItems: 9
 
   clock-names:
-items:
-  - const: byte
-  - const: byte_intf
-  - const: pixel
-  - const: core
-  - const: iface
-  - const: bus
+minItems: 3
+maxItems: 9
 
   phys:
 maxItems: 1
@@ -161,6 +159,192 @@ required:
   - assigned-clock-parents
   - ports
 
+allOf:
+  - $ref: ../dsi-controller.yaml#
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,apq8064-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 7
+clock-names:
+  items:
+- const: iface
+- const: bus
+- const: core_mmss
+- const: src
+- const: byte
+- const: pixel
+- const: core
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,msm8916-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 6
+clock-names:
+  items:
+- const: mdp_core
+- const: iface
+- const: bus
+- const: byte
+- const: pixel
+- const: core
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,msm8953-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 6
+clock-names:
+  items:
+- const: mdp_core
+- const: iface
+- const: bus
+- const: byte
+- const: pixel
+- const: core
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,msm8974-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 7
+clock-names:
+  items:
+- const: mdp_core
+- const: iface
+- const: bus
+- const: byte
+- const: pixel
+- const: core
+- const: core_mmss
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,msm8996-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 7
+clock-names:
+  items:
+- const: mdp_core
+- const: byte
+- const: iface
+- const: bus
+- const: core_mmss
+- const: pixel
+- const: core
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,msm8998-dsi-ctrl
+then:
+  properties:
+clocks:
+  maxItems: 6
+clock-names:
+  items:
+- const: byte
+- const: byte_intf
+- const: pixel
+- const: core
+- const: iface
+- const: bus
+
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - qcom,sc7180-dsi-ctrl
+  - qcom,sc7280-dsi-ctrl
+  - qcom,sm8250-dsi-ctrl
+  - qcom,sm8150-dsi-ctrl
+  - qcom,sm8250-dsi-ctrl
+  - qcom,sm8350-dsi-ctrl
+  - qcom,sm8450-dsi-ctrl
+  - qcom,sm8550-dsi-ctrl
+then:
+  properties:
+   

[Freedreno] [PATCH v9 1/2] dt-bindings: msm: dsi-controller-main: Add compatible strings for every current SoC

2023-01-18 Thread Bryan O'Donoghue
Currently we do not differentiate between the various users of the
qcom,mdss-dsi-ctrl. The driver is flexible enough to operate from one
compatible string but, the hardware does have some significant differences
in the number of clocks.

To facilitate documenting the clocks add the following compatible strings

- qcom,apq8064-dsi-ctrl
- qcom,msm8916-dsi-ctrl
- qcom,msm8953-dsi-ctrl
- qcom,msm8974-dsi-ctrl
- qcom,msm8996-dsi-ctrl
- qcom,msm8998-dsi-ctrl
- qcom,sc7180-dsi-ctrl
- qcom,sc7280-dsi-ctrl
- qcom,sdm660-dsi-ctrl
- qcom,sdm845-dsi-ctrl
- qcom,sm8150-dsi-ctrl
- qcom,sm8250-dsi-ctrl
- qcom,sm8350-dsi-ctrl
- qcom,sm8450-dsi-ctrl
- qcom,sm8550-dsi-ctrl
- qcom,qcm2290-dsi-ctrl

Deprecate qcom,dsi-ctrl-6g-qcm2290 in favour of the desired format while we
do so.

Several MDSS yaml files exist which document the dsi sub-node.
For each existing SoC MDSS yaml, provide the right dsi compat string.

Acked-by: Rob Herring 
Signed-off-by: Bryan O'Donoghue 
---
 .../display/msm/dsi-controller-main.yaml  | 30 ---
 .../bindings/display/msm/qcom,mdss.yaml   |  3 +-
 .../display/msm/qcom,msm8998-mdss.yaml|  8 +++--
 .../display/msm/qcom,sc7180-mdss.yaml |  6 ++--
 .../display/msm/qcom,sc7280-mdss.yaml |  6 ++--
 .../display/msm/qcom,sdm845-mdss.yaml |  8 +++--
 .../display/msm/qcom,sm8150-mdss.yaml |  8 +++--
 .../display/msm/qcom,sm8250-mdss.yaml |  8 +++--
 .../display/msm/qcom,sm8350-mdss.yaml |  6 ++--
 .../display/msm/qcom,sm8450-mdss.yaml |  8 +++--
 10 files changed, 65 insertions(+), 26 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 6e2fd6e9fa7f0..35668caa190c4 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -14,9 +14,31 @@ allOf:
 
 properties:
   compatible:
-enum:
-  - qcom,mdss-dsi-ctrl
-  - qcom,dsi-ctrl-6g-qcm2290
+oneOf:
+  - items:
+  - enum:
+  - qcom,apq8064-dsi-ctrl
+  - qcom,msm8916-dsi-ctrl
+  - qcom,msm8953-dsi-ctrl
+  - qcom,msm8974-dsi-ctrl
+  - qcom,msm8996-dsi-ctrl
+  - qcom,msm8998-dsi-ctrl
+  - qcom,qcm2290-dsi-ctrl
+  - qcom,sc7180-dsi-ctrl
+  - qcom,sc7280-dsi-ctrl
+  - qcom,sdm660-dsi-ctrl
+  - qcom,sdm845-dsi-ctrl
+  - qcom,sm8150-dsi-ctrl
+  - qcom,sm8250-dsi-ctrl
+  - qcom,sm8350-dsi-ctrl
+  - qcom,sm8450-dsi-ctrl
+  - qcom,sm8550-dsi-ctrl
+  - const: qcom,mdss-dsi-ctrl
+  - items:
+  - enum:
+  - dsi-ctrl-6g-qcm2290
+  - const: qcom,mdss-dsi-ctrl
+deprecated: true
 
   reg:
 maxItems: 1
@@ -149,7 +171,7 @@ examples:
  #include 
 
  dsi@ae94000 {
-   compatible = "qcom,mdss-dsi-ctrl";
+   compatible = "qcom,sc7180-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x400>;
reg-names = "dsi_ctrl";
 
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
index ba0460268731b..c194bea46c72f 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -94,7 +94,8 @@ patternProperties:
 type: object
 properties:
   compatible:
-const: qcom,mdss-dsi-ctrl
+contains:
+  const: qcom,mdss-dsi-ctrl
 
   "^phy@[1-9a-f][0-9a-f]*$":
 type: object
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
index 8b82eef28162c..3c2b6ed98a568 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml
@@ -46,7 +46,9 @@ patternProperties:
 type: object
 properties:
   compatible:
-const: qcom,mdss-dsi-ctrl
+items:
+  - const: qcom,msm8998-dsi-ctrl
+  - const: qcom,mdss-dsi-ctrl
 
   "^phy@[0-9a-f]+$":
 type: object
@@ -128,7 +130,7 @@ examples:
 };
 
 dsi@c994000 {
-compatible = "qcom,mdss-dsi-ctrl";
+compatible = "qcom,msm8998-dsi-ctrl", "qcom,mdss-dsi-ctrl";
 reg = <0x0c994000 0x400>;
 reg-names = "dsi_ctrl";
 
@@ -198,7 +200,7 @@ examples:
 };
 
 dsi@c996000 {
-compatible = "qcom,mdss-dsi-ctrl";
+compatible = "qcom,msm8998-dsi-ctrl", "qcom,mdss-dsi-ctrl";
 reg = <0x0c996000 0x400>;
 reg-names = "dsi_ctrl";
 
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml 
b/Docu

[Freedreno] [PATCH v9 0/2] mdss-dsi-ctrl binding and dts fixes

2023-01-18 Thread Bryan O'Donoghue
V9:
- Adds Rob's RB to #1
- Fixes two check splats - Dmitry

V8:
- Squash first and last patch to fix bisectability

link: 
https://lore.kernel.org/linux-arm-msm/167388664232.594279.4607492026981202284.r...@kernel.org/T/#u

V7:
- The bulk of the patches for this series have been merged.
  There are still four patches to be pushed/updated.
- Adds clocks for msm8974 - Dmitry
- Adds compat strings for sm8150, sm8350, sm8450, sm8550 - Dmitry
- Changes last patch in series to state - Rob
  compatible:
contains:
  const: qcom,mdss-dsi-ctrl

link: 
https://lore.kernel.org/linux-arm-msm/20221223021025.1646636-1-bryan.odonog...@linaro.org/

V6:
- Squashes a number of patches per Krzysztof's comments on bisectability
- Adds in Acked-by Rob and Krzysztof 

V5:
- Adds compat strings to bindings/display/msm/qcom,SoC-mdss.yaml - Dmitry
- Re-orders simple fixes to the start of the series to allow backports - Dmitry 
- VDDA and drop of node-names - Krzysztof
- Deprecates qcom,dsi-ctrl-6g-qcm2290 - Krzysztof, Dmitry
- Expands set of updated files to include new msm8953 - bod
- Converts to agreed compat string qcom,SoC-dsi-ctrl hence
  -  - qcom,mdss-dsi-ctrl-msm8996
  +  - qcom,msm8996-dsi-ctrl
- Adds RB where indicated for the compat strings.
V4:
- Moves the update of the example from patch #5 to patch #4

V3:
- Moves declaration of mdss-dsi-ctrl into compat string declaration
  patch - Krzysztof, Dmitry
- Renames qcm-2290 compat string to agreed compat "qcom,socname-dsi-ctrl"
  Dmirty, Krzysztof
- Adds empty line after if clause in yaml control flow section - Dmirty
- Adds Rb/Ack - Krzysztof, Dmitry, Doug, David
- vdd*
  Looking into this some more, I don't believe vdd, vdda, vddio ought to be
  required properties. Its up to the PCB manufacturer and the panel in-use
  how that panel is powered. Powering the panel is not something that
  even necessarily needs to be done from the dsi-ctrl driver.
  Originally marking vdd* as required in the .txt was an error, its not a
  SoC level dtsi requirement.
- clock-names
  Rather than replicate the clock-name in each if block I listed them with
  a specific description from a similar reference in usb/qcom,dwc3.yaml.
 
https://lore.kernel.org/linux-arm-msm/eb80681f-2e0b-605f-0444-ec65562f7...@linaro.org/

V2:
https://www.spinics.net/lists/linux-arm-msm/msg116326.html

- Moves the DSI PHY changes to a different later series.
  There are enough dsi-controller-main changes to justify its own
  standalone series.

- The original phy-name binding change given discussion with Rob and
  Krzysztof became its own standalone series that has since been merged.
  https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg403214.html

- Retains the drop of power-domain from yaml as a required property.
  I dug into the available dtsi. The apq8064 doesn't appear to have any
  GDSC which can be attached as a power-domain, which means the
  power-domain requirement is not universal across the various silicon
  versions.

- Adds Dmitry's RB to power-domain drop

- For the clock declarations I've
  * I noticed that the simple change I had worked for msm8939 but
subsquently broke other dtsi which drove a bigger change to document
the clocks on a per compatible basis.
  * Added compat strings in yaml.
  * Moved the allOf down later in the file to acomodate the if/then.
  * Number of clocks validated on a per compatible basis
  * The driver code which doesn't care about the number of clocks
can still operate on the mdss-dsi-ctrl compat but the dts checks will
validate against the compat string and yaml.

- vdd descriptions
  Took the previous text I missed from the .txt file - Krzysztof, Dmitry
  Adds vdd, vdda and vddio to the required list. This exposes warnings in
  existing dtsi but the previous .txt declared these regulators as
  required. - Krzysztof
 
V1:
This series fixes up a number of dtbs checks which are being flagged adding
in the msm8939 dtsi.


When converting from .txt to .yaml a number of the parameters for the older
msm8916 silicon were not transmitted into the yaml.

Adding in the msm8939 which is a near 1:1 copy of the msm8916 in terms of
dtsi triggers a rake of dtbs checks as a result.

https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg403211.html

Bryan O'Donoghue (2):
  dt-bindings: msm: dsi-controller-main: Add compatible strings for
every current SoC
  dt-bindings: msm: dsi-controller-main: Document clocks on a per
compatible basis

 .../display/msm/dsi-controller-main.yaml  | 248 --
 .../bindings/display/msm/qcom,mdss.yaml   |   3 +-
 .../display/msm/qcom,msm8998-mdss.yaml|   8 +-
 .../display/msm/qcom,sc7180-mdss.yaml |   6 +-
 .../display/msm/qcom,sc7280-mdss.yaml |   6 +-
 .../display/msm/qcom,sdm845-mdss.yaml |   8 +-
 .../display/msm/qcom,sm8150-mdss.yaml |   8 +-
 .../display/msm/qcom,sm8250-mdss.yaml |   8 +-
 .../display/ms

Re: [Freedreno] [PATCH v7 03/11] dt-bindings: display/msm: add core clock to the mdss bindings

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 06:12:35 +0200, Dmitry Baryshkov wrote:
> Add (optional) core clock to the mdss bindings to let the MDSS driver
> access hardware registers before MDP driver probes.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/qcom,mdss.yaml   | 32 +--
>  1 file changed, 22 insertions(+), 10 deletions(-)
> 

Reviewed-by: Rob Herring 


Re: [Freedreno] [PATCH 4/4] dt-binbings: display/msm: dsi-controller-main: add missing supplies

2023-01-18 Thread Rob Herring
On Wed, Jan 18, 2023 at 10:41 AM Rob Herring  wrote:
>
>
> On Wed, 18 Jan 2023 05:24:32 +0200, Dmitry Baryshkov wrote:
> > Describe DSI supplies used on apq8064 (vdda-supply) and msm8994/96
> > (vcca-supply).
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >  .../bindings/display/msm/dsi-controller-main.yaml | 8 
> >  1 file changed, 8 insertions(+)
> >
>
> Acked-by: Rob Herring 

That is, with the typo in the subject fixed.


Re: [Freedreno] [PATCH] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Jessica Zhang




On 1/17/2023 6:16 PM, Dmitry Baryshkov wrote:

On Wed, 18 Jan 2023 at 04:14, Jessica Zhang  wrote:


Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied after a
suspend/resume.


.. or if the LM/DSPP blocks were reallocated by resource allocation
during the modeset.


Hi Dmitry,

Acked -- will change the commit message in a v2.

Thanks,

Jessica Zhang





Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 
---
  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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
 int i;


-   if (!state->color_mgmt_changed)
+   if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
 return;

 for (i = 0; i < cstate->num_mixers; i++) {
--
2.39.0




--
With best wishes
Dmitry


[Freedreno] [PATCH v2] drm/msm/dpu: Reapply CTM if modeset is needed

2023-01-18 Thread Jessica Zhang
Add a !drm_atomic_crtc_needs_modeset() check to
_dpu_crtc_setup_cp_blocks() so that CTM is reapplied if the LM/DSPP
blocks were reallocated during modeset.

Changes in V2:
- Fixed commit message

Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/23
Signed-off-by: Jessica Zhang 
---
 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 13ce321283ff..aa120a230222 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
 
 
-   if (!state->color_mgmt_changed)
+   if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
 
for (i = 0; i < cstate->num_mixers; i++) {
-- 
2.39.0



Re: [Freedreno] [PATCH 4/4] dt-binbings: display/msm: dsi-controller-main: add missing supplies

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:24:32 +0200, Dmitry Baryshkov wrote:
> Describe DSI supplies used on apq8064 (vdda-supply) and msm8994/96
> (vcca-supply).
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/dsi-controller-main.yaml | 8 
>  1 file changed, 8 insertions(+)
> 

Acked-by: Rob Herring 


Re: [Freedreno] [PATCH 3/4] dt-bindings: display/msm: dsi-controller-main: allow using fewer lanes

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:24:31 +0200, Dmitry Baryshkov wrote:
> Some platforms might use less than full 4 lanes DSI interface. Allow
> using any amount of lanes starting from 1 up to 4.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../devicetree/bindings/display/msm/dsi-controller-main.yaml  | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring 


Re: [Freedreno] [PATCH 2/4] dt-bindings: display/msm: dsi-controller-main: account for apq8064

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:24:30 +0200, Dmitry Baryshkov wrote:
> APQ8064 requires listing four clocks in the assigned-clocks /
> assigned-clock-parents properties. Account for that.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/dsi-controller-main.yaml | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring 


Re: [Freedreno] [PATCH 1/4] dt-bindings: display/msm: dsi-controller-main: remove #address/#size-cells

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:24:29 +0200, Dmitry Baryshkov wrote:
> Stop mentioning #address-cells/#size-cells which are defined in
> display/dsi-controller.yaml. Use unevaluatedProperties instead of
> additionalProperties to allow skipping properties defined in other
> schema files.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/dsi-controller-main.yaml   | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 

Acked-by: Rob Herring 


Re: [Freedreno] [PATCH 2/4] dt-bindings: display/msm: qcom, sc8280xp-mdss: add DP / eDP child nodes

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:17:16 +0200, Dmitry Baryshkov wrote:
> Describe DP and eDP devices as subdevices to the MDSS on SC8280XP
> platform.
> 
> Fixes: 45af56bf2d74 ("dt-bindings: display/msm: Add binding for SC8280XP 
> MDSS")
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/qcom,sc8280xp-mdss.yaml  | 8 
>  1 file changed, 8 insertions(+)
> 

Acked-by: Rob Herring 


Re: [Freedreno] [PATCH 1/4] dt-bindings: display/msm: add qcom, sc8280xp-edp to list of eDP devices

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 05:17:15 +0200, Dmitry Baryshkov wrote:
> Add qcom,sc8280xp-edp to the list of eDP devices, unblocking `aux-bus'
> property and fobidding `#sound-dai-cells' property. Also since
> sc8280xp-edp, overriding sc8280xp-dp, will contain 5 reg resources, drop
> the reg contraint (as it will become equivalent to the top-level one,
> requiring min 4 and max 5 reg entries).
> 
> Fixes: b6f8c4debc00 ("dt-bindings: msm/dp: Add SDM845 and SC8280XP 
> compatibles")
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../devicetree/bindings/display/msm/dp-controller.yaml | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 

Acked-by: Rob Herring 


[Freedreno] [PATCH] drm/msm/gpu: Add proper DEVFREQ_GOV_SIMPLE_ONDEMAND dependency

2023-01-18 Thread Arnd Bergmann
From: Arnd Bergmann 

DRM_MSM can no longer be built when devfreq is disabled:

WARNING: unmet direct dependencies detected for DEVFREQ_GOV_SIMPLE_ONDEMAND
  Depends on [n]: PM_DEVFREQ [=n]
  Selected by [y]:
  - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM [=n] || SOC_IMX5 
[=n] || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && 
(QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=n] || QCOM_LLCC [=n]=n) 
&& (QCOM_COMMAND_DB [=y] || QCOM_COMMAND_DB [=y]=n)

In file included from drivers/gpu/drm/msm/msm_gpu.h:18,
 from drivers/gpu/drm/msm/adreno/adreno_gpu.h:15,
 from drivers/gpu/drm/msm/adreno/adreno_device.c:9:
drivers/gpu/drm/msm/msm_drv.h:238:45: error: field 'gpu_devfreq_config' has 
incomplete type
  238 | struct devfreq_simple_ondemand_data gpu_devfreq_config;
  | ^~

Device drivers should never select user-visible options, especially
in other subsystems. This one can simply be expressed as a Kconfig
'depends on' statement, though a better approach would be to
let the driver keep working even without devfreq.

Note that the same symbol selects a bunch of other drivers that
should probably be turned into 'depends on' as well, but doing so
has the potential to introduce regressions, so I'm not touching
that here.

Fixes: 6563f60f14cb ("drm/msm/gpu: Add devfreq tuning debugfs")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/msm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 871870ddf7ec..7f6f5202648a 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -9,6 +9,7 @@ config DRM_MSM
depends on QCOM_OCMEM || QCOM_OCMEM=n
depends on QCOM_LLCC || QCOM_LLCC=n
depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
+   depends on DEVFREQ_GOV_SIMPLE_ONDEMAND
select IOMMU_IO_PGTABLE
select QCOM_MDT_LOADER if ARCH_QCOM
select REGULATOR
@@ -23,7 +24,6 @@ config DRM_MSM
select SHMEM
select TMPFS
select QCOM_SCM
-   select DEVFREQ_GOV_SIMPLE_ONDEMAND
select WANT_DEV_COREDUMP
select SND_SOC_HDMI_CODEC if SND_SOC
select SYNC_FILE
-- 
2.39.0



Re: [Freedreno] [PATCH v7 04/11] dt-bindings: display/msm: rename mdss nodes to display-subsystem

2023-01-18 Thread Rob Herring


On Wed, 18 Jan 2023 06:12:36 +0200, Dmitry Baryshkov wrote:
> Follow the 'generic names' rule and rename mdss nodes to
> display-subsystem.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
> 
> Note, this patch might generate warnings in qcom,sm6115-mdss and
> qcom,qcm2290-mdss examples, but they have been fixed by the commit
> e5266ca38294 ("dt-bindings: display: msm: Rename mdss node name in
> example")
> 
> See https://gitlab.freedesktop.org/drm/msm/-/commit/e5266ca38294
> 
> 
> ---
>  .../devicetree/bindings/display/msm/mdss-common.yaml  | 8 
>  .../devicetree/bindings/display/msm/qcom,mdss.yaml| 5 -
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring 


Re: [Freedreno] [PATCH 00/13] drm/bridge: lt9611: several fixes and improvements

2023-01-18 Thread Neil Armstrong
Hi,

On Wed, 18 Jan 2023 10:16:45 +0200, Dmitry Baryshkov wrote:
> A series of patches to fix mode programming for the Lontium lt9611
> DSI-to-HDMI bridge (found e.g. on the Thundercomm RB3/Dragonboard845c
> platform).
> 
> Changes since v2:
>  - Rewrote mode_valid callback to be more explicit.
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-next)

[01/13] drm/bridge: lt9611: fix sleep mode setup

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=ae2d329f104b75a0a78dcaded29fe6283289cdf9
[02/13] drm/bridge: lt9611: fix HPD reenablement

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=a7790f6bd38f3642b60ae3504a2c749135b89451
[03/13] drm/bridge: lt9611: fix polarity programming

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=0b157efa384ea417304b1da284ee2f603c607fc3
[04/13] drm/bridge: lt9611: fix programming of video modes

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=ad188aa47edaa033a270e1a3efae43836ff47569
[05/13] drm/bridge: lt9611: fix clock calculation

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=2576eb26494eb0509dd9ceb0cd27771a7a5e3674
[06/13] drm/bridge: lt9611: pass a pointer to the of node

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=b0a7f8736789935f62d6df32d441cdf05a5c05d2
[07/13] drm/bridge: lt9611: rework the mode_set function

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=fad97f2811933085adb3dc3b13b2e1cf985295b1
[08/13] drm/bridge: lt9611: attach to the next bridge

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=0c3997b0fec74a828ef258851e2fb260e3e7620c
[09/13] drm/bridge: lt9611: fix sync polarity for DVI output

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=0c7474694849b44cfdf4e22b41e8f3eb85d78709
[10/13] drm/bridge: lt9611: simplify video timings programming

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=6b089d5e35d6daf3d348a3fbd8974d4ed896a231
[11/13] drm/bridge: lt9611: rework infoframes handling

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=84cf74d99f88bc476678254310baffddfba68bb6
[12/13] drm/bridge: lt9611: stop filtering modes via the table

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=4914cbc4fbadf0a3bcad9b0b09b3d8005a3dcd9e
[13/13] drm/bridge: lt9611: properly program the dual host mode

https://cgit.freedesktop.org/drm/drm-misc/commit/?id=5e83f359d9805b3561f160afafddfa7572155d1c

-- 
Neil


Re: [Freedreno] drm/msm/dsi: correct byte intf clock rate for 14nm DSI PHY

2023-01-18 Thread Konrad Dybcio



On 18.01.2023 14:00, Dmitry Baryshkov wrote:
> According to the vendor kernel, byte intf clock rate should be a half of
> the byte clock only when DSI PHY version is above 2.0 (in other words,
> 10nm PHYs and later) and only if PHY is used in D-PHY mode. Currently
> MSM DSI code handles only the second part of the clause (C-PHY vs
> D-PHY), skipping DSI PHY version check, which causes issues on some of
> 14nm DSI PHY platforms (e.g. qcm2290).
> 
> Move divisor selection to DSI PHY code, pass selected divisor through
> shared timings and set byte intf clock rate accordingly.
> 
> Cc: Loic Poulain 
> Signed-off-by: Dmitry Baryshkov 
> ---
> 
> This patch is a reimplementation of [1] in a slightly more flexible way.
> 
> [1] 
> https://patchwork.kernel.org/project/linux-arm-msm/patch/1642586079-12472-1-git-send-email-loic.poul...@linaro.org/
> 
> ---
Tested-by: Konrad Dybcio  # SM6115P J606F
Reviewed-by: Konrad Dybcio 

Interestingly enough, this seems to somehow solve the issue
where I had to manually set the brightness again after the
first frame transfer or get a black screen otherwise.. 

Konrad
>  drivers/gpu/drm/msm/dsi/dsi.h |  1 +
>  drivers/gpu/drm/msm/dsi/dsi_host.c| 14 ++
>  drivers/gpu/drm/msm/dsi/phy/dsi_phy.c |  4 
>  3 files changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index 1a551cc0e889..bd3763a5d723 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -141,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
>   u32 clk_post;
>   u32 clk_pre;
>   bool clk_pre_inc_by_2;
> + bool byte_intf_clk_div_2;
>  };
>  
>  struct msm_dsi_phy_clk_request {
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 7c21f2fba520..18fa30e1e858 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -122,6 +122,7 @@ struct msm_dsi_host {
>   struct clk *byte_intf_clk;
>  
>   unsigned long byte_clk_rate;
> + unsigned long byte_intf_clk_rate;
>   unsigned long pixel_clk_rate;
>   unsigned long esc_clk_rate;
>  
> @@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev)
>  
>  int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
>  {
> - unsigned long byte_intf_rate;
>   int ret;
>  
>   DBG("Set clk rates: pclk=%d, byteclk=%lu",
> @@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host 
> *msm_host)
>   }
>  
>   if (msm_host->byte_intf_clk) {
> - /* For CPHY, byte_intf_clk is same as byte_clk */
> - if (msm_host->cphy_mode)
> - byte_intf_rate = msm_host->byte_clk_rate;
> - else
> - byte_intf_rate = msm_host->byte_clk_rate / 2;
> -
> - ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate);
> + ret = clk_set_rate(msm_host->byte_intf_clk, 
> msm_host->byte_intf_clk_rate);
>   if (ret) {
>   pr_err("%s: Failed to set rate byte intf clk, %d\n",
>  __func__, ret);
> @@ -2394,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   goto unlock_ret;
>   }
>  
> + msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
> + if (phy_shared_timings->byte_intf_clk_div_2)
> + msm_host->byte_intf_clk_rate /= 2;
> +
>   msm_dsi_sfpb_config(msm_host, true);
>  
>   ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
> diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c 
> b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
> index 57445a5dc816..bb09cbe8ff86 100644
> --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
> +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
> @@ -350,6 +350,8 @@ int msm_dsi_dphy_timing_calc_v3(struct 
> msm_dsi_dphy_timing *timing,
>   timing->shared_timings.clk_pre_inc_by_2 = 0;
>   }
>  
> + timing->shared_timings.byte_intf_clk_div_2 = true;
> +
>   timing->ta_go = 3;
>   timing->ta_sure = 0;
>   timing->ta_get = 4;
> @@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct 
> msm_dsi_dphy_timing *timing,
>   tmax = 255;
>   timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 
> 1) + tmin;
>  
> + timing->shared_timings.byte_intf_clk_div_2 = true;
> +
>   DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
>   timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
>   timing->clk_zero, timing->clk_trail, timing->clk_prepare, 
> timing->hs_exit,
> 


Re: [Freedreno] [PATCH] arm64: dts: qcom: sm8350: use qcom, sm8350-dsi-ctrl compatibles

2023-01-18 Thread Konrad Dybcio



On 18.01.2023 04:20, Dmitry Baryshkov wrote:
> Add the per-SoC (qcom,sm8350-dsi-ctrl) compatible strings to DSI nodes
> to follow the pending DSI bindings changes.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
Reviewed-by: Konrad Dybcio 

Konrad
>  arch/arm64/boot/dts/qcom/sm8350.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi 
> b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> index 703ba3d81e82..a066566b6ea9 100644
> --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> @@ -2883,7 +2883,7 @@ dpu_intf1_out: endpoint {
>   };
>  
>   mdss_dsi0: dsi@ae94000 {
> - compatible = "qcom,mdss-dsi-ctrl";
> + compatible = "qcom,sm8350-dsi-ctrl", 
> "qcom,mdss-dsi-ctrl";
>   reg = <0 0x0ae94000 0 0x400>;
>   reg-names = "dsi_ctrl";
>  
> @@ -2978,7 +2978,7 @@ mdss_dsi0_phy: phy@ae94400 {
>   };
>  
>   mdss_dsi1: dsi@ae96000 {
> - compatible = "qcom,mdss-dsi-ctrl";
> + compatible = "qcom,sm8350-dsi-ctrl", 
> "qcom,mdss-dsi-ctrl";
>   reg = <0 0x0ae96000 0 0x400>;
>   reg-names = "dsi_ctrl";
>  


[Freedreno] [PATCH] drm/msm/dsi: simplify pixel clk rate handling

2023-01-18 Thread Dmitry Baryshkov
Move a call to dsi_calc_pclk() out of calc_clk_rate directly towards
msm_dsi_host_get_phy_clk_req(). It is called for both 6g and v2 hosts.

Also, while we are at it, replace another dsi_get_pclk_rate() invocation
with using the stored value at msm_host->pixel_clk_rate.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi.h  |  4 ++--
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |  2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c | 24 
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index bd3763a5d723..93ec54478eb6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -129,8 +129,8 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, 
uint64_t *iova);
 int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
 int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
 int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
 void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct 
mipi_dsi_host *host);
 void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
 struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index 44be4a88aa83..5106e66846c3 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -51,7 +51,7 @@ struct msm_dsi_host_cfg_ops {
void* (*tx_buf_get)(struct msm_dsi_host *msm_host);
void (*tx_buf_put)(struct msm_dsi_host *msm_host);
int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova);
-   int (*calc_clk_rate)(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+   int (*calc_clk_rate)(struct msm_dsi_host *msm_host);
 };
 
 struct msm_dsi_cfg_handler {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 18fa30e1e858..7d99a108bff6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -616,28 +616,21 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
 
 }
 
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
 {
-   if (!msm_host->mode) {
-   pr_err("%s: mode not set\n", __func__);
-   return -EINVAL;
-   }
-
-   dsi_calc_pclk(msm_host, is_bonded_dsi);
msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
+
return 0;
 }
 
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
 {
u32 bpp = dsi_get_bpp(msm_host->format);
u64 pclk_bpp;
unsigned int esc_mhz, esc_div;
unsigned long byte_mhz;
 
-   dsi_calc_pclk(msm_host, is_bonded_dsi);
-
-   pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp;
+   pclk_bpp = msm_host->pixel_clk_rate * bpp;
do_div(pclk_bpp, 8);
msm_host->src_clk_rate = pclk_bpp;
 
@@ -2292,7 +2285,14 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host 
*host,
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
int ret;
 
-   ret = cfg_hnd->ops->calc_clk_rate(msm_host, is_bonded_dsi);
+   if (!msm_host->mode) {
+   pr_err("%s: mode not set\n", __func__);
+   return;
+   }
+
+   dsi_calc_pclk(msm_host, is_bonded_dsi);
+
+   ret = cfg_hnd->ops->calc_clk_rate(msm_host);
if (ret) {
pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
return;
-- 
2.39.0



[Freedreno] [PATCH] drm/msm/dsi: correct byte intf clock rate for 14nm DSI PHY

2023-01-18 Thread Dmitry Baryshkov
According to the vendor kernel, byte intf clock rate should be a half of
the byte clock only when DSI PHY version is above 2.0 (in other words,
10nm PHYs and later) and only if PHY is used in D-PHY mode. Currently
MSM DSI code handles only the second part of the clause (C-PHY vs
D-PHY), skipping DSI PHY version check, which causes issues on some of
14nm DSI PHY platforms (e.g. qcm2290).

Move divisor selection to DSI PHY code, pass selected divisor through
shared timings and set byte intf clock rate accordingly.

Cc: Loic Poulain 
Signed-off-by: Dmitry Baryshkov 
---

This patch is a reimplementation of [1] in a slightly more flexible way.

[1] 
https://patchwork.kernel.org/project/linux-arm-msm/patch/1642586079-12472-1-git-send-email-loic.poul...@linaro.org/

---
 drivers/gpu/drm/msm/dsi/dsi.h |  1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c| 14 ++
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c |  4 
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 1a551cc0e889..bd3763a5d723 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -141,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
u32 clk_post;
u32 clk_pre;
bool clk_pre_inc_by_2;
+   bool byte_intf_clk_div_2;
 };
 
 struct msm_dsi_phy_clk_request {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7c21f2fba520..18fa30e1e858 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -122,6 +122,7 @@ struct msm_dsi_host {
struct clk *byte_intf_clk;
 
unsigned long byte_clk_rate;
+   unsigned long byte_intf_clk_rate;
unsigned long pixel_clk_rate;
unsigned long esc_clk_rate;
 
@@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev)
 
 int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
 {
-   unsigned long byte_intf_rate;
int ret;
 
DBG("Set clk rates: pclk=%d, byteclk=%lu",
@@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
}
 
if (msm_host->byte_intf_clk) {
-   /* For CPHY, byte_intf_clk is same as byte_clk */
-   if (msm_host->cphy_mode)
-   byte_intf_rate = msm_host->byte_clk_rate;
-   else
-   byte_intf_rate = msm_host->byte_clk_rate / 2;
-
-   ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate);
+   ret = clk_set_rate(msm_host->byte_intf_clk, 
msm_host->byte_intf_clk_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
   __func__, ret);
@@ -2394,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
 
+   msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
+   if (phy_shared_timings->byte_intf_clk_div_2)
+   msm_host->byte_intf_clk_rate /= 2;
+
msm_dsi_sfpb_config(msm_host, true);
 
ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 57445a5dc816..bb09cbe8ff86 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -350,6 +350,8 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing 
*timing,
timing->shared_timings.clk_pre_inc_by_2 = 0;
}
 
+   timing->shared_timings.byte_intf_clk_div_2 = true;
+
timing->ta_go = 3;
timing->ta_sure = 0;
timing->ta_get = 4;
@@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing 
*timing,
tmax = 255;
timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 
1) + tmin;
 
+   timing->shared_timings.byte_intf_clk_div_2 = true;
+
DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
timing->clk_zero, timing->clk_trail, timing->clk_prepare, 
timing->hs_exit,
-- 
2.39.0



Re: [Freedreno] [PATCH v2] drm/msm/dpu: Remove some unused variables

2023-01-18 Thread Marijn Suijten
On 2023-01-18 17:18:33, Jiapeng Chong wrote:
> Variables 'sc8280xp_regdma' and 'sm8350_regdma' are defined in the
> dpu_hw_catalog.c file, but not used elsewhere, so remove these unused
> variables.
> 
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2029:37: warning: unused
> variable 'sc8280xp_regdma'.
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2053:37: warning: unused
> variable 'sm8350_regdma'.
> 
> Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3722
> Reported-by: Abaci Robot 
> Signed-off-by: Jiapeng Chong 

Does this need a Fixes tag?

> ---
> Changes in v2:
>   -Adding the regdma entries to .dma_cfg of these chipsets.

Don't forget to change the title of this patch; now you're not removing
unused variables anymore.

- Marijn

>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> 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 0f3da480b066..3318e1d18a0e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -2677,6 +2677,8 @@ static const struct dpu_mdss_cfg sc8280xp_dpu_cfg = {
>   .intf = sc8280xp_intf,
>   .vbif_count = ARRAY_SIZE(sdm845_vbif),
>   .vbif = sdm845_vbif,
> + .reg_dma_count = 1,
> + .dma_cfg = &sc8280xp_regdma,
>   .perf = &sc8280xp_perf_data,
>   .mdss_irqs = IRQ_SC8280XP_MASK,
>  };
> @@ -2732,7 +2734,7 @@ static const struct dpu_mdss_cfg sm8350_dpu_cfg = {
>   .vbif_count = ARRAY_SIZE(sdm845_vbif),
>   .vbif = sdm845_vbif,
>   .reg_dma_count = 1,
> - .dma_cfg = &sm8250_regdma,
> + .dma_cfg = &sm8350_regdma,
>   .perf = &sm8350_perf_data,
>   .mdss_irqs = IRQ_SM8350_MASK,
>  };
> -- 
> 2.20.1.7.g153144c
> 


[Freedreno] [PATCH v2] drm/msm/dpu: Remove some unused variables

2023-01-18 Thread Jiapeng Chong
Variables 'sc8280xp_regdma' and 'sm8350_regdma' are defined in the
dpu_hw_catalog.c file, but not used elsewhere, so remove these unused
variables.

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2029:37: warning: unused
variable 'sc8280xp_regdma'.
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c:2053:37: warning: unused
variable 'sm8350_regdma'.

Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3722
Reported-by: Abaci Robot 
Signed-off-by: Jiapeng Chong 
---
Changes in v2:
  -Adding the regdma entries to .dma_cfg of these chipsets.

 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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 0f3da480b066..3318e1d18a0e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -2677,6 +2677,8 @@ static const struct dpu_mdss_cfg sc8280xp_dpu_cfg = {
.intf = sc8280xp_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
+   .reg_dma_count = 1,
+   .dma_cfg = &sc8280xp_regdma,
.perf = &sc8280xp_perf_data,
.mdss_irqs = IRQ_SC8280XP_MASK,
 };
@@ -2732,7 +2734,7 @@ static const struct dpu_mdss_cfg sm8350_dpu_cfg = {
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
.reg_dma_count = 1,
-   .dma_cfg = &sm8250_regdma,
+   .dma_cfg = &sm8350_regdma,
.perf = &sm8350_perf_data,
.mdss_irqs = IRQ_SM8350_MASK,
 };
-- 
2.20.1.7.g153144c



Re: [Freedreno] [PATCH v2] drm/probe_helper: sort out poll_running vs poll_enabled

2023-01-18 Thread Laurentiu Palcu
On Wed, Jan 18, 2023 at 01:39:05AM +0200, Dmitry Baryshkov wrote:
> There are two flags attemting to guard connector polling:
> poll_enabled and poll_running. While poll_enabled semantics is clearly
> defined and fully adhered (mark that drm_kms_helper_poll_init() was
> called and not finalized by the _fini() call), the poll_running flag
> doesn't have such clearliness.
> 
> This flag is used only in drm_helper_probe_single_connector_modes() to
> guard calling of drm_kms_helper_poll_enable, it doesn't guard the
> drm_kms_helper_poll_fini(), etc. Change it to only be set if the polling
> is actually running. Tie HPD enablement to this flag.
> 
> This fixes the following warning reported after merging the HPD series:
> 
> Hot plug detection already enabled
> WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_bridge.c:1257 
> drm_bridge_hpd_enable+0x94/0x9c [drm]
> Modules linked in: videobuf2_memops snd_soc_simple_card 
> snd_soc_simple_card_utils fsl_imx8_ddr_perf videobuf2_common 
> snd_soc_imx_spdif adv7511 etnaviv imx8m_ddrc imx_dcss mc cec nwl_dsi gov
> CPU: 2 PID: 9 Comm: kworker/u8:0 Not tainted 6.2.0-rc2-15208-g25b283acd578 #6
> Hardware name: NXP i.MX8MQ EVK (DT)
> Workqueue: events_unbound deferred_probe_work_func
> pstate: 6005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : drm_bridge_hpd_enable+0x94/0x9c [drm]
> lr : drm_bridge_hpd_enable+0x94/0x9c [drm]
> sp : 89ef3740
> x29: 89ef3740 x28: 09331f00 x27: 1000
> x26: 0020 x25: 81148ed8 x24: 0a8fe000
> x23: fffd x22: 05086348 x21: 81133ee0
> x20: 0550d800 x19: 05086288 x18: 0006
> x17:  x16: 896ef008 x15: 972891004260
> x14: 2a1403e19400 x13: 972891004260 x12: 2a1403e19400
> x11: 7100385f29400801 x10: 0aa0 x9 : 88112744
> x8 : 00250b00 x7 : 0003 x6 : 0011
> x5 :  x4 : bd986a48 x3 : 0001
> x2 :  x1 :  x0 : 0025
> Call trace:
>  drm_bridge_hpd_enable+0x94/0x9c [drm]
>  drm_bridge_connector_enable_hpd+0x2c/0x3c [drm_kms_helper]
>  drm_kms_helper_poll_enable+0x94/0x10c [drm_kms_helper]
>  drm_helper_probe_single_connector_modes+0x1a8/0x510 [drm_kms_helper]
>  drm_client_modeset_probe+0x204/0x1190 [drm]
>  __drm_fb_helper_initial_config_and_unlock+0x5c/0x4a4 [drm_kms_helper]
>  drm_fb_helper_initial_config+0x54/0x6c [drm_kms_helper]
>  drm_fbdev_client_hotplug+0xd0/0x140 [drm_kms_helper]
>  drm_fbdev_generic_setup+0x90/0x154 [drm_kms_helper]
>  dcss_kms_attach+0x1c8/0x254 [imx_dcss]
>  dcss_drv_platform_probe+0x90/0xfc [imx_dcss]
>  platform_probe+0x70/0xcc
>  really_probe+0xc4/0x2e0
>  __driver_probe_device+0x80/0xf0
>  driver_probe_device+0xe0/0x164
>  __device_attach_driver+0xc0/0x13c
>  bus_for_each_drv+0x84/0xe0
>  __device_attach+0xa4/0x1a0
>  device_initial_probe+0x1c/0x30
>  bus_probe_device+0xa4/0xb0
>  deferred_probe_work_func+0x90/0xd0
>  process_one_work+0x200/0x474
>  worker_thread+0x74/0x43c
>  kthread+0xfc/0x110
>  ret_from_fork+0x10/0x20
> ---[ end trace  ]---
> 
> Reported-by: Laurentiu Palcu 
> Fixes: c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors")
> Tested-by: Marek Szyprowski 
> Tested-by: Chen-Yu Tsai 
> Signed-off-by: Dmitry Baryshkov 

I gave this a test and the warning is gone. Also, HPD works as expected.

Acked-by: Laurentiu Palcu 
Tested-by: Laurentiu Palcu 

Cheers,
Laurentiu

> ---
> 
> Changes since v1:
> - Fixed drm_kms_helper_enable_hpd() to call enable_hpd() instead of
>   disable_hpd().
> 
> ---
>  drivers/gpu/drm/drm_probe_helper.c | 110 +
>  1 file changed, 63 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 7973f2589ced..04754bb7b131 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -222,6 +222,45 @@ drm_connector_mode_valid(struct drm_connector *connector,
>   return ret;
>  }
>  
> +static void drm_kms_helper_disable_hpd(struct drm_device *dev)
> +{
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + const struct drm_connector_helper_funcs *funcs =
> + connector->helper_private;
> +
> + if (funcs && funcs->disable_hpd)
> + funcs->disable_hpd(connector);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +}
> +
> +static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
> +{
> + bool poll = false;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(c

Re: [Freedreno] [PATCH 12/13] drm/bridge: lt9611: stop filtering modes via the table

2023-01-18 Thread Neil Armstrong

On 18/01/2023 09:16, Dmitry Baryshkov wrote:

The lt9611 bridge can support different modes, it makes no sense to list
them in the table. Drop the table and check the number of interfaces
using the fixed value.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/bridge/lontium-lt9611.c | 49 ++---
  1 file changed, 12 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 82af1f954cc6..c2cd36d926a0 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -84,24 +84,6 @@ static const struct regmap_config lt9611_regmap_config = {
.num_ranges = ARRAY_SIZE(lt9611_ranges),
  };
  
-struct lt9611_mode {

-   u16 hdisplay;
-   u16 vdisplay;
-   u8 vrefresh;
-   u8 lanes;
-   u8 intfs;
-};
-
-static struct lt9611_mode lt9611_modes[] = {
-   { 3840, 2160, 30, 4, 2 }, /* 3840x2160 24bit 30Hz 4Lane 2ports */
-   { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
-   { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
-   { 1920, 1080, 24, 3, 1 },
-   { 720, 480, 60, 4, 1 },
-   { 720, 576, 50, 2, 1 },
-   { 640, 480, 60, 2, 1 },
-};
-
  static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
  {
return container_of(bridge, struct lt9611, bridge);
@@ -603,21 +585,6 @@ static int lt9611_regulator_enable(struct lt9611 *lt9611)
return 0;
  }
  
-static struct lt9611_mode *lt9611_find_mode(const struct drm_display_mode *mode)

-{
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(lt9611_modes); i++) {
-   if (lt9611_modes[i].hdisplay == mode->hdisplay &&
-   lt9611_modes[i].vdisplay == mode->vdisplay &&
-   lt9611_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
-   return <9611_modes[i];
-   }
-   }
-
-   return NULL;
-}
-
  static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
  {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
@@ -832,12 +799,20 @@ static enum drm_mode_status 
lt9611_bridge_mode_valid(struct drm_bridge *bridge,
 const struct 
drm_display_info *info,
 const struct 
drm_display_mode *mode)
  {
-   struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
  
-	if (!lt9611_mode)

-   return MODE_BAD;
-   else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
+   if (mode->hdisplay > 3840)
+   return MODE_BAD_HVALUE;
+
+   if (mode->vdisplay > 2160)
+   return MODE_BAD_VVALUE;
+
+   if (mode->hdisplay == 3840 &&
+   mode->vdisplay == 2160 &&
+   drm_mode_vrefresh(mode) > 30)
+   return MODE_CLOCK_HIGH;
+
+   if (mode->hdisplay > 2000 && !lt9611->dsi1_node)
return MODE_PANEL;
else
return MODE_OK;


Reviewed-by: Neil Armstrong 


[Freedreno] [PATCH 13/13] drm/bridge: lt9611: properly program the dual host mode

2023-01-18 Thread Dmitry Baryshkov
If the bridge is connected using both DSI ports, the driver should use
both of them all the time. Correct programming sequence to always use
dual-port mode if both dsi0 and dsi1 are connected.

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 28 -
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index c2cd36d926a0..276c77b273cd 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -118,7 +118,7 @@ static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
{ 0x8306, 0x0a },
};
 
-   if (mode->hdisplay == 3840)
+   if (lt9611->dsi1_node)
reg_cfg[1].def = 0x03;
 
return regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
@@ -191,16 +191,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
{ 0x832d, 0x38 },
{ 0x8331, 0x08 },
};
-   const struct reg_sequence reg_cfg2[] = {
-   { 0x830b, 0x03 },
-   { 0x830c, 0xd0 },
-   { 0x8348, 0x03 },
-   { 0x8349, 0xe0 },
-   { 0x8324, 0x72 },
-   { 0x8325, 0x00 },
-   { 0x832a, 0x01 },
-   { 0x834a, 0x10 },
-   };
u8 pol = 0x10;
 
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
@@ -209,10 +199,18 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
pol |= 0x1;
regmap_write(lt9611->regmap, 0x831d, pol);
 
-   if (mode->hdisplay == 3840)
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
-   else
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+   if (lt9611->dsi1_node) {
+   unsigned int hact = mode->hdisplay;
+
+   hact >>= 2;
+   hact += 0x50;
+   hact = min(hact, 0x3e0U);
+   regmap_write(lt9611->regmap, 0x830b, hact / 256);
+   regmap_write(lt9611->regmap, 0x830c, hact % 256);
+   regmap_write(lt9611->regmap, 0x8348, hact / 256);
+   regmap_write(lt9611->regmap, 0x8349, hact % 256);
+   }
 
regmap_write(lt9611->regmap, 0x8326, pcr_m);
 
-- 
2.39.0



[Freedreno] [PATCH 11/13] drm/bridge: lt9611: rework infoframes handling

2023-01-18 Thread Dmitry Baryshkov
Rework handling infoframes:
- Write full HDMI AVI infoframe instead of just fixing the VIC value
- Also send the HDMI Vendor Specific infoframe, as recommended by the
  HDMI spec.

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 57 +++--
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1396ab081f61..82af1f954cc6 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -59,7 +59,6 @@ struct lt9611 {
enum drm_connector_status status;
 
u8 edid_buf[EDID_SEG_SIZE];
-   u32 vic;
 };
 
 #define LT9611_PAGE_CONTROL0xff
@@ -352,12 +351,51 @@ static int lt9611_video_check(struct lt9611 *lt9611)
return temp;
 }
 
-static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+static void lt9611_hdmi_set_infoframes(struct lt9611 *lt9611,
+  struct drm_connector *connector,
+  struct drm_display_mode *mode)
 {
-   regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
-   regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
-   regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
+   union hdmi_infoframe infoframe;
+   ssize_t len;
+   u8 iframes = 0x0a; /* UD1 infoframe */
+   u8 buf[32];
+   int ret;
+   int i;
+
+   ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe.avi,
+  connector,
+  mode);
+   if (ret < 0)
+   goto out;
+
+   len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf));
+   if (len < 0)
+   goto out;
+
+   for (i = 0; i < len; i++)
+   regmap_write(lt9611->regmap, 0x8440 + i, buf[i]);
+
+   ret = 
drm_hdmi_vendor_infoframe_from_display_mode(&infoframe.vendor.hdmi,
+ connector,
+ mode);
+   if (ret < 0)
+   goto out;
+
+   len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf));
+   if (len < 0)
+   goto out;
 
+   for (i = 0; i < len; i++)
+   regmap_write(lt9611->regmap, 0x8474 + i, buf[i]);
+
+   iframes |= 0x20;
+
+out:
+   regmap_write(lt9611->regmap, 0x843d, iframes); /* UD1 infoframe */
+}
+
+static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+{
if (is_hdmi)
regmap_write(lt9611->regmap, 0x82d6, 0x8c);
else
@@ -687,9 +725,7 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
struct drm_display_mode *mode;
-   struct hdmi_avi_infoframe avi_frame;
unsigned int postdiv;
-   int ret;
 
connector = drm_atomic_get_new_connector_for_encoder(state, 
bridge->encoder);
if (WARN_ON(!connector))
@@ -710,18 +746,13 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
lt9611_mipi_video_setup(lt9611, mode);
lt9611_pcr_setup(lt9611, mode, postdiv);
 
-   ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
-  connector,
-  mode);
-   if (!ret)
-   lt9611->vic = avi_frame.video_code;
-
if (lt9611_power_on(lt9611)) {
dev_err(lt9611->dev, "power on failed\n");
return;
}
 
lt9611_mipi_input_analog(lt9611);
+   lt9611_hdmi_set_infoframes(lt9611, connector, mode);
lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi);
lt9611_hdmi_tx_phy(lt9611);
 
-- 
2.39.0



[Freedreno] [PATCH 12/13] drm/bridge: lt9611: stop filtering modes via the table

2023-01-18 Thread Dmitry Baryshkov
The lt9611 bridge can support different modes, it makes no sense to list
them in the table. Drop the table and check the number of interfaces
using the fixed value.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 49 ++---
 1 file changed, 12 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 82af1f954cc6..c2cd36d926a0 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -84,24 +84,6 @@ static const struct regmap_config lt9611_regmap_config = {
.num_ranges = ARRAY_SIZE(lt9611_ranges),
 };
 
-struct lt9611_mode {
-   u16 hdisplay;
-   u16 vdisplay;
-   u8 vrefresh;
-   u8 lanes;
-   u8 intfs;
-};
-
-static struct lt9611_mode lt9611_modes[] = {
-   { 3840, 2160, 30, 4, 2 }, /* 3840x2160 24bit 30Hz 4Lane 2ports */
-   { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
-   { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
-   { 1920, 1080, 24, 3, 1 },
-   { 720, 480, 60, 4, 1 },
-   { 720, 576, 50, 2, 1 },
-   { 640, 480, 60, 2, 1 },
-};
-
 static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
 {
return container_of(bridge, struct lt9611, bridge);
@@ -603,21 +585,6 @@ static int lt9611_regulator_enable(struct lt9611 *lt9611)
return 0;
 }
 
-static struct lt9611_mode *lt9611_find_mode(const struct drm_display_mode 
*mode)
-{
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(lt9611_modes); i++) {
-   if (lt9611_modes[i].hdisplay == mode->hdisplay &&
-   lt9611_modes[i].vdisplay == mode->vdisplay &&
-   lt9611_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
-   return <9611_modes[i];
-   }
-   }
-
-   return NULL;
-}
-
 static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
@@ -832,12 +799,20 @@ static enum drm_mode_status 
lt9611_bridge_mode_valid(struct drm_bridge *bridge,
 const struct 
drm_display_info *info,
 const struct 
drm_display_mode *mode)
 {
-   struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 
-   if (!lt9611_mode)
-   return MODE_BAD;
-   else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
+   if (mode->hdisplay > 3840)
+   return MODE_BAD_HVALUE;
+
+   if (mode->vdisplay > 2160)
+   return MODE_BAD_VVALUE;
+
+   if (mode->hdisplay == 3840 &&
+   mode->vdisplay == 2160 &&
+   drm_mode_vrefresh(mode) > 30)
+   return MODE_CLOCK_HIGH;
+
+   if (mode->hdisplay > 2000 && !lt9611->dsi1_node)
return MODE_PANEL;
else
return MODE_OK;
-- 
2.39.0



[Freedreno] [PATCH 07/13] drm/bridge: lt9611: rework the mode_set function

2023-01-18 Thread Dmitry Baryshkov
The mode_set callback is deprectated for drm_bridges in favour of using
atomic_enable callback. Move corresponding code into the function
lt9611_bridge_atomic_enable() and turn lt9611_bridge_pre_enable() into
the proper atomic_pre_enable callback.

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 61 +++--
 1 file changed, 36 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 3b77238ca4af..1b65a573be27 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -713,6 +713,39 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+   struct drm_atomic_state *state = old_bridge_state->base.state;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state;
+   struct drm_crtc_state *crtc_state;
+   struct drm_display_mode *mode;
+   struct hdmi_avi_infoframe avi_frame;
+   unsigned int postdiv;
+   int ret;
+
+   connector = drm_atomic_get_new_connector_for_encoder(state, 
bridge->encoder);
+   if (WARN_ON(!connector))
+   return;
+
+   conn_state = drm_atomic_get_new_connector_state(state, connector);
+   if (WARN_ON(!conn_state))
+   return;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+   if (WARN_ON(!crtc_state))
+   return;
+
+   mode = &crtc_state->adjusted_mode;
+
+   lt9611_mipi_input_digital(lt9611, mode);
+   lt9611_pll_setup(lt9611, mode, &postdiv);
+   lt9611_mipi_video_setup(lt9611, mode);
+   lt9611_pcr_setup(lt9611, mode, postdiv);
+
+   ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
+  connector,
+  mode);
+   if (!ret)
+   lt9611->vic = avi_frame.video_code;
 
if (lt9611_power_on(lt9611)) {
dev_err(lt9611->dev, "power on failed\n");
@@ -856,7 +889,8 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct 
drm_bridge *bridge,
return MODE_OK;
 }
 
-static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
+static void lt9611_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+   struct drm_bridge_state 
*old_bridge_state)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
static const struct reg_sequence reg_cfg[] = {
@@ -884,29 +918,6 @@ lt9611_bridge_atomic_post_disable(struct drm_bridge 
*bridge,
lt9611_sleep_setup(lt9611);
 }
 
-static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
-  const struct drm_display_mode *mode,
-  const struct drm_display_mode *adj_mode)
-{
-   struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
-   struct hdmi_avi_infoframe avi_frame;
-   unsigned int postdiv;
-   int ret;
-
-   lt9611_bridge_pre_enable(bridge);
-
-   lt9611_mipi_input_digital(lt9611, mode);
-   lt9611_pll_setup(lt9611, mode, &postdiv);
-   lt9611_mipi_video_setup(lt9611, mode);
-   lt9611_pcr_setup(lt9611, mode, postdiv);
-
-   ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
-  <9611->connector,
-  mode);
-   if (!ret)
-   lt9611->vic = avi_frame.video_code;
-}
-
 static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
 {
return __lt9611_detect(bridge_to_lt9611(bridge));
@@ -957,11 +968,11 @@ lt9611_atomic_get_input_bus_fmts(struct drm_bridge 
*bridge,
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
.attach = lt9611_bridge_attach,
.mode_valid = lt9611_bridge_mode_valid,
-   .mode_set = lt9611_bridge_mode_set,
.detect = lt9611_bridge_detect,
.get_edid = lt9611_bridge_get_edid,
.hpd_enable = lt9611_bridge_hpd_enable,
 
+   .atomic_pre_enable = lt9611_bridge_atomic_pre_enable,
.atomic_enable = lt9611_bridge_atomic_enable,
.atomic_disable = lt9611_bridge_atomic_disable,
.atomic_post_disable = lt9611_bridge_atomic_post_disable,
-- 
2.39.0



[Freedreno] [PATCH 10/13] drm/bridge: lt9611: simplify video timings programming

2023-01-18 Thread Dmitry Baryshkov
Inline calculated values to simplify the calculation in
lt9611_mipi_video_setup().

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 7f9be74acf0d..1396ab081f61 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -155,12 +155,12 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
hactive = mode->hdisplay;
hsync_len = mode->hsync_end - mode->hsync_start;
hfront_porch = mode->hsync_start - mode->hdisplay;
-   hsync_porch = hsync_len + mode->htotal - mode->hsync_end;
+   hsync_porch = mode->htotal - mode->hsync_start;
 
vactive = mode->vdisplay;
vsync_len = mode->vsync_end - mode->vsync_start;
vfront_porch = mode->vsync_start - mode->vdisplay;
-   vsync_porch = vsync_len + mode->vtotal - mode->vsync_end;
+   vsync_porch = mode->vtotal - mode->vsync_start;
 
regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
-- 
2.39.0



[Freedreno] [PATCH 08/13] drm/bridge: lt9611: attach to the next bridge

2023-01-18 Thread Dmitry Baryshkov
The bindings require that there is a next bridge after the lt9611. If
nothing else it can be the hdmi-connector (as used on the RB3 platform,
see sdm845-db845c.dts).

Bring in the next bridge into the drm bridges chain and attach to it.

Since lt9611 is not anymore the last bridge in the chain, this also
allows us to drop all the !DRM_BRIDGE_ATTACH_NO_CONNECTOR functionality.

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 99 ++---
 1 file changed, 7 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1b65a573be27..773d7a56f86f 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -33,7 +34,7 @@
 struct lt9611 {
struct device *dev;
struct drm_bridge bridge;
-   struct drm_connector connector;
+   struct drm_bridge *next_bridge;
 
struct regmap *regmap;
 
@@ -107,11 +108,6 @@ static struct lt9611 *bridge_to_lt9611(struct drm_bridge 
*bridge)
return container_of(bridge, struct lt9611, bridge);
 }
 
-static struct lt9611 *connector_to_lt9611(struct drm_connector *connector)
-{
-   return container_of(connector, struct lt9611, connector);
-}
-
 static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
 {
const struct reg_sequence reg_cfg[] = {
@@ -581,9 +577,9 @@ static struct lt9611_mode *lt9611_find_mode(const struct 
drm_display_mode *mode)
return NULL;
 }
 
-/* connector funcs */
-static enum drm_connector_status __lt9611_detect(struct lt9611 *lt9611)
+static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
 {
+   struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
unsigned int reg_val = 0;
int connected = 0;
 
@@ -596,12 +592,6 @@ static enum drm_connector_status __lt9611_detect(struct 
lt9611 *lt9611)
return lt9611->status;
 }
 
-static enum drm_connector_status
-lt9611_connector_detect(struct drm_connector *connector, bool force)
-{
-   return __lt9611_detect(connector_to_lt9611(connector));
-}
-
 static int lt9611_read_edid(struct lt9611 *lt9611)
 {
unsigned int temp;
@@ -683,30 +673,6 @@ lt9611_get_edid_block(void *data, u8 *buf, unsigned int 
block, size_t len)
return 0;
 }
 
-static int lt9611_connector_get_modes(struct drm_connector *connector)
-{
-   struct lt9611 *lt9611 = connector_to_lt9611(connector);
-   unsigned int count;
-   struct edid *edid;
-
-   lt9611_power_on(lt9611);
-   edid = drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
-   drm_connector_update_edid_property(connector, edid);
-   count = drm_add_edid_modes(connector, edid);
-   kfree(edid);
-
-   return count;
-}
-
-static enum drm_mode_status
-lt9611_connector_mode_valid(struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
-
-   return lt9611_mode ? MODE_OK : MODE_BAD;
-}
-
 /* bridge funcs */
 static void
 lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -784,21 +750,6 @@ lt9611_bridge_atomic_disable(struct drm_bridge *bridge,
}
 }
 
-static struct
-drm_connector_helper_funcs lt9611_bridge_connector_helper_funcs = {
-   .get_modes = lt9611_connector_get_modes,
-   .mode_valid = lt9611_connector_mode_valid,
-};
-
-static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .detect = lt9611_connector_detect,
-   .destroy = drm_connector_cleanup,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
 static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
 struct device_node *dsi_node)
 {
@@ -834,44 +785,13 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct 
lt9611 *lt9611,
return dsi;
 }
 
-static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 
*lt9611)
-{
-   int ret;
-
-   ret = drm_connector_init(bridge->dev, <9611->connector,
-<9611_bridge_connector_funcs,
-DRM_MODE_CONNECTOR_HDMIA);
-   if (ret) {
-   DRM_ERROR("Failed to initialize connector with drm\n");
-   return ret;
-   }
-
-   drm_connector_helper_add(<9611->connector,
-<9611_bridge_connector_helper_funcs);
-
-   if (!bridge->encoder) {
-   DRM_ERROR("Parent encoder object not found");
-   return -ENODEV;
-   }
-
-   drm_connector_attach_encoder(<961

[Freedreno] [PATCH 09/13] drm/bridge: lt9611: fix sync polarity for DVI output

2023-01-18 Thread Dmitry Baryshkov
Attaching DVI sink to the lt9611 requires different setup. Fix the
register write to make the DVI displays sync onto the correct sync
pulse.

Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 773d7a56f86f..7f9be74acf0d 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -352,13 +352,16 @@ static int lt9611_video_check(struct lt9611 *lt9611)
return temp;
 }
 
-static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611)
+static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
 {
regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
 
-   regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+   if (is_hdmi)
+   regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+   else
+   regmap_write(lt9611->regmap, 0x82d6, 0x0c);
regmap_write(lt9611->regmap, 0x82d7, 0x04);
 }
 
@@ -719,7 +722,7 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
}
 
lt9611_mipi_input_analog(lt9611);
-   lt9611_hdmi_tx_digital(lt9611);
+   lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi);
lt9611_hdmi_tx_phy(lt9611);
 
msleep(500);
-- 
2.39.0



[Freedreno] [PATCH 04/13] drm/bridge: lt9611: fix programming of video modes

2023-01-18 Thread Dmitry Baryshkov
Program the upper part of the hfront_porch into the proper register.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index deb503ca956a..f377052a45a4 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -187,7 +187,8 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
 
regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
 
-   regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256));
+   regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) |
+   ((hfront_porch / 256) << 4));
regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
 }
 
-- 
2.39.0



[Freedreno] [PATCH 03/13] drm/bridge: lt9611: fix polarity programming

2023-01-18 Thread Dmitry Baryshkov
Fix programming of hsync and vsync polarities

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 58f39b279217..deb503ca956a 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -207,7 +207,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
 
/* stage 2 */
{ 0x834a, 0x40 },
-   { 0x831d, 0x10 },
 
/* MK limit */
{ 0x832d, 0x38 },
@@ -222,11 +221,19 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
{ 0x8325, 0x00 },
{ 0x832a, 0x01 },
{ 0x834a, 0x10 },
-   { 0x831d, 0x10 },
-   { 0x8326, 0x37 },
};
+   u8 pol = 0x10;
 
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+   pol |= 0x2;
+   if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+   pol |= 0x1;
+   regmap_write(lt9611->regmap, 0x831d, pol);
+
+   if (mode->hdisplay == 3840)
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
+   else
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
 
switch (mode->hdisplay) {
case 640:
@@ -236,7 +243,7 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
case 3840:
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
+   regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
}
 
-- 
2.39.0



[Freedreno] [PATCH 05/13] drm/bridge: lt9611: fix clock calculation

2023-01-18 Thread Dmitry Baryshkov
Instead of having several fixed values for the pcr register, calculate
it before programming. This allows the bridge to support most of the
display modes.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 32 +++--
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index f377052a45a4..e2799a0df8f8 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -192,8 +192,9 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
 }
 
-static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct 
drm_display_mode *mode)
+static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct 
drm_display_mode *mode, unsigned int postdiv)
 {
+   unsigned int pcr_m = mode->clock * 5 * postdiv / 27000;
const struct reg_sequence reg_cfg[] = {
{ 0x830b, 0x01 },
{ 0x830c, 0x10 },
@@ -236,24 +237,14 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
else
regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
 
-   switch (mode->hdisplay) {
-   case 640:
-   regmap_write(lt9611->regmap, 0x8326, 0x14);
-   break;
-   case 1920:
-   regmap_write(lt9611->regmap, 0x8326, 0x37);
-   break;
-   case 3840:
-   regmap_write(lt9611->regmap, 0x8326, 0x37);
-   break;
-   }
+   regmap_write(lt9611->regmap, 0x8326, pcr_m);
 
/* pcr rst */
regmap_write(lt9611->regmap, 0x8011, 0x5a);
regmap_write(lt9611->regmap, 0x8011, 0xfa);
 }
 
-static int lt9611_pll_setup(struct lt9611 *lt9611, const struct 
drm_display_mode *mode)
+static int lt9611_pll_setup(struct lt9611 *lt9611, const struct 
drm_display_mode *mode, unsigned int *postdiv)
 {
unsigned int pclk = mode->clock;
const struct reg_sequence reg_cfg[] = {
@@ -271,12 +262,16 @@ static int lt9611_pll_setup(struct lt9611 *lt9611, const 
struct drm_display_mode
 
regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
 
-   if (pclk > 15)
+   if (pclk > 15) {
regmap_write(lt9611->regmap, 0x812d, 0x88);
-   else if (pclk > 7)
+   *postdiv = 1;
+   } else if (pclk > 7) {
regmap_write(lt9611->regmap, 0x812d, 0x99);
-   else
+   *postdiv = 2;
+   } else {
regmap_write(lt9611->regmap, 0x812d, 0xaa);
+   *postdiv = 4;
+   }
 
/*
 * first divide pclk by 2 first
@@ -895,14 +890,15 @@ static void lt9611_bridge_mode_set(struct drm_bridge 
*bridge,
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
struct hdmi_avi_infoframe avi_frame;
+   unsigned int postdiv;
int ret;
 
lt9611_bridge_pre_enable(bridge);
 
lt9611_mipi_input_digital(lt9611, mode);
-   lt9611_pll_setup(lt9611, mode);
+   lt9611_pll_setup(lt9611, mode, &postdiv);
lt9611_mipi_video_setup(lt9611, mode);
-   lt9611_pcr_setup(lt9611, mode);
+   lt9611_pcr_setup(lt9611, mode, postdiv);
 
ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
   <9611->connector,
-- 
2.39.0



[Freedreno] [PATCH 06/13] drm/bridge: lt9611: pass a pointer to the of node

2023-01-18 Thread Dmitry Baryshkov
Pass a pointer to the OF node while registering lt9611 MIPI device.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index e2799a0df8f8..3b77238ca4af 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -769,7 +769,7 @@ static const struct drm_connector_funcs 
lt9611_bridge_connector_funcs = {
 static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
 struct device_node *dsi_node)
 {
-   const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
+   const struct mipi_dsi_device_info info = { "lt9611", 0, 
lt9611->dev->of_node};
struct mipi_dsi_device *dsi;
struct mipi_dsi_host *host;
struct device *dev = lt9611->dev;
-- 
2.39.0



[Freedreno] [PATCH 02/13] drm/bridge: lt9611: fix HPD reenablement

2023-01-18 Thread Dmitry Baryshkov
The driver will reset the bridge in the atomic_pre_enable(). However
this will also drop the HPD interrupt state. Instead of resetting the
bridge, properly wake it up. This fixes the HPD interrupt delivery after
the disable/enable cycle.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 2714184cc53f..58f39b279217 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -856,12 +856,18 @@ static enum drm_mode_status 
lt9611_bridge_mode_valid(struct drm_bridge *bridge,
 static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+   static const struct reg_sequence reg_cfg[] = {
+   { 0x8102, 0x12 },
+   { 0x8123, 0x40 },
+   { 0x8130, 0xea },
+   { 0x8011, 0xfa },
+   };
 
if (!lt9611->sleep)
return;
 
-   lt9611_reset(lt9611);
-   regmap_write(lt9611->regmap, 0x80ee, 0x01);
+   regmap_multi_reg_write(lt9611->regmap,
+  reg_cfg, ARRAY_SIZE(reg_cfg));
 
lt9611->sleep = false;
 }
-- 
2.39.0



[Freedreno] [PATCH 01/13] drm/bridge: lt9611: fix sleep mode setup

2023-01-18 Thread Dmitry Baryshkov
On atomic_post_disable the bridge goes to the low power state. However
the code disables too much of the chip, so the HPD event is not being
detected and delivered to the host. Reduce the power saving in order to
get the HPD event.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: Neil Armstrong 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 7c0a99173b39..2714184cc53f 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -448,12 +448,11 @@ static void lt9611_sleep_setup(struct lt9611 *lt9611)
{ 0x8023, 0x01 },
{ 0x8157, 0x03 }, /* set addr pin as output */
{ 0x8149, 0x0b },
-   { 0x8151, 0x30 }, /* disable IRQ */
+
{ 0x8102, 0x48 }, /* MIPI Rx power down */
{ 0x8123, 0x80 },
{ 0x8130, 0x00 },
-   { 0x8100, 0x01 }, /* bandgap power down */
-   { 0x8101, 0x00 }, /* system clk power down */
+   { 0x8011, 0x0a },
};
 
regmap_multi_reg_write(lt9611->regmap,
-- 
2.39.0



[Freedreno] [PATCH 00/13] drm/bridge: lt9611: several fixes and improvements

2023-01-18 Thread Dmitry Baryshkov
A series of patches to fix mode programming for the Lontium lt9611
DSI-to-HDMI bridge (found e.g. on the Thundercomm RB3/Dragonboard845c
platform).

Changes since v2:
 - Rewrote mode_valid callback to be more explicit.

Changes since v1:
 - Fixed the double-DSI check to look for the lt9611->dsi1_node rather
   than lt9611->dsi1, modesetting happens before lt9611->dsi1 is set.

 - Added full dual-DSI support, properly enabling the 4k modes on RB3.

Dmitry Baryshkov (13):
  drm/bridge: lt9611: fix sleep mode setup
  drm/bridge: lt9611: fix HPD reenablement
  drm/bridge: lt9611: fix polarity programming
  drm/bridge: lt9611: fix programming of video modes
  drm/bridge: lt9611: fix clock calculation
  drm/bridge: lt9611: pass a pointer to the of node
  drm/bridge: lt9611: rework the mode_set function
  drm/bridge: lt9611: attach to the next bridge
  drm/bridge: lt9611: fix sync polarity for DVI output
  drm/bridge: lt9611: simplify video timings programming
  drm/bridge: lt9611: rework infoframes handling
  drm/bridge: lt9611: stop filtering modes via the table
  drm/bridge: lt9611: properly program the dual host mode

 drivers/gpu/drm/bridge/lontium-lt9611.c | 340 ++--
 1 file changed, 141 insertions(+), 199 deletions(-)

-- 
2.39.0