The audio clock is an external resource from the DPSUB point of view,
not a resource internal to the display controller. Move it to the
zynqmp_dpsub structure, to allow accessing it from outside the disp
code.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c  | 54 ++---------------------------
 drivers/gpu/drm/xlnx/zynqmp_disp.h  |  2 --
 drivers/gpu/drm/xlnx/zynqmp_dp.c    |  8 ++---
 drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 54 +++++++++++++++++++++++++++--
 drivers/gpu/drm/xlnx/zynqmp_dpsub.h |  7 ++++
 5 files changed, 65 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 767ec5e5cfa4..bd21eb77589f 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -165,8 +165,6 @@ struct zynqmp_disp_layer {
  * @blend.base: Register I/O base address for the blender
  * @avbuf.base: Register I/O base address for the audio/video buffer manager
  * @audio.base: Registers I/O base address for the audio mixer
- * @audio.clk: Audio clock
- * @audio.clk_from_ps: True of the audio clock comes from PS, false from PL
  * @layers: Layers (planes)
  */
 struct zynqmp_disp {
@@ -184,8 +182,6 @@ struct zynqmp_disp {
        } avbuf;
        struct {
                void __iomem *base;
-               struct clk *clk;
-               bool clk_from_ps;
        } audio;
 
        struct zynqmp_disp_layer layers[ZYNQMP_DISP_NUM_LAYERS];
@@ -891,25 +887,6 @@ static void zynqmp_disp_audio_disable(struct zynqmp_disp 
*disp)
                                ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
 }
 
-static void zynqmp_disp_audio_init(struct zynqmp_disp *disp)
-{
-       /* Try the live PL audio clock. */
-       disp->audio.clk = devm_clk_get(disp->dev, "dp_live_audio_aclk");
-       if (!IS_ERR(disp->audio.clk)) {
-               disp->audio.clk_from_ps = false;
-               return;
-       }
-
-       /* If the live PL audio clock is not valid, fall back to PS clock. */
-       disp->audio.clk = devm_clk_get(disp->dev, "dp_aud_clk");
-       if (!IS_ERR(disp->audio.clk)) {
-               disp->audio.clk_from_ps = true;
-               return;
-       }
-
-       dev_err(disp->dev, "audio disabled due to missing clock\n");
-}
-
 /* 
-----------------------------------------------------------------------------
  * ZynqMP Display external functions for zynqmp_dp
  */
@@ -928,32 +905,6 @@ void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp)
        drm_crtc_handle_vblank(crtc);
 }
 
-/**
- * zynqmp_disp_audio_enabled - If the audio is enabled
- * @disp: Display controller
- *
- * Return if the audio is enabled depending on the audio clock.
- *
- * Return: true if audio is enabled, or false.
- */
-bool zynqmp_disp_audio_enabled(struct zynqmp_disp *disp)
-{
-       return !!disp->audio.clk;
-}
-
-/**
- * zynqmp_disp_get_audio_clk_rate - Get the current audio clock rate
- * @disp: Display controller
- *
- * Return: the current audio clock rate.
- */
-unsigned int zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp *disp)
-{
-       if (zynqmp_disp_audio_enabled(disp))
-               return 0;
-       return clk_get_rate(disp->audio.clk);
-}
-
 /**
  * zynqmp_disp_get_crtc_mask - Return the CRTC bit mask
  * @disp: Display controller
@@ -1403,7 +1354,8 @@ static void zynqmp_disp_enable(struct zynqmp_disp *disp)
        zynqmp_disp_avbuf_enable(disp);
        /* Choose clock source based on the DT clock handle. */
        zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps,
-                                            disp->audio.clk_from_ps, true);
+                                            disp->dpsub->aud_clk_from_ps,
+                                            true);
        zynqmp_disp_avbuf_enable_channels(disp);
        zynqmp_disp_avbuf_enable_audio(disp);
 
@@ -1664,8 +1616,6 @@ int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub, struct 
drm_device *drm)
        if (IS_ERR(disp->audio.base))
                return PTR_ERR(disp->audio.base);
 
-       zynqmp_disp_audio_init(disp);
-
        ret = zynqmp_disp_create_layers(disp);
        if (ret)
                return ret;
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.h 
b/drivers/gpu/drm/xlnx/zynqmp_disp.h
index f402901afb23..1b7f90a81857 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.h
@@ -31,8 +31,6 @@ struct zynqmp_disp;
 struct zynqmp_dpsub;
 
 void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp);
-bool zynqmp_disp_audio_enabled(struct zynqmp_disp *disp);
-unsigned int zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp *disp);
 uint32_t zynqmp_disp_get_crtc_mask(struct zynqmp_disp *disp);
 
 int zynqmp_disp_drm_init(struct zynqmp_dpsub *dpsub);
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 363015d248ab..7bd5769804e9 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1251,7 +1251,7 @@ static void zynqmp_dp_encoder_mode_set_stream(struct 
zynqmp_dp *dp,
                reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code);
                zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_N_VID, reg);
                zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_M_VID, mode->clock);
-               rate = zynqmp_disp_get_audio_clk_rate(dp->dpsub->disp);
+               rate = zynqmp_dpsub_get_audio_clk_rate(dp->dpsub);
                if (rate) {
                        dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512);
                        zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, reg);
@@ -1260,7 +1260,7 @@ static void zynqmp_dp_encoder_mode_set_stream(struct 
zynqmp_dp *dp,
        }
 
        /* Only 2 channel audio is supported now */
-       if (zynqmp_disp_audio_enabled(dp->dpsub->disp))
+       if (zynqmp_dpsub_audio_enabled(dp->dpsub))
                zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, 1);
 
        zynqmp_dp_write(dp, ZYNQMP_DP_USER_PIX_WIDTH, 1);
