Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kahola <mika.kahola@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 1/5] drm/i915/mtl: Add Support for C10, C20 PHY Message Bus
Date: Thu, 29 Sep 2022 16:17:43 +0300	[thread overview]
Message-ID: <20220929131747.2592092-2-mika.kahola@intel.com> (raw)
In-Reply-To: <20220929131747.2592092-1-mika.kahola@intel.com>

From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>

XELPDP has C10 and C20 phys from Synopsys to drive displays. Each phy
has a dedicated PIPE 5.2 Message bus for configuration. This message
bus is used to configure the phy internal registers.

Bspec: 64599, 65100, 65101, 67610, 67636

Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Signed-off-by: Mika Kahola <mika.kahola@intel.com> (v4)
---
 drivers/gpu/drm/i915/display/intel_cx0_phy.c | 179 +++++++++++++++++++
 1 file changed, 179 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/display/intel_cx0_phy.c

diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
new file mode 100644
index 000000000000..7930b0255cfa
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "intel_de.h"
+#include "intel_uncore.h"
+
+static void intel_cx0_bus_reset(struct drm_i915_private *i915, enum port port, int lane)
+{
+	enum phy phy = intel_port_to_phy(i915, port);
+
+	/* Bring the phy to idle. */
+	intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+		       XELPDP_PORT_M2P_TRANSACTION_RESET);
+
+	/* Wait for Idle Clear. */
+	if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+				    XELPDP_PORT_M2P_TRANSACTION_RESET,
+				    XELPDP_MSGBUS_TIMEOUT_SLOW)) {
+		drm_err_once(&i915->drm, "Failed to bring PHY %c to idle. \n", phy_name(phy));
+		return;
+	}
+
+	intel_de_write(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane), ~0);
+	return;
+}
+
+__maybe_unused static u8 intel_cx0_read(struct drm_i915_private *i915, enum port port,
+			 int lane, u16 addr)
+{
+	enum phy phy = intel_port_to_phy(i915, port);
+	u32 val = 0;
+	int attempts = 0;
+
+retry:
+	if (attempts == 3) {
+		drm_err_once(&i915->drm, "PHY %c Read %04x failed after %d retries. Status: 0x%x\n", phy_name(phy), addr, attempts, val ?: 0);
+		return 0;
+	}
+
+	/* Wait for pending transactions.*/
+	if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+				    XELPDP_PORT_M2P_TRANSACTION_PENDING,
+				    XELPDP_MSGBUS_TIMEOUT_SLOW)) {
+		drm_dbg(&i915->drm, "PHY %c Timeout waiting for previous transaction to complete. Reset the bus and retry.\n", phy_name(phy));
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	/* Issue the read command. */
+	intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+		       XELPDP_PORT_M2P_TRANSACTION_PENDING |
+		       XELPDP_PORT_M2P_COMMAND_READ |
+		       XELPDP_PORT_M2P_ADDRESS(addr));
+
+	/* Wait for response ready. And read response.*/
+	if (__intel_wait_for_register(&i915->uncore,
+				      XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane),
+				      XELPDP_PORT_P2M_RESPONSE_READY,
+				      XELPDP_PORT_P2M_RESPONSE_READY,
+				      XELPDP_MSGBUS_TIMEOUT_FAST_US,
+				      XELPDP_MSGBUS_TIMEOUT_SLOW, &val)) {
+		drm_dbg(&i915->drm, "PHY %c Timeout waiting for Read response ACK. Status: 0x%x\n", phy_name(phy), val);
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	/* Check for error. */
+	if (val & XELPDP_PORT_P2M_ERROR_SET) {
+		drm_dbg(&i915->drm, "PHY %c Error occurred during read command. Status: 0x%x\n", phy_name(phy), val);
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	/* Check for Read Ack. */
+	if (REG_FIELD_GET(XELPDP_PORT_P2M_COMMAND_TYPE_MASK, val) !=
+	    XELPDP_PORT_P2M_COMMAND_READ_ACK) {
+		drm_dbg(&i915->drm, "PHY %c Not a Read response. MSGBUS Status: 0x%x.\n", phy_name(phy), val);
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	/* Clear Response Ready flag.*/
+	intel_de_write(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane), ~0);
+	return (u8)REG_FIELD_GET(XELPDP_PORT_P2M_DATA_MASK, val);
+}
+
+static int intel_cx0_wait_cwrite_ack(struct drm_i915_private *i915,
+				      enum port port, int lane)
+{
+	enum phy phy = intel_port_to_phy(i915, port);
+	u32 val;
+
+	/* Check for write ack. */
+	if (__intel_wait_for_register(&i915->uncore,
+				      XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane),
+				      XELPDP_PORT_P2M_RESPONSE_READY,
+				      XELPDP_PORT_P2M_RESPONSE_READY,
+				      XELPDP_MSGBUS_TIMEOUT_FAST_US,
+				      XELPDP_MSGBUS_TIMEOUT_SLOW, &val)) {
+		drm_dbg(&i915->drm, "PHY %c Timeout waiting for Committed message ACK. Status: 0x%x\n", phy_name(phy), val);
+		return -ETIMEDOUT;
+	}
+
+	if ((REG_FIELD_GET(XELPDP_PORT_P2M_COMMAND_TYPE_MASK, val) !=
+	     XELPDP_PORT_P2M_COMMAND_WRITE_ACK) || val & XELPDP_PORT_P2M_ERROR_SET) {
+		drm_dbg(&i915->drm, "PHY %c Unexpected ACK received. MSGBUS STATUS: 0x%x.\n", phy_name(phy), val);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+__maybe_unused static void intel_cx0_write(struct drm_i915_private *i915, enum port port,
+			    int lane, u16 addr, u8 data, bool committed)
+{
+	enum phy phy = intel_port_to_phy(i915, port);
+	int attempts = 0;
+
+retry:
+	if (attempts == 3) {
+		drm_err_once(&i915->drm, "PHY %c Write %04x failed after %d retries.\n", phy_name(phy), addr, attempts);
+		return;
+	}
+
+	/* Wait for pending transactions.*/
+	if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+				    XELPDP_PORT_M2P_TRANSACTION_PENDING,
+				    XELPDP_MSGBUS_TIMEOUT_SLOW)) {
+		drm_dbg(&i915->drm, "PHY %c Timeout waiting for previous transaction to complete. Reset the bus and retry.\n", phy_name(phy));
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	/* Issue the write command. */
+	intel_de_write(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
+		       XELPDP_PORT_M2P_TRANSACTION_PENDING |
+		       (committed ? XELPDP_PORT_M2P_COMMAND_WRITE_COMMITTED :
+		       XELPDP_PORT_M2P_COMMAND_WRITE_UNCOMMITTED) |
+		       XELPDP_PORT_M2P_DATA(data) |
+		       XELPDP_PORT_M2P_ADDRESS(addr));
+
+	/* Check for error. */
+	if (committed) {
+		if (intel_cx0_wait_cwrite_ack(i915, port, lane) < 0) {
+			attempts++;
+			intel_cx0_bus_reset(i915, port, lane);
+			goto retry;
+		}
+	} else if ((intel_de_read(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(phy, lane)) &
+			    XELPDP_PORT_P2M_ERROR_SET)) {
+		drm_dbg(&i915->drm, "PHY %c Error occurred during write command.\n", phy_name(phy));
+		attempts++;
+		intel_cx0_bus_reset(i915, port, lane);
+		goto retry;
+	}
+
+	intel_de_write(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane), ~0);
+
+	return;
+}
+
+__maybe_unused static void intel_cx0_rmw(struct drm_i915_private *i915, enum port port,
+			  int lane, u16 addr, u8 clear, u8 set, bool committed)
+{
+	u8 old, val;
+
+	old = intel_cx0_read(i915, port, lane, addr);
+	val = (old & ~clear) | set;
+
+	if (val != old)
+		intel_cx0_write(i915, port, lane, addr, val, committed);
+}
-- 
2.34.1


  reply	other threads:[~2022-09-29 13:22 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-29 13:17 [Intel-gfx] [PATCH 0/5] drm/i915/mtl: Add C10 phy support Mika Kahola
2022-09-29 13:17 ` Mika Kahola [this message]
2022-09-30  9:04   ` [Intel-gfx] [PATCH 1/5] drm/i915/mtl: Add Support for C10, C20 PHY Message Bus Jani Nikula
2022-10-06 10:04     ` Kahola, Mika
2022-10-11  0:00   ` Lucas De Marchi
2022-09-29 13:17 ` [Intel-gfx] [PATCH 2/5] drm/i915/mtl: Add PLL programming support for C10 phy Mika Kahola
2022-09-30  9:19   ` Jani Nikula
2022-09-29 13:17 ` [Intel-gfx] [PATCH 3/5] drm/i915/mtl: Add support for C10 phy programming Mika Kahola
2022-09-30  9:32   ` Jani Nikula
2022-10-14 12:44     ` Kahola, Mika
2022-10-18 10:39       ` Jani Nikula
2022-09-29 13:17 ` [Intel-gfx] [PATCH 4/5] drm/i915/mtl: Add C10 phy programming for HDMI Mika Kahola
2022-09-29 13:17 ` [Intel-gfx] [PATCH 5/5] drm/i915/mtl: Add vswing programming for C10 phys Mika Kahola
2022-09-29 19:46 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/mtl: Add C10 phy support Patchwork
2022-09-29 20:08 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-09-30 21:08 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2022-09-29 11:16 [Intel-gfx] [PATCH 0/5] drm/i915/mtl: Add C10 support Mika Kahola
2022-09-29 11:16 ` [Intel-gfx] [PATCH 1/5] drm/i915/mtl: Add Support for C10, C20 PHY Message Bus Mika Kahola

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=20220929131747.2592092-2-mika.kahola@intel.com \
    --to=mika.kahola@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox