Re: [Freedreno] [PATCH v2 2/4] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver

2023-08-17 Thread Bryan O'Donoghue

On 17/08/2023 15:59, Dmitry Baryshkov wrote:

Add the nb7vpq904m, onboard USB-C redriver / retimer.

Signed-off-by: Dmitry Baryshkov 
---
  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 52 +++-
  1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts 
b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 303d07f9c6e5..a4f7a9f9c22c 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -610,6 +610,46 @@ lt9611_out: endpoint {
  /* LS-I2C1 */
   {
status = "okay";
+
+   typec-mux@1c {
+   compatible = "onnn,nb7vpq904m";
+   reg = <0x1c>;
+
+   vcc-supply = <_s4a_1p8>;
+
+   retimer-switch;
+   orientation-switch;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   redriver_usb_con_ss: endpoint {
+   remote-endpoint = 
<_typec_mux_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   redriver_phy_con_ss: endpoint {
+   remote-endpoint = <_1_qmpphy_out>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   redriver_usb_con_sbu: endpoint {
+   remote-endpoint = 
<_typec_sbu_out>;
+   };
+   };
+   };
+   };
  };
  
   {

@@ -1299,7 +1339,7 @@ _1_qmpphy {
  };
  
  _1_qmpphy_out {

-   remote-endpoint = <_typec_mux_in>;
+   remote-endpoint = <_phy_con_ss>;
  };
  
  _2 {

@@ -1388,7 +1428,15 @@ pm8150b_role_switch_in: endpoint {
port@1 {
reg = <1>;
pm8150b_typec_mux_in: endpoint {
-   remote-endpoint = <_1_qmpphy_out>;
+   remote-endpoint = 
<_usb_con_ss>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   pm8150b_typec_sbu_out: endpoint {
+   remote-endpoint = 
<_usb_con_sbu>;
};
};
};


LGTM

Reviewed-by: Bryan O'Donoghue 


Re: [Freedreno] [PATCH 3/3] drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set

2023-08-17 Thread Abhinav Kumar




On 8/17/2023 11:50 AM, Dmitry Baryshkov wrote:

On 08/08/2023 02:49, Abhinav Kumar wrote:



On 6/4/2023 7:45 AM, Dmitry Baryshkov wrote:

The atomic_mode_set() callback only sets the phys_enc's IRQ data. As the
INTF and WB are statically allocated to each encoder/phys_enc, drop the
atomic_mode_set callback and set the IRQs during encoder init.

For the CMD panel usecase some of IRQ indexes depend on the selected
resources. Move setting them to the irq_enable() callback.



The irq_enable() callback is called from the 
dpu_encoder_virt_atomic_enable() after the phys layer's enable.


Thats late.

So lets consider the case where command mode panel's clock is powered 
from bootloader (quite common).


Now, as soon as the tearcheck is configured and interface is ON from 
the phys's enable(), nothing prevents / should prevent the interrupt 
from firing.


Please note that interrupt callbacks are also registered from the 
irq_control(). There is no way the interrupt can fire beforehand (and 
the call chain is dpu_encoder_virt_atomic_enable() -> 
dpu_encoder_resource_control() -> _dpu_encoder_resource_control_helper() 
-> _dpu_encoder_irq_control() -> irq_control().


If we ever want to move irq_control() to be called before phys's 
enable() callbacks, this will be a separate patchset, involving 
refactoring of dpu_encoder_resource_control().




Ack, I will rebase my patches on top of this and re-test it.

Then will give my R-b, tested-by tags by Monday.



So I feel / think mode_set is the correct location to assign these.

I can ack patches 1 and 2 but I think you did those mainly for this 
one, so I would like to get some clarity on this part.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 --
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  5 ---
  .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 32 ---
  .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 13 ++--
  .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c   | 11 +--
  5 files changed, 17 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index cc61f0cf059d..6b5c80dc5967 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1148,8 +1148,6 @@ static void 
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,

  phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
  phys->cached_mode = crtc_state->adjusted_mode;
-    if (phys->ops.atomic_mode_set)
-    phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
  }
  }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

index faf033cd086e..24dbc28be4f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -67,8 +67,6 @@ struct dpu_encoder_phys;
   * @is_master:    Whether this phys_enc is the current master
   *    encoder. Can be switched at enable time. Based
   *    on split_role and current mode (CMD/VID).
- * @atomic_mode_set:    DRM Call. Set a DRM mode.
- *    This likely caches the mode, for use at enable.
   * @enable:    DRM Call. Enable a DRM mode.
   * @disable:    DRM Call. Disable mode.
   * @atomic_check:    DRM Call. Atomic check new DRM state.
@@ -95,9 +93,6 @@ struct dpu_encoder_phys;
  struct dpu_encoder_phys_ops {
  void (*prepare_commit)(struct dpu_encoder_phys *encoder);
  bool (*is_master)(struct dpu_encoder_phys *encoder);
-    void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
-    struct drm_crtc_state *crtc_state,
-    struct drm_connector_state *conn_state);
  void (*enable)(struct dpu_encoder_phys *encoder);
  void (*disable)(struct dpu_encoder_phys *encoder);
  int (*atomic_check)(struct dpu_encoder_phys *encoder,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c

index 3422b49f23c2..a0b7d8803e94 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -140,23 +140,6 @@ static void 
dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)

  dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
  }
-static void dpu_encoder_phys_cmd_atomic_mode_set(
-    struct dpu_encoder_phys *phys_enc,
-    struct drm_crtc_state *crtc_state,
-    struct drm_connector_state *conn_state)
-{
-    phys_enc->irq[INTR_IDX_CTL_START] = 
phys_enc->hw_ctl->caps->intr_start;

-
-    phys_enc->irq[INTR_IDX_PINGPONG] = 
phys_enc->hw_pp->caps->intr_done;

-
-    if (phys_enc->has_intf_te)
-    phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_intf->cap->intr_tear_rd_ptr;

-    else
-    phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_pp->caps->intr_rdptr;

-
-    

Re: [Freedreno] [PATCH 3/3] drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set

2023-08-17 Thread Dmitry Baryshkov

On 08/08/2023 02:49, Abhinav Kumar wrote:



On 6/4/2023 7:45 AM, Dmitry Baryshkov wrote:

The atomic_mode_set() callback only sets the phys_enc's IRQ data. As the
INTF and WB are statically allocated to each encoder/phys_enc, drop the
atomic_mode_set callback and set the IRQs during encoder init.

For the CMD panel usecase some of IRQ indexes depend on the selected
resources. Move setting them to the irq_enable() callback.



The irq_enable() callback is called from the 
dpu_encoder_virt_atomic_enable() after the phys layer's enable.


Thats late.

So lets consider the case where command mode panel's clock is powered 
from bootloader (quite common).


Now, as soon as the tearcheck is configured and interface is ON from the 
phys's enable(), nothing prevents / should prevent the interrupt from 
firing.


Please note that interrupt callbacks are also registered from the 
irq_control(). There is no way the interrupt can fire beforehand (and 
the call chain is dpu_encoder_virt_atomic_enable() -> 
dpu_encoder_resource_control() -> _dpu_encoder_resource_control_helper() 
-> _dpu_encoder_irq_control() -> irq_control().


If we ever want to move irq_control() to be called before phys's 
enable() callbacks, this will be a separate patchset, involving 
refactoring of dpu_encoder_resource_control().




So I feel / think mode_set is the correct location to assign these.

I can ack patches 1 and 2 but I think you did those mainly for this one, 
so I would like to get some clarity on this part.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 --
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  5 ---
  .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 32 ---
  .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 13 ++--
  .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c   | 11 +--
  5 files changed, 17 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index cc61f0cf059d..6b5c80dc5967 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1148,8 +1148,6 @@ static void 
dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,

  phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
  phys->cached_mode = crtc_state->adjusted_mode;
-    if (phys->ops.atomic_mode_set)
-    phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
  }
  }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

index faf033cd086e..24dbc28be4f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -67,8 +67,6 @@ struct dpu_encoder_phys;
   * @is_master:    Whether this phys_enc is the current master
   *    encoder. Can be switched at enable time. Based
   *    on split_role and current mode (CMD/VID).
- * @atomic_mode_set:    DRM Call. Set a DRM mode.
- *    This likely caches the mode, for use at enable.
   * @enable:    DRM Call. Enable a DRM mode.
   * @disable:    DRM Call. Disable mode.
   * @atomic_check:    DRM Call. Atomic check new DRM state.
@@ -95,9 +93,6 @@ struct dpu_encoder_phys;
  struct dpu_encoder_phys_ops {
  void (*prepare_commit)(struct dpu_encoder_phys *encoder);
  bool (*is_master)(struct dpu_encoder_phys *encoder);
-    void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
-    struct drm_crtc_state *crtc_state,
-    struct drm_connector_state *conn_state);
  void (*enable)(struct dpu_encoder_phys *encoder);
  void (*disable)(struct dpu_encoder_phys *encoder);
  int (*atomic_check)(struct dpu_encoder_phys *encoder,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c

index 3422b49f23c2..a0b7d8803e94 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -140,23 +140,6 @@ static void 
dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)

  dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
  }
-static void dpu_encoder_phys_cmd_atomic_mode_set(
-    struct dpu_encoder_phys *phys_enc,
-    struct drm_crtc_state *crtc_state,
-    struct drm_connector_state *conn_state)
-{
-    phys_enc->irq[INTR_IDX_CTL_START] = 
phys_enc->hw_ctl->caps->intr_start;

-
-    phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
-
-    if (phys_enc->has_intf_te)
-    phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_intf->cap->intr_tear_rd_ptr;

-    else
-    phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_pp->caps->intr_rdptr;

-
-    phys_enc->irq[INTR_IDX_UNDERRUN] = 
phys_enc->hw_intf->cap->intr_underrun;

-}
-
  static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
  struct dpu_encoder_phys 

Re: [Freedreno] [PATCH v3 2/4] drm/msm/dpu: Enable widebus for DSI INTF

2023-08-17 Thread Dmitry Baryshkov

On 08/08/2023 00:40, Jessica Zhang wrote:



On 8/2/2023 11:20 AM, Dmitry Baryshkov wrote:
On Wed, 2 Aug 2023 at 21:09, Jessica Zhang  
wrote:


diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c

index df88358e7037..dace6168be2d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
 phys_enc->hw_intf,
 phys_enc->hw_pp->idx);

-   if (intf_cfg.dsc != 0)
+   if (intf_cfg.dsc != 0) {
 cmd_mode_cfg.data_compress = true;
+   cmd_mode_cfg.wide_bus_en = 
dpu_encoder_is_widebus_enabled(phys_enc->parent);

+   }


This embeds the knowledge that a wide bus can only be enabled when DSC
is in use. Please move the wide_bus_en assignment out of conditional
code.


Wide bus for DSI will only be enabled if DSC is enabled, so this is 
technically not wrong, as DP will use the video mode path.






 if (phys_enc->hw_intf->ops.program_intf_cmd_cfg)
 
phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, 
_mode_cfg);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c

index 8ec6505d9e78..dc6f3febb574 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -521,6 +521,9 @@ static void 
dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx,


This function is only enabled for DPU >= 7.0, while IIRC wide bus can
be enabled even for some of the earlier chipsets.


The command mode path is only called for DSI, which only supports wide 
bus for DPU 7.0+.


After second consideration, let's ignore this part, as wide bus will 
only be enabled for DSI / CMD after 7.0. If we ever have SoC that has 
CMD + wide_bus earlier than 5.0, we can reconsider this code pice.


Can you please add a comment that the register itself is present earlier 
(5.0), but it doesn't have to be programmed since the flags will not be 
set anyway.







 if (cmd_mode_cfg->data_compress)
 intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;

+   if (cmd_mode_cfg->wide_bus_en)
+   intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
+
 DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2);
  }





--
With best wishes
Dmitry



[Freedreno] [PATCH v2 3/4] arm64: dts: qcom: qrb5165-rb5: enable displayport controller

2023-08-17 Thread Dmitry Baryshkov
Enable the onboard displayport controller, connect it to QMP PHY.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts 
b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index a4f7a9f9c22c..3bd0c06e7315 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -656,6 +656,15 @@  {
status = "okay";
 };
 
+_dp {
+   status = "okay";
+};
+
+_dp_out {
+   data-lanes = <0 1>;
+   remote-endpoint = <_1_qmpphy_dp_in>;
+};
+
 _dsi0 {
status = "okay";
vdda-supply = <_l9a_1p2>;
@@ -1442,3 +1451,7 @@ pm8150b_typec_sbu_out: endpoint {
};
};
 };
+
+_1_qmpphy_dp_in {
+   remote-endpoint = <_dp_out>;
+};
-- 
2.39.2



[Freedreno] [PATCH v2 4/4] arm64: dts: qcom: qrb5165-rb5: enable DP altmode

2023-08-17 Thread Dmitry Baryshkov
Add displayport altmode declaration to the Type-C controller node to
enable DP altmode negotiation.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts 
b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 3bd0c06e7315..c8cd40a462a3 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -1423,6 +1423,13 @@ PDO_FIXED_DUAL_ROLE |
 PDO_FIXED_USB_COMM |
 PDO_FIXED_DATA_SWAP)>;
 
