All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: dri-devel@lists.freedesktop.org
Cc: Michal Simek <michal.simek@xilinx.com>,
	Jianqiang Chen <jianqian@xilinx.com>
Subject: [PATCH v2 20/37] drm: xlnx: zynqmp_dpsub: Move audio clk from zynqmp_disp to zynqmp_dpsub
Date: Thu, 29 Sep 2022 01:47:02 +0300	[thread overview]
Message-ID: <20220928224719.3291-21-laurent.pinchart@ideasonboard.com> (raw)
In-Reply-To: <20220928224719.3291-1-laurent.pinchart@ideasonboard.com>

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.pinchart@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 62f9daf93465..640be60c4214 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -167,8 +167,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 {
@@ -186,8 +184,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];
@@ -893,25 +889,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
  */
@@ -930,32 +907,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
@@ -1409,7 +1360,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);
 
@@ -1670,8 +1622,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 33fd69ed7550..3e4d164d40fe 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1252,7 +1252,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);
@@ -1261,7 +1261,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);
@@ -1372,7 +1372,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) {
@@ -1406,7 +1406,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 a278a73e1713..cb01548f2b8c 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -196,6 +196,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
  */
@@ -214,14 +244,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)) {
@@ -231,6 +263,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 bcb119bb97e1..5bd42e192e17 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
  * @bridge: The DP encoder bridge
  * @disp: The display controller
@@ -48,6 +50,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_bridge *bridge;
@@ -63,4 +67,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


  parent reply	other threads:[~2022-09-28 22:48 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-28 22:46 [PATCH v2 00/37] drm: xlnx: zynqmp_dpsub: Initial live video input support Laurent Pinchart
2022-09-28 22:46 ` Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 01/37] dt-bindings: display: xlnx: zynqmp-dpsub: Add OF graph ports Laurent Pinchart
2022-09-28 22:46   ` Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 02/37] drm: xlnx: zynqmp_dpsub: Switch to atomic encoder enable/disable Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 03/37] drm: xlnx: zynqmp_dpsub: Constify mode argument to function Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 04/37] drm: xlnx: zynqmp_dpsub: Create DRM bridge to model DP encoder Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 05/37] drm: xlnx: zynqmp_dpsub: Don't access connector in zynqmp_dp_set_format() Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 06/37] drm: xlnx: zynqmp_dpsub: Move connector registration to bridge attach Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 07/37] drm: xlnx: zynqmp_dpsub: Move encoder to DPSUB core Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 08/37] drm: xlnx: zynqmp_dpsub: Attach to the next bridge Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 09/37] drm: xlnx: zynqmp_dpsub: Use DRM connector bridge helper Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 10/37] drm: xlnx: zynqmp_dpsub: Report HPD through the bridge Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 11/37] drm: xlnx: zynqmp_dpsub: Drop unused zynqmp_disp.event field Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 12/37] drm: xlnx: zynqmp_dpsub: Drop unused zynqmp_disp_format.bus_fmt field Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 13/37] drm: xlnx: zynqmp_dpsub: Don't pass CRTC to zynqmp_disp_setup_clock() Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 14/37] drm: xlnx: zynqmp_dpsub: Configure blender in zynqmp_disp_enable() Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 15/37] drm: xlnx: zynqmp_dpsub: Use local variable in zynqmp_disp_layer_update() Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 16/37] drm: xlnx: zynqmp_dpsub: Pass format info to zynqmp_disp_layer_set_format() Laurent Pinchart
2022-09-28 22:46 ` [PATCH v2 17/37] drm: xlnx: zynqmp_dpsub: Remplace hardcoded values with ARRAY_SIZE() Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 18/37] drm: xlnx: zynqmp_dpsub: Don't use drmm_kcalloc() for temporary data Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 19/37] drm: xlnx: zynqmp_dpsub: Move pclk from zynqmp_disp to zynqmp_dpsub Laurent Pinchart
2022-09-28 22:47 ` Laurent Pinchart [this message]
2022-09-28 22:47 ` [PATCH v2 21/37] drm: xlnx: zynqmp_dpsub: Move CRTC to zynqmp_dpsub structure Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 22/37] drm: xlnx: zynqmp_dpsub: Move planes " Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 23/37] drm: xlnx: zynqmp_dpsub: Move DRM/KMS initialization to separate file Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 24/37] drm: xlnx: zynqmp_dpsub: Move CRTC handling to zynqmp_kms.c Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 25/37] drm: xlnx: zynqmp_dpsub: Move planes " Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 26/37] drm: xlnx: zynqmp_dpsub: Register AUX bus at bridge attach time Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 27/37] drm: xlnx: zynqmp_dpsub: Move DP bridge init to zynqmp_dp_probe() Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 28/37] drm: xlnx: zynqmp_dpsub: Manage DP and DISP allocations manually Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 29/37] drm: xlnx: zynqmp_dpsub: Move all DRM init and cleanup to zynqmp_kms.c Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 30/37] drm: xlnx: zynqmp_dpsub: Decouple DRM device from zynqmp_dpsub Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 31/37] drm: xlnx: zynqmp_dpsub: Rename zynqmp_dpsub_handle_vblank with DRM prefix Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 32/37] drm: xlnx: zynqmp_dpsub: Parse DT to find connected ports Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 33/37] drm: xlnx: zynqmp_dpsub: Allow configuration of layer mode Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 34/37] drm: xlnx: zynqmp_dpsub: Support operation without DMA engine Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 35/37] drm: xlnx: zynqmp_dpsub: Add support for live video input Laurent Pinchart
2022-09-28 22:47 ` [PATCH v2 36/37] arm64: dts: zynqmp: Add ports for the DisplayPort subsystem Laurent Pinchart
2022-09-28 22:47   ` Laurent Pinchart
2022-10-19 15:59   ` Laurent Pinchart
2022-10-20  6:50     ` Michal Simek
2022-10-20  6:50       ` Michal Simek
2022-09-28 22:47 ` [PATCH v2 37/37] arm64: dts: zynqmp: zcu106a: Describe DisplayPort connector Laurent Pinchart
2022-09-28 22:47   ` Laurent Pinchart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220928224719.3291-21-laurent.pinchart@ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jianqian@xilinx.com \
    --cc=michal.simek@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.