@@ -1371,7 +1371,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct 
drm_bridge *bridge,
        /* Enable the encoder */
        dp->enabled = true;
        zynqmp_dp_update_misc(dp);
-       if (zynqmp_disp_audio_enabled(dp->dpsub->disp))
+       if (zynqmp_dpsub_audio_enabled(dp->dpsub))
                zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1);
        zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0);
        if (dp->status == connector_status_connected) {
@@ -1405,7 +1405,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct 
drm_bridge *bridge,
        drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
        zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN,
                        ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL);
-       if (zynqmp_disp_audio_enabled(dp->dpsub->disp))
+       if (zynqmp_dpsub_audio_enabled(dp->dpsub))
                zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0);
        pm_runtime_put_sync(dp->dev);
 }
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c 
b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index 6ef9885644aa..ba52dbed5ba0 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -198,6 +198,36 @@ static const struct dev_pm_ops zynqmp_dpsub_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(zynqmp_dpsub_suspend, zynqmp_dpsub_resume)
 };
 
+/* 
-----------------------------------------------------------------------------
+ * DPSUB Configuration
+ */
+
+/**
+ * zynqmp_dpsub_audio_enabled - If the audio is enabled
+ * @dpsub: DisplayPort subsystem
+ *
+ * Return if the audio is enabled depending on the audio clock.
+ *
+ * Return: true if audio is enabled, or false.
+ */
+bool zynqmp_dpsub_audio_enabled(struct zynqmp_dpsub *dpsub)
+{
+       return !!dpsub->aud_clk;
+}
+
+/**
+ * zynqmp_dpsub_get_audio_clk_rate - Get the current audio clock rate
+ * @dpsub: DisplayPort subsystem
+ *
+ * Return: the current audio clock rate.
+ */
+unsigned int zynqmp_dpsub_get_audio_clk_rate(struct zynqmp_dpsub *dpsub)
+{
+       if (zynqmp_dpsub_audio_enabled(dpsub))
+               return 0;
+       return clk_get_rate(dpsub->aud_clk);
+}
+
 /* 
-----------------------------------------------------------------------------
  * Probe & Remove
  */
@@ -216,14 +246,16 @@ static int zynqmp_dpsub_init_clocks(struct zynqmp_dpsub 
*dpsub)
                return ret;
        }
 
-       /* Try the live PL video clock */
+       /*
+        * Try the live PL video clock, and fall back to the PS clock if the
+        * live PL video clock isn't valid.
+        */
        dpsub->vid_clk = devm_clk_get(dpsub->dev, "dp_live_video_in_clk");
        if (!IS_ERR(dpsub->vid_clk))
                dpsub->vid_clk_from_ps = false;
        else if (PTR_ERR(dpsub->vid_clk) == -EPROBE_DEFER)
                return PTR_ERR(dpsub->vid_clk);
 
-       /* If the live PL video clock is not valid, fall back to PS clock */
        if (IS_ERR_OR_NULL(dpsub->vid_clk)) {
                dpsub->vid_clk = devm_clk_get(dpsub->dev, 
"dp_vtc_pixel_clk_in");
                if (IS_ERR(dpsub->vid_clk)) {
@@ -233,6 +265,24 @@ static int zynqmp_dpsub_init_clocks(struct zynqmp_dpsub 
*dpsub)
                dpsub->vid_clk_from_ps = true;
        }
 
+       /*
+        * Try the live PL audio clock, and fall back to the PS clock if the
+        * live PL audio clock isn't valid. Missing audio clock disables audio
+        * but isn't an error.
+        */
+       dpsub->aud_clk = devm_clk_get(dpsub->dev, "dp_live_audio_aclk");
+       if (!IS_ERR(dpsub->aud_clk)) {
+               dpsub->aud_clk_from_ps = false;
+               return 0;
+       }
+
+       dpsub->aud_clk = devm_clk_get(dpsub->dev, "dp_aud_clk");
+       if (!IS_ERR(dpsub->aud_clk)) {
+               dpsub->aud_clk_from_ps = true;
+               return 0;
+       }
+
+       dev_info(dpsub->dev, "audio disabled due to missing clock\n");
        return 0;
 }
 
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h 
b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
index f5500bb2af5e..55d90f4130b2 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
@@ -35,6 +35,8 @@ enum zynqmp_dpsub_format {
  * @apb_clk: The APB clock
  * @vid_clk: Video clock
  * @vid_clk_from_ps: True of the video clock comes from PS, false from PL
+ * @aud_clk: Audio clock
+ * @aud_clk_from_ps: True of the audio clock comes from PS, false from PL
  * @encoder: The dummy DRM encoder
  * @connector: The DP connector
  * @bridge: The DP encoder bridge
@@ -49,6 +51,8 @@ struct zynqmp_dpsub {
        struct clk *apb_clk;
        struct clk *vid_clk;
        bool vid_clk_from_ps;
+       struct clk *aud_clk;
+       bool aud_clk_from_ps;
 
        struct drm_encoder encoder;
        struct drm_connector *connector;
@@ -65,4 +69,7 @@ static inline struct zynqmp_dpsub *to_zynqmp_dpsub(struct 
drm_device *drm)
        return container_of(drm, struct zynqmp_dpsub, drm);
 }
 
+bool zynqmp_dpsub_audio_enabled(struct zynqmp_dpsub *dpsub);
+unsigned int zynqmp_dpsub_get_audio_clk_rate(struct zynqmp_dpsub *dpsub);
+
 #endif /* _ZYNQMP_DPSUB_H_ */
-- 
Regards,

Laurent Pinchart

Reply via email to