+   altmodes {
+   displayport {
+   svid = <0xff01>;
+   vdo = <0x1c46>;
+   };
+   };
+
ports {
#address-cells = <1>;
#size-cells = <0>;
-- 
2.39.2



[Freedreno] [PATCH v2 2/4] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver

2023-08-17 Thread Dmitry Baryshkov
Add the nb7vpq904m, onboard USB-C redriver / retimer.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 52 +++-
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts 
b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 303d07f9c6e5..a4f7a9f9c22c 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -610,6 +610,46 @@ lt9611_out: endpoint {
 /* LS-I2C1 */
  {
status = "okay";
+
+   typec-mux@1c {
+   compatible = "onnn,nb7vpq904m";
+   reg = <0x1c>;
+
+   vcc-supply = <_s4a_1p8>;
+
+   retimer-switch;
+   orientation-switch;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   redriver_usb_con_ss: endpoint {
+   remote-endpoint = 
<_typec_mux_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   redriver_phy_con_ss: endpoint {
+   remote-endpoint = <_1_qmpphy_out>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   redriver_usb_con_sbu: endpoint {
+   remote-endpoint = 
<_typec_sbu_out>;
+   };
+   };
+   };
+   };
 };
 
  {
@@ -1299,7 +1339,7 @@ _1_qmpphy {
 };
 
 _1_qmpphy_out {
-   remote-endpoint = <_typec_mux_in>;
+   remote-endpoint = <_phy_con_ss>;
 };
 
 _2 {
@@ -1388,7 +1428,15 @@ pm8150b_role_switch_in: endpoint {
port@1 {
reg = <1>;
pm8150b_typec_mux_in: endpoint {
-   remote-endpoint = <_1_qmpphy_out>;
+   remote-endpoint = 
<_usb_con_ss>;
+   };
+   };
+
+   port@2 {
+   reg = <2>;
+
+   pm8150b_typec_sbu_out: endpoint {
+   remote-endpoint = 
<_usb_con_sbu>;
};
};
};
-- 
2.39.2



[Freedreno] [PATCH v2 1/4] arm64: dts: qcom: sm8250: Add DisplayPort device node

2023-08-17 Thread Dmitry Baryshkov
Declare the displayport controller present on the Qualcomm SM8250 SoC.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 89 
 1 file changed, 89 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi 
b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index eb00bbd3e1f3..8d705a1713fb 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -3638,6 +3638,8 @@ port@1 {
 
port@2 {
reg = <2>;
+
+   usb_1_qmpphy_dp_in: endpoint {};
};
};
};
@@ -4405,6 +4407,14 @@ dpu_intf2_out: endpoint {
remote-endpoint = 
<_dsi1_in>;
};
};
+
+   port@2 {
+   reg = <2>;
+
+   dpu_intf0_out: endpoint {
+   remote-endpoint = 
<_dp_in>;
+   };
+   };
};
 
mdp_opp_table: opp-table {
@@ -4432,6 +4442,85 @@ opp-46000 {
};
};
 
+   mdss_dp: displayport-controller@ae9 {
+   compatible = "qcom,sm8250-dp", "qcom,sm8350-dp";
+   reg = <0 0xae9 0 0x200>,
+ <0 0xae90200 0 0x200>,
+ <0 0xae90400 0 0x600>,
+ <0 0xae91000 0 0x400>,
+ <0 0xae91400 0 0x400>;
+   interrupt-parent = <>;
+   interrupts = <12>;
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_DP_AUX_CLK>,
+< DISP_CC_MDSS_DP_LINK_CLK>,
+< 
DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+< DISP_CC_MDSS_DP_PIXEL_CLK>;
+   clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+   assigned-clocks = < 
DISP_CC_MDSS_DP_LINK_CLK_SRC>,
+ < 
DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
+   assigned-clock-parents = <_phy 0>,
+<_phy 1>;
+
+   phys = <_phy>;
+   phy-names = "dp";
+
+   #sound-dai-cells = <0>;
+
+   operating-points-v2 = <_opp_table>;
+   power-domains = < SM8250_MMCX>;
+
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   mdss_dp_in: endpoint {
+   remote-endpoint = 
<_intf0_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   mdss_dp_out: endpoint {
+   };
+   };
+   };
+
+   dp_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-16000 {
+   opp-hz = /bits/ 64 <16000>;
+   required-opps = 
<_opp_low_svs>;
+   };
+
+   opp-27000 {
+   opp-hz = /bits/ 64 <27000>;
+   required-opps = 
<_opp_svs>;
+   };
+
+   opp-54000 {
+   opp-hz = /bits/ 64 

[Freedreno] [PATCH v2 0/4] arm64: dts: qcom: qrb5165-rb5: enable DP support

2023-08-17 Thread Dmitry Baryshkov
Implement DisplayPort support for the Qualcomm RB5 platform.

Note: while testing this, I had link training issues with several
dongles with DP connectors. Other DisplayPort-USB-C dongles (with HDMI
or VGA connectors) work perfectly.

Dependencies: [1]
Soft-dependencies: [2], [3]

[1] 
https://lore.kernel.org/linux-arm-msm/20230816115151.501736-1-bryan.odonog...@linaro.org/
[2] 
https://lore.kernel.org/linux-arm-msm/20230709034211.4045004-1-dmitry.barysh...@linaro.org/
[3] 
https://lore.kernel.org/linux-arm-msm/20230817145516.5924-1-dmitry.barysh...@linaro.org/

Changes since v1:
 - Rebased on v9 of Bryan's patchset
 - Dropped merged dt-bindings patch

Dmitry Baryshkov (4):
  arm64: dts: qcom: sm8250: Add DisplayPort device node
  arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver
  arm64: dts: qcom: qrb5165-rb5: enable displayport controller
  arm64: dts: qcom: qrb5165-rb5: enable DP altmode

 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 72 ++-
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 89 
 2 files changed, 159 insertions(+), 2 deletions(-)

-- 
2.39.2



[Freedreno] [PATCH v4 3/3] usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE

2023-08-17 Thread Dmitry Baryshkov
Switch to using the new DRM_AUX_BRIDGE helper to create the
transparent DRM bridge device instead of handcoding corresponding
functionality.

Reviewed-by: Heikki Krogerus 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/usb/typec/mux/Kconfig  |  2 +-
 drivers/usb/typec/mux/nb7vpq904m.c | 44 ++
 2 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 65da61150ba7..e3fee531548f 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -40,7 +40,7 @@ config TYPEC_MUX_NB7VPQ904M
tristate "On Semiconductor NB7VPQ904M Type-C redriver driver"
depends on I2C
depends on DRM || DRM=n
-   select DRM_PANEL_BRIDGE if DRM
+   select DRM_AUX_BRIDGE if DRM && OF
select REGMAP_I2C
help
  Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
diff --git a/drivers/usb/typec/mux/nb7vpq904m.c 
b/drivers/usb/typec/mux/nb7vpq904m.c
index cda206cf0c38..b17826713753 100644
--- a/drivers/usb/typec/mux/nb7vpq904m.c
+++ b/drivers/usb/typec/mux/nb7vpq904m.c
@@ -11,7 +11,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -70,8 +70,6 @@ struct nb7vpq904m {
bool swap_data_lanes;
struct typec_switch *typec_switch;
 
-   struct drm_bridge bridge;
-
struct mutex lock; /* protect non-concurrent retimer & switch */
 
enum typec_orientation orientation;
@@ -297,44 +295,6 @@ static int nb7vpq904m_retimer_set(struct typec_retimer 
*retimer, struct typec_re
return ret;
 }
 
-#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
-static int nb7vpq904m_bridge_attach(struct drm_bridge *bridge,
-   enum drm_bridge_attach_flags flags)
-{
-   struct nb7vpq904m *nb7 = container_of(bridge, struct nb7vpq904m, 
bridge);
-   struct drm_bridge *next_bridge;
-
-   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
-   return -EINVAL;
-
-   next_bridge = devm_drm_of_get_bridge(>client->dev, 
nb7->client->dev.of_node, 0, 0);
-   if (IS_ERR(next_bridge)) {
-   dev_err(>client->dev, "failed to acquire drm_bridge: 
%pe\n", next_bridge);
-   return PTR_ERR(next_bridge);
-   }
-
-   return drm_bridge_attach(bridge->encoder, next_bridge, bridge,
-DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-}
-
-static const struct drm_bridge_funcs nb7vpq904m_bridge_funcs = {
-   .attach = nb7vpq904m_bridge_attach,
-};
-
-static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7)
-{
-   nb7->bridge.funcs = _bridge_funcs;
-   nb7->bridge.of_node = nb7->client->dev.of_node;
-
-   return devm_drm_bridge_add(>client->dev, >bridge);
-}
-#else
-static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7)
-{
-   return 0;
-}
-#endif
-
 static const struct regmap_config nb7_regmap = {
.max_register = 0x1f,
.reg_bits = 8,
@@ -461,7 +421,7 @@ static int nb7vpq904m_probe(struct i2c_client *client)
 
gpiod_set_value(nb7->enable_gpio, 1);
 
-   ret = nb7vpq904m_register_bridge(nb7);
+   ret = drm_aux_bridge_register(dev);
if (ret)
goto err_disable_gpio;
 
-- 
2.39.2



[Freedreno] [PATCH v4 2/3] phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE

2023-08-17 Thread Dmitry Baryshkov
Switch to using the new DRM_AUX_BRIDGE helper to create the
transparent DRM bridge device instead of handcoding corresponding
functionality.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/phy/qualcomm/Kconfig  |  2 +-
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 ++-
 2 files changed, 3 insertions(+), 43 deletions(-)

diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index ced603806375..97f53debe761 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -63,7 +63,7 @@ config PHY_QCOM_QMP_COMBO
depends on DRM || DRM=n
select GENERIC_PHY
select MFD_SYSCON
-   select DRM_PANEL_BRIDGE if DRM
+   select DRM_AUX_BRIDGE if DRM_BRIDGE && OF
help
  Enable this to support the QMP Combo PHY transceiver that is used
  with USB3 and DisplayPort controllers on Qualcomm chips.
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c 
b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 9c3de41ecedb..367d5e93422c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -21,7 +21,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include 
 
@@ -1419,8 +1419,6 @@ struct qmp_combo {
struct clk_hw dp_link_hw;
struct clk_hw dp_pixel_hw;
 
-   struct drm_bridge bridge;
-
struct typec_switch_dev *sw;
enum typec_orientation orientation;
 };
@@ -3193,44 +3191,6 @@ static int qmp_combo_typec_switch_register(struct 
qmp_combo *qmp)
 }
 #endif
 
-#if IS_ENABLED(CONFIG_DRM)
-static int qmp_combo_bridge_attach(struct drm_bridge *bridge,
-  enum drm_bridge_attach_flags flags)
-{
-   struct qmp_combo *qmp = container_of(bridge, struct qmp_combo, bridge);
-   struct drm_bridge *next_bridge;
-
-   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
-   return -EINVAL;
-
-   next_bridge = devm_drm_of_get_bridge(qmp->dev, qmp->dev->of_node, 0, 0);
-   if (IS_ERR(next_bridge)) {
-   dev_err(qmp->dev, "failed to acquire drm_bridge: %pe\n", 
next_bridge);
-   return PTR_ERR(next_bridge);
-   }
-
-   return drm_bridge_attach(bridge->encoder, next_bridge, bridge,
-DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-}
-
-static const struct drm_bridge_funcs qmp_combo_bridge_funcs = {
-   .attach = qmp_combo_bridge_attach,
-};
-
-static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp)
-{
-   qmp->bridge.funcs = _combo_bridge_funcs;
-   qmp->bridge.of_node = qmp->dev->of_node;
-
-   return devm_drm_bridge_add(qmp->dev, >bridge);
-}
-#else
-static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp)
-{
-   return 0;
-}
-#endif
-
 static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct 
device_node *np)
 {
struct device *dev = qmp->dev;
@@ -3436,7 +3396,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   ret = qmp_combo_dp_register_bridge(qmp);
+   ret = drm_aux_bridge_register(dev);
if (ret)
return ret;
 
-- 
2.39.2



[Freedreno] [PATCH v4 0/3] drm: simplify support for transparent DRM bridges

2023-08-17 Thread Dmitry Baryshkov
Supporting DP/USB-C can result in a chain of several transparent
bridges (PHY, redrivers, mux, etc). This results in drivers having
similar boilerplate code for such bridges.

Next, these drivers are susceptible to -EPROBE_DEFER loops: the next
bridge can either be probed from the bridge->attach callback, when it is
too late to return -EPROBE_DEFER, or from the probe() callback, when the
next bridge might not yet be available, because it depends on the
resources provided by the probing device.

Last, but not least, this results in the the internal knowledge of DRM
subsystem slowly diffusing into other subsystems, like PHY or USB/TYPEC.

To solve all these issues, define a separate DRM helper, which creates
separate aux device just for the bridge. During probe such aux device
doesn't result in the EPROBE_DEFER loops. Instead it allows the device
drivers to probe properly, according to the actual resource
dependencies. The bridge auxdevs are then probed when the next bridge
becomes available, sparing drivers from drm_bridge_attach() returning
-EPROBE_DEFER.

Proposed merge strategy: immutable branch with the drm commit, which is
then merged into PHY and USB subsystems together with the corresponding
patch.

Changes since v3:
 - Moved bridge driver to gpu/drm/bridge (Neil Armstrong)
 - Renamed it to aux-bridge (since there is already a simple_bridge driver)
 - Made CONFIG_OF mandatory for this driver (Neil Armstrong)
 - Added missing kfree and ida_free (Dan Carpenter)

Changes since v2:
 - ifdef'ed bridge->of_node access (LKP)

Changes since v1:
 - Added EXPORT_SYMBOL_GPL / MODULE_LICENSE / etc. to drm_simple_bridge

Dmitry Baryshkov (3):
  drm/bridge: add transparent bridge helper
  phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE
  usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE

 drivers/gpu/drm/bridge/Kconfig|   9 ++
 drivers/gpu/drm/bridge/Makefile   |   1 +
 drivers/gpu/drm/bridge/aux-bridge.c   | 132 ++
 drivers/phy/qualcomm/Kconfig  |   2 +-
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c |  44 +---
 drivers/usb/typec/mux/Kconfig |   2 +-
 drivers/usb/typec/mux/nb7vpq904m.c|  44 +---
 include/drm/bridge/aux-bridge.h   |  19 
 8 files changed, 167 insertions(+), 86 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c
 create mode 100644 include/drm/bridge/aux-bridge.h

-- 
2.39.2



[Freedreno] [PATCH v4 1/3] drm/bridge: add transparent bridge helper

2023-08-17 Thread Dmitry Baryshkov
Define a helper for creating simple transparent bridges which serve the
only purpose of linking devices into the bridge chain up to the last
bridge representing the connector. This is especially useful for
DP/USB-C bridge chains, which can span across several devices, but do
not require any additional functionality from the intermediate bridges.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/Kconfig  |   9 ++
 drivers/gpu/drm/bridge/Makefile |   1 +
 drivers/gpu/drm/bridge/aux-bridge.c | 132 
 include/drm/bridge/aux-bridge.h |  19 
 4 files changed, 161 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c
 create mode 100644 include/drm/bridge/aux-bridge.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 44a660a4bdbf..80e5d9f722e4 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -12,6 +12,15 @@ config DRM_PANEL_BRIDGE
help
  DRM bridge wrapper of DRM panels
 
+config DRM_AUX_BRIDGE
+   tristate
+   depends on DRM_BRIDGE && OF
+   select AUXILIARY_BUS
+   select DRM_PANEL_BRIDGE
+   help
+ Simple transparent bridge that is used by several non-DRM drivers to
+ build bridges chain.
+
 menu "Display Interface Bridges"
depends on DRM && DRM_BRIDGE
 
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 2b892b7ed59e..918e3bfff079 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
 obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-bridge.c 
b/drivers/gpu/drm/bridge/aux-bridge.c
new file mode 100644
index ..13fe794592f2
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-bridge.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Author: Dmitry Baryshkov 
+ */
+#include 
+#include 
+
+#include 
+#include 
+
+static DEFINE_IDA(aux_bridge_ida);
+
+static void drm_aux_bridge_release(struct device *dev)
+{
+   struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+   ida_free(_bridge_ida, adev->id);
+
+   kfree(adev);
+}
+
+static void drm_aux_bridge_unregister_adev(void *_adev)
+{
+   struct auxiliary_device *adev = _adev;
+
+   auxiliary_device_delete(adev);
+   auxiliary_device_uninit(adev);
+}
+
+int drm_aux_bridge_register(struct device *parent)
+{
+   struct auxiliary_device *adev;
+   int ret;
+
+   adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+   if (!adev)
+   return -ENOMEM;
+
+   ret = ida_alloc(_bridge_ida, GFP_KERNEL);
+   if (ret < 0) {
+   kfree(adev);
+   return ret;
+   }
+
+   adev->id = ret;
+   adev->name = "aux_bridge";
+   adev->dev.parent = parent;
+#ifdef CONFIG_OF
+   adev->dev.of_node = parent->of_node;
+#endif
+   adev->dev.release = drm_aux_bridge_release;
+
+   ret = auxiliary_device_init(adev);
+   if (ret) {
+   ida_free(_bridge_ida, adev->id);
+   kfree(adev);
+   return ret;
+   }
+
+   ret = auxiliary_device_add(adev);
+   if (ret) {
+   auxiliary_device_uninit(adev);
+   return ret;
+   }
+
+   return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, 
adev);
+}
+EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
+
+struct drm_aux_bridge_data {
+   struct drm_bridge bridge;
+   struct drm_bridge *next_bridge;
+   struct device *dev;
+};
+
+static int drm_aux_bridge_attach(struct drm_bridge *bridge,
+   enum drm_bridge_attach_flags flags)
+{
+   struct drm_aux_bridge_data *data;
+
+   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
+   return -EINVAL;
+
+   data = container_of(bridge, struct drm_aux_bridge_data, bridge);
+
+   return drm_bridge_attach(bridge->encoder, data->next_bridge, bridge,
+DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+}
+
+static const struct drm_bridge_funcs drm_aux_bridge_funcs = {
+   .attach = drm_aux_bridge_attach,
+};
+
+static int drm_aux_bridge_probe(struct auxiliary_device *auxdev,
+  const struct auxiliary_device_id *id)
+{
+   struct drm_aux_bridge_data *data;
+
+   data = devm_kzalloc(>dev, sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   data->dev = >dev;
+   data->next_bridge = devm_drm_of_get_bridge(>dev, 
auxdev->dev.of_node, 0, 0);
+   if (IS_ERR(data->next_bridge))
+   return dev_err_probe(>dev, PTR_ERR(data->next_bridge),
+"failed to acquire