Kaynağa Gözat

Merged TI feature audio-display into ti-linux-4.19.y

TI-Feature: audio-display
TI-Branch: audio_display-ti-linux-4.19.y

* 'audio_display-ti-linux-4.19.y' of ssh://bitbucket.itg.ti.com/lcpdpublicdom/audio-display: (26 commits)
  arm64: dts: ti: k3-j721e: Disable MHDP in SoC- and enable in board-dt
  arm64: dts: ti: k3-j721: cleanup DP connector data
  arm64: dts: ti: k3-j721: move DP routing and pinmux to board DT file
  phy: ti: j721e-wiz: Implement DisplayPort mode to the wiz driver
  Revert "HACK: phy: ti: j721e-wiz: override WIZ settings for DP"
  arm64: dts: ti: k3-j721e-proc-board-tps65917: Update wiz lane<n>-mode props
  arm64: dts: ti: k3-j721e-common-proc-board: Update wiz lane<n>-mode props
  dt-bindings: phy: ti,phy-j721e-wiz: Add "lane<n>-mode" properties
  dt-bindings: phy: Add PHY_TYPE_DP definition
  arm64: dts: ti: k3-j721e-main: Update wiz node compatible strings
  phy: ti: j721e-wiz: Use "ti,j721e-wiz-10g" or "ti,j721e-wiz-16g" compatible
  dt-bindings: phy: ti,phy-j721e-wiz: Add *-10g and *-16g to compatible
  drm/bridge: cdns-mhdp: Add error handling for phy_configure() function.
  drm/bridge: cdns-mhdp: Set correct value in framer config register.
  drm/bridge: cdns-mhdp: Add support for SSC handling.
  drm/bridge: cdns-mhdp: Add function to get max number of lanes.
  drm/bridge: cdns-mhdp: Remove extra phy configuration calls.
  drm/bridge: cdns-mhdp: Add separate function to improve code redability.
  drm/bridge: cdns-mhdp: Fix to read correct DPCD registers for DP 1.4+ devices
  drm/bridge: cdns-mhdp: Remove setting register DP_SET_POWER twice.
  ...

Signed-off-by: LCPD Auto Merger <lcpd_integration@list.ti.com>
LCPD Auto Merger 6 yıl önce
ebeveyn
işleme
9da80f6d55

+ 1 - 1
Documentation/devicetree/bindings/display/bridge/cdns,mhdp.txt

@@ -10,7 +10,7 @@ Required properties:
 - clocks: DP bridge clock, it's used by the IP to know how to translate
 	a number of clock cycles into a time (which is used to comply
 	with DP standard timings and delays),
-- phys: see the Documentation/devicetree/bindings/phy/phy-cadence-dp.txt
+- phys: see the Documentation/devicetree/bindings/phy/phy-cadence-torrent.txt
 - phy-names: must be "dpphy"
 
 Required subnodes:

+ 4 - 4
Documentation/devicetree/bindings/phy/phy-cadence-dp.txt → Documentation/devicetree/bindings/phy/phy-cadence-torrent.txt

@@ -1,12 +1,12 @@
-Cadence MHDP DisplayPort SD0801 PHY binding
-===========================================
+Cadence Torrent SD0801 PHY binding for DisplayPort
+===================================================
 
 This binding describes the Cadence SD0801 PHY hardware included with
 the Cadence MHDP DisplayPort controller.
 
 -------------------------------------------------------------------------------
 Required properties (controller (parent) node):
-- compatible	: Should be "cdns,dp-phy"
+- compatible	: Should be "cdns,torrent-phy"
 - clocks	: PHY reference clock. Must contain an entry in clock-names.
 		  See ../clocks/clock-bindings.txt for details.
 - clock-names	: Must be "refclk"
@@ -24,7 +24,7 @@ Optional properties:
 
 Example:
 	dp_phy: phy@f0fb030a00 {
-		compatible = "cdns,dp-phy";
+		compatible = "cdns,torrent-phy";
 		reg = <0xf0 0xfb030a00 0x0 0x00000040>,
 		      <0xf0 0xfb500000 0x0 0x00100000>;
 		num_lanes = <4>;

+ 11 - 2
Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.txt

@@ -1,7 +1,8 @@
 TI J721E WIZ (SERDES Wrapper)
 
 Required properties:
- - compatible: Should be "ti,j721e-wiz"
+ - compatible: Should be "ti,j721e-wiz-16g" for Sierra phy wrapper,
+	       or "ti,j721e-wiz-10g" for Torrent phy wrapper.
  - #address-cells : should be 2 to indicate the child node should use 2 cell
      for address
  - #size-cells: should be 2 to indicate the child node should use 2 cell for
@@ -32,6 +33,12 @@ clock bindings in Documentation/devicetree/bindings/clock/clock-bindings.txt
      Type-C spec states minimum CC pin debounce of 100 ms and maximum
      of 200 ms.
 
+ - lane<n>-mode, : Integer describing static lane usage for lane n. For
+     Sierra there may be properties for n = 0 and n = 1, for Torrent n = 0,
+     n = 1, n = 2, and n = 3. The constants to indicate the lane usage 
+     are defined in "include/dt-bindings/phy/phy.h". The lane is assumed
+     to be unused if the lane<n>-use property does not exist.
+
 Required subnodes:
  - Clock Subnode: WIZ node should have '3' subnodes for each of the clock
      selects it supports. The clock subnodes should have the following names
@@ -50,7 +57,7 @@ Required subnodes:
 
 Example: Example shows binding for SERDES_16G (Sierra SERDES with WIZ wrapper)
 serdes_wiz0: wiz@5000000 {
-	compatible = "ti,j721e-wiz";
+	compatible = "ti,j721e-wiz-16g";
 	#address-cells = <2>;
 	#size-cells = <2>;
 	power-domains = <&k3_pds 292 TI_SCI_PD_EXCLUSIVE>;
@@ -58,6 +65,8 @@ serdes_wiz0: wiz@5000000 {
 	num-lanes = <2>;
 	#reset-cells = <1>;
 	ranges;
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
 
 	pll0_refclk: pll0_refclk {
 		clocks = <&k3_clks 292 11>, <&cmn_refclk>;

+ 52 - 2
arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts

@@ -101,11 +101,12 @@
 	};
 
 	dp0: connector {
-		compatible = "dp-connector"; /* No such binding exists yet.. */
+		compatible = "dp-connector";
+		label = "DP0";
 
 		port {
 			dp_connector_in: endpoint {
-			remote-endpoint = <&dp_bridge_output>;
+				remote-endpoint = <&dp_bridge_output>;
 			};
 		};
 	};
@@ -432,6 +433,38 @@
 	};
 };
 
+&serdes_wiz4 {
+	lane0-mode = <PHY_TYPE_DP>;
+	lane1-mode = <PHY_TYPE_DP>;
+	lane2-mode = <PHY_TYPE_DP>;
+	lane3-mode = <PHY_TYPE_DP>;
+};
+
+&mhdp {
+	status = "ok";
+	pinctrl-names = "default";
+	pinctrl-0 = <&dp0_pins_default>;
+};
+
+&dp0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		dp_bridge_input: endpoint {
+			remote-endpoint = <&dpi_out_real0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dp_bridge_output: endpoint {
+			remote-endpoint = <&dp_connector_in>;
+		};
+	};
+};
+
 &main_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c0_pins_default>;
@@ -646,6 +679,8 @@
 &serdes_wiz3 {
 	typec-dir-gpios = <&main_gpio1 3 GPIO_ACTIVE_HIGH>;
 	typec-dir-debounce = <300>;	/* TUSB321, tCCB_DEFAULT 133 ms */
+	lane0-mode = <PHY_TYPE_USB3>;
+	lane1-mode = <PHY_TYPE_USB3>;
 };
 
 &serdes3 {
@@ -703,6 +738,11 @@
 	status = "disabled";
 };
 
+&serdes_wiz0 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes0 {
 	serdes0_pcie_link: link@0 {
 		reg = <0>;
@@ -713,6 +753,11 @@
 	};
 };
 
+&serdes_wiz1 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes1 {
 	serdes1_pcie_link: link@0 {
 		reg = <0>;
@@ -723,6 +768,11 @@
 	};
 };
 
+&serdes_wiz2 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes2 {
 	serdes2_pcie_link: link@0 {
 		reg = <0>;

+ 8 - 24
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi

@@ -629,7 +629,7 @@
 	};
 
 	serdes_wiz0: wiz@5000000 {
-		compatible = "ti,j721e-wiz";
+		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 292 TI_SCI_PD_EXCLUSIVE>;
@@ -691,7 +691,7 @@
 	};
 
 	serdes_wiz1: wiz@5010000 {
-		compatible = "ti,j721e-wiz";
+		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 293 TI_SCI_PD_EXCLUSIVE>;
@@ -753,7 +753,7 @@
 	};
 
 	serdes_wiz2: wiz@5020000 {
-		compatible = "ti,j721e-wiz";
+		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 294 TI_SCI_PD_EXCLUSIVE>;
@@ -815,7 +815,7 @@
 	};
 
 	serdes_wiz3: wiz@5030000 {
-		compatible = "ti,j721e-wiz";
+		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 295 TI_SCI_PD_EXCLUSIVE>;
@@ -877,7 +877,7 @@
 	};
 
 	serdes_wiz4: wiz@5050000 {
-		compatible = "ti,j721e-wiz";
+		compatible = "ti,j721e-wiz-10g";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 297 TI_SCI_PD_EXCLUSIVE>;
@@ -929,7 +929,7 @@
 
 		serdes4: serdes@5050000 {
 			/* XXX we also map EDP0 registers here as the PHY driver needs those... */
-			compatible = "cdns,dp-phy";
+			compatible = "cdns,torrent-phy";
 			reg = <0x00 0x05050000 0x0 0x00010000>, /* SERDES_10G0 */
 			      <0x00 0x0A030A00 0x0 0x00000040>; /* DSS_EDP0_V2A_CORE_VP_REGS_APB + 30A00 */
 
@@ -950,8 +950,7 @@
 		reg = <0x00 0x0A000000 0x0 0x30A00>, /* DSS_EDP0_V2A_CORE_VP_REGS_APB - upto PHY mapped area */
 		      <0x00 0x04F40000 0x0 0x20>;    /* DSS_EDP0_INTG_CFG_VP */
 
-		pinctrl-names = "default";
-		pinctrl-0 = <&dp0_pins_default>;
+		status = "disabled";
 
 		clocks = <&k3_clks 151 36>;
 
@@ -964,25 +963,10 @@
 		power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>;
 
 		/* TODO: No audio config yet */
-		/* TODO: Pinmux for eDP output pins */
 
-		ports {
+		dp0_ports: ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				dp_bridge_input: endpoint {
-					remote-endpoint = <&dpi_out_real0>;
-				};
-			};
-
-			port@1 {
-				reg = <1>;
-				dp_bridge_output: endpoint {
-					remote-endpoint = <&dp_connector_in>;
-				};
-			};
 		};
 	};
 

+ 52 - 2
arch/arm64/boot/dts/ti/k3-j721e-proc-board-tps65917.dts

@@ -156,11 +156,12 @@
 	};
 
 	dp0: connector {
-		compatible = "dp-connector"; /* No such binding exists yet.. */
+		compatible = "dp-connector";
+		label = "DP0";
 
 		port {
 			dp_connector_in: endpoint {
-			remote-endpoint = <&dp_bridge_output>;
+				remote-endpoint = <&dp_bridge_output>;
 			};
 		};
 	};
@@ -467,6 +468,38 @@
 	};
 };
 
+&serdes_wiz4 {
+	lane0-mode = <PHY_TYPE_DP>;
+	lane1-mode = <PHY_TYPE_DP>;
+	lane2-mode = <PHY_TYPE_DP>;
+	lane3-mode = <PHY_TYPE_DP>;
+};
+
+&mhdp {
+	status = "ok";
+	pinctrl-names = "default";
+	pinctrl-0 = <&dp0_pins_default>;
+};
+
+&dp0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		dp_bridge_input: endpoint {
+			remote-endpoint = <&dpi_out_real0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dp_bridge_output: endpoint {
+			remote-endpoint = <&dp_connector_in>;
+		};
+	};
+};
+
 &main_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c0_pins_default>;
@@ -681,6 +714,8 @@
 &serdes_wiz3 {
 	typec-dir-gpios = <&main_gpio1 3 GPIO_ACTIVE_HIGH>;
 	typec-dir-debounce = <300>;	/* TUSB321, tCCB_DEFAULT 133 ms */
+	lane0-mode = <PHY_TYPE_USB3>;
+	lane1-mode = <PHY_TYPE_USB3>;
 };
 
 &serdes3 {
@@ -738,6 +773,11 @@
 	status = "disabled";
 };
 
+&serdes_wiz0 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes0 {
 	serdes0_pcie_link: link@0 {
 		reg = <0>;
@@ -748,6 +788,11 @@
 	};
 };
 
+&serdes_wiz1 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes1 {
 	serdes1_pcie_link: link@0 {
 		reg = <0>;
@@ -758,6 +803,11 @@
 	};
 };
 
+&serdes_wiz2 {
+	lane0-mode = <PHY_TYPE_PCIE>;
+	lane1-mode = <PHY_TYPE_PCIE>;
+};
+
 &serdes2 {
 	serdes2_pcie_link: link@0 {
 		reg = <0>;

+ 84 - 62
drivers/gpu/drm/bridge/cdns-mhdp.c

@@ -641,12 +641,24 @@ static unsigned int max_link_rate(struct cdns_mhdp_host host,
 	return min(host.link_rate, sink.link_rate);
 }
 
+static u8 mhdp_max_num_lanes(struct cdns_mhdp_host host,
+			     struct cdns_mhdp_sink sink)
+{
+	return min_t(u8, sink.lanes_cnt, host.lanes_cnt);
+}
+
 static u8 eq_training_pattern_supported(struct cdns_mhdp_host host,
 					struct cdns_mhdp_sink sink)
 {
 	return fls(host.pattern_supp & sink.pattern_supp);
 }
 
+static bool mhdp_get_ssc_supported(struct cdns_mhdp_device *mhdp)
+{
+	/* Check if SSC is supported by both sides */
+	return (mhdp->host.ssc) && (mhdp->sink.ssc);
+}
+
 static int mhdp_fw_activate(const struct firmware *fw,
 			    struct cdns_mhdp_device *mhdp)
 {
@@ -1082,11 +1094,12 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge)
 	return 0;
 }
 
-static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
+static int mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 {
 	u32 reg32;
 	u8 i;
 	union phy_configure_opts phy_cfg;
+	int ret;
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_DISABLE);
@@ -1111,11 +1124,16 @@ static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 		phy_cfg.dp.voltage[i] = 0;
 		phy_cfg.dp.pre[i] = 0;
 	}
-	phy_cfg.dp.ssc = false;
+	phy_cfg.dp.ssc = mhdp_get_ssc_supported(mhdp);
 	phy_cfg.dp.set_lanes = true;
 	phy_cfg.dp.set_rate = true;
 	phy_cfg.dp.set_voltages = true;
-	phy_configure(mhdp->phy,  &phy_cfg);
+	ret = phy_configure(mhdp->phy,  &phy_cfg);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return ret;
+	}
 
 	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
 			    CDNS_PHY_COMMON_CONFIG |
@@ -1125,6 +1143,8 @@ static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE);
+
+	return 0;
 }
 
 static void mhdp_get_adjust_train(struct cdns_mhdp_device *mhdp,
@@ -1224,6 +1244,7 @@ static bool mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	u32 reg32;
 	union phy_configure_opts phy_cfg;
+	int ret;
 
 	dev_dbg(mhdp->dev, "Starting EQ phase\n");
 
@@ -1243,11 +1264,16 @@ static bool mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 	do {
 		mhdp_get_adjust_train(mhdp, link_status, lanes_data, &phy_cfg);
 		phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-		phy_cfg.dp.ssc = false;
+		phy_cfg.dp.ssc = mhdp_get_ssc_supported(mhdp);
 		phy_cfg.dp.set_lanes = false;
 		phy_cfg.dp.set_rate = false;
 		phy_cfg.dp.set_voltages = true;
-		phy_configure(mhdp->phy,  &phy_cfg);
+		ret = phy_configure(mhdp->phy,  &phy_cfg);
+		if (ret) {
+			dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+				__func__, ret);
+			goto err;
+		}
 
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes,
 				    training_interval, lanes_data, link_status);
@@ -1340,10 +1366,13 @@ static bool mhdp_link_training_cr(struct cdns_mhdp_device *mhdp)
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	bool cr_done;
 	union phy_configure_opts phy_cfg;
+	int ret;
 
 	dev_dbg(mhdp->dev, "Starting CR phase\n");
 
-	mhdp_link_training_init(mhdp);
+	ret = mhdp_link_training_init(mhdp);
+	if (ret)
+		goto err;
 
 	drm_dp_dpcd_read_link_status(&mhdp->aux, link_status);
 
@@ -1354,11 +1383,16 @@ static bool mhdp_link_training_cr(struct cdns_mhdp_device *mhdp)
 
 		mhdp_get_adjust_train(mhdp, link_status, lanes_data, &phy_cfg);
 		phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-		phy_cfg.dp.ssc = false;
+		phy_cfg.dp.ssc = mhdp_get_ssc_supported(mhdp);
 		phy_cfg.dp.set_lanes = false;
 		phy_cfg.dp.set_rate = false;
 		phy_cfg.dp.set_voltages = true;
-		phy_configure(mhdp->phy,  &phy_cfg);
+		ret = phy_configure(mhdp->phy,  &phy_cfg);
+		if (ret) {
+			dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+				__func__, ret);
+			goto err;
+		}
 
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes, 100,
 				    lanes_data, link_status);
@@ -1422,7 +1456,6 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			      unsigned int training_interval)
 {
 	u32 reg32;
-	union phy_configure_opts phy_cfg;
 	const u8 eq_tps = eq_training_pattern_supported(mhdp->host, mhdp->sink);
 
 	while (1) {
@@ -1432,14 +1465,6 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 				dev_dbg(mhdp->dev,
 					"Reducing link rate during CR phase\n");
 				lower_link_rate(&mhdp->link);
-				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
-				phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
-				phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-				phy_cfg.dp.ssc = false;
-				phy_cfg.dp.set_lanes = false;
-				phy_cfg.dp.set_rate = true;
-				phy_cfg.dp.set_voltages = false;
-				phy_configure(mhdp->phy,  &phy_cfg);
 
 				continue;
 			} else if (mhdp->link.num_lanes > 1) {
@@ -1448,14 +1473,6 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 				mhdp->link.num_lanes >>= 1;
 				mhdp->link.rate = max_link_rate(mhdp->host,
 								mhdp->sink);
-				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
-				phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
-				phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-				phy_cfg.dp.ssc = false;
-				phy_cfg.dp.set_lanes = true;
-				phy_cfg.dp.set_rate = false;
-				phy_cfg.dp.set_voltages = false;
-				phy_configure(mhdp->phy,  &phy_cfg);
 
 				continue;
 			}
@@ -1473,14 +1490,6 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			dev_dbg(mhdp->dev,
 				"Reducing lanes number during EQ phase\n");
 			mhdp->link.num_lanes >>= 1;
-			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
-			phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
-			phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-			phy_cfg.dp.ssc = false;
-			phy_cfg.dp.set_lanes = true;
-			phy_cfg.dp.set_rate = false;
-			phy_cfg.dp.set_voltages = false;
-			phy_configure(mhdp->phy,  &phy_cfg);
 
 			continue;
 		} else if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
@@ -1488,14 +1497,7 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			dev_dbg(mhdp->dev,
 				"Reducing link rate during EQ phase\n");
 			lower_link_rate(&mhdp->link);
-			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
-			phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
-			phy_cfg.dp.lanes = (mhdp->link.num_lanes);
-			phy_cfg.dp.ssc = false;
-			phy_cfg.dp.set_lanes = false;
-			phy_cfg.dp.set_rate = true;
-			phy_cfg.dp.set_voltages = false;
-			phy_configure(mhdp->phy,  &phy_cfg);
+			mhdp->link.num_lanes = mhdp_max_num_lanes(mhdp->host, mhdp->sink);
 
 			continue;
 		}
@@ -1513,6 +1515,7 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
 	reg32 &= ~GENMASK(1, 0);
 	reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes);
+	reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC;
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
 
 	/* Reset PHY config */
@@ -1573,16 +1576,37 @@ static u32 get_training_interval_us(struct cdns_mhdp_device *mhdp,
 	return 0;
 }
 
+static void mhdp_fill_sink_caps(struct cdns_mhdp_device *mhdp,
+				u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	mhdp->sink.link_rate = mhdp->link.rate;
+	mhdp->sink.lanes_cnt = mhdp->link.num_lanes;
+	mhdp->sink.enhanced = !!(mhdp->link.capabilities &
+				 DP_LINK_CAP_ENHANCED_FRAMING);
+
+	/* Set SSC support */
+	mhdp->sink.ssc = !!(dpcd[DP_MAX_DOWNSPREAD] &
+				  DP_MAX_DOWNSPREAD_0_5);
+
+	/* Set TPS support */
+	mhdp->sink.pattern_supp = CDNS_SUPPORT_TPS(1) | CDNS_SUPPORT_TPS(2);
+	if (drm_dp_tps3_supported(dpcd))
+		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(3);
+	if (drm_dp_tps4_supported(dpcd))
+		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(4);
+
+	/* Set fast link support */
+	mhdp->sink.fast_link = !!(dpcd[DP_MAX_DOWNSPREAD] &
+				  DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+}
+
 static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 {
 	u32 resp;
 	u8 reg0[DP_RECEIVER_CAP_SIZE], amp[2];
-
-	/*
-	 * Upon power-on reset/device disconnection: [2:0] bits should be 0b001
-	 * and [7:5] bits 0b000.
-	 */
-	drm_dp_dpcd_writeb(&mhdp->aux, DP_SET_POWER, 1);
+	u8 ext_cap_chk = 0;
+	unsigned int addr;
+	int err;
 
 	drm_dp_link_probe(&mhdp->aux, &mhdp->link);
 
@@ -1591,25 +1615,23 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	/* FIXME (CDNS): do we have to wait for 100ms before going on? */
 	mdelay(100);
 
-	mhdp->sink.link_rate = mhdp->link.rate;
-	mhdp->sink.lanes_cnt = mhdp->link.num_lanes;
-	mhdp->sink.enhanced = !!(mhdp->link.capabilities &
-				 DP_LINK_CAP_ENHANCED_FRAMING);
+	drm_dp_dpcd_readb(&mhdp->aux, DP_TRAINING_AUX_RD_INTERVAL, &ext_cap_chk);
 
-	drm_dp_dpcd_read(&mhdp->aux, DP_DPCD_REV, reg0, DP_RECEIVER_CAP_SIZE);
+	if (ext_cap_chk & DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)
+		addr = DP_DP13_DPCD_REV;
+	else
+		addr = DP_DPCD_REV;
 
-	mhdp->sink.pattern_supp = CDNS_SUPPORT_TPS(1) | CDNS_SUPPORT_TPS(2);
-	if (drm_dp_tps3_supported(reg0))
-		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(3);
-	if (drm_dp_tps4_supported(reg0))
-		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(4);
+	err = drm_dp_dpcd_read(&mhdp->aux, addr, reg0, DP_RECEIVER_CAP_SIZE);
+	if (err < 0) {
+		dev_err(mhdp->dev, "Failed to read receiver capabilities\n");
+		return err;
+	}
 
-	mhdp->sink.fast_link = !!(reg0[DP_MAX_DOWNSPREAD] &
-				  DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+	mhdp_fill_sink_caps(mhdp, reg0);
 
 	mhdp->link.rate = max_link_rate(mhdp->host, mhdp->sink);
-	mhdp->link.num_lanes = min_t(u8, mhdp->sink.lanes_cnt,
-				     mhdp->host.lanes_cnt & GENMASK(2, 0));
+	mhdp->link.num_lanes = mhdp_max_num_lanes(mhdp->host, mhdp->sink);
 
 	/* Disable framer for link training */
 	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
@@ -1617,7 +1639,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	/* Spread AMP if required, enable 8b/10b coding */
-	amp[0] = mhdp->host.ssc ? DP_SPREAD_AMP_0_5 : 0;
+	amp[0] = mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0;
 	amp[1] = DP_SET_ANSI_8B10B;
 	drm_dp_dpcd_write(&mhdp->aux, DP_DOWNSPREAD_CTRL, amp, 2);
 

+ 3 - 2
drivers/gpu/drm/bridge/cdns-mhdp.h

@@ -202,8 +202,9 @@ struct cdns_mhdp_sink {
 	unsigned int link_rate;
 	u8 lanes_cnt;
 	u8 pattern_supp;
-	u8 fast_link;
-	u8 enhanced;
+	u8 fast_link : 1;
+	u8 enhanced : 1;
+	u8 ssc : 1;
 };
 
 struct cdns_mhdp_display_fmt {

+ 4 - 4
drivers/phy/cadence/Kconfig

@@ -1,17 +1,17 @@
 #
 # Phy drivers for Cadence PHYs
 #
-config PHY_CADENCE_DP
-	tristate "Cadence MHDP DisplayPort PHY driver"
+config PHY_CADENCE_TORRENT
+	tristate "Cadence Torrent PHY driver"
 	depends on OF
 	depends on HAS_IOMEM
 	select GENERIC_PHY
 	help
-	  Support for Cadence MHDP DisplayPort PHY.
+	  Support for Cadence Torrent PHY.
 
 config PHY_CADENCE_SIERRA
 	tristate "Cadence Sierra PHY Driver"
 	depends on OF && HAS_IOMEM && RESET_CONTROLLER
 	select GENERIC_PHY
 	help
-	  Enable this to support the Cadence Sierra PHY driver
+	  Enable this to support the Cadence Sierra PHY driver

+ 1 - 1
drivers/phy/cadence/Makefile

@@ -1,2 +1,2 @@
-obj-$(CONFIG_PHY_CADENCE_DP)	+= phy-cadence-dp.o
+obj-$(CONFIG_PHY_CADENCE_TORRENT)	+= phy-cadence-torrent.o
 obj-$(CONFIG_PHY_CADENCE_SIERRA)	+= phy-cadence-sierra.o

+ 115 - 115
drivers/phy/cadence/phy-cadence-dp.c → drivers/phy/cadence/phy-cadence-torrent.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Cadence MHDP DisplayPort SD0801 PHY driver.
+ * Cadence Torrent SD0801 PHY driver.
  *
  * Copyright 2018 Cadence Design Systems, Inc.
  *
@@ -161,7 +161,7 @@
 #define RX_REE_GCSM2_CTRL(j)			(0x8000 + 0x0220 + (j) * 0x400)
 #define RX_REE_PERGCSM_CTRL(j)			(0x8000 + 0x0230 + (j) * 0x400)
 
-struct cdns_dp_phy {
+struct cdns_torrent_phy {
 	void __iomem *base;	/* DPTX registers base */
 	void __iomem *sd_base;	/* SD0801 registers base */
 	u32 num_lanes; /* Number of lanes to use */
@@ -179,39 +179,39 @@ enum phy_powerstate {
 	POWERSTATE_A3 = 3,
 };
 
-static int cdns_dp_phy_init(struct phy *phy);
-static int cdns_dp_phy_exit(struct phy *phy);
-static int cdns_dp_phy_run(struct cdns_dp_phy *cdns_phy);
-static int cdns_dp_phy_wait_pma_cmn_ready(struct cdns_dp_phy *cdns_phy);
-static void cdns_dp_phy_pma_cfg(struct cdns_dp_phy *cdns_phy);
-static void cdns_dp_phy_pma_cmn_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy);
-static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy, u32 rate, bool ssc);
-static void cdns_dp_phy_pma_cmn_cfg_25mhz(struct cdns_dp_phy *cdns_phy);
-static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy, u32 rate, bool ssc);
-static void cdns_dp_phy_pma_lane_cfg(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_init(struct phy *phy);
+static int cdns_torrent_dp_exit(struct phy *phy);
+static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy);
+static int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
+static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy);
+static void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
+static void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc);
+static void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
+static void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, u32 rate, bool ssc);
+static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
 				     unsigned int lane);
-static void cdns_dp_phy_pma_cmn_rate(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
 				     u32 rate, u32 lanes);
-static void cdns_dp_phy_write_field(struct cdns_dp_phy *cdns_phy,
+static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
 				    unsigned int offset,
 				    unsigned char start_bit,
 				    unsigned char num_bits,
 				    unsigned int val);
-static int cdns_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts);
-static void cdns_dp_phy_set_a0_pll(struct cdns_dp_phy *cdns_phy, u32 num_lanes);
-static int cdns_dp_phy_set_power_state(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_configure(struct phy *phy, union phy_configure_opts *opts);
+static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy, u32 num_lanes);
+static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
 				       u32 num_lanes,
 				       enum phy_powerstate powerstate);
 
-static int cdns_dp_phy_on(struct phy *gphy);
-static int cdns_dp_phy_off(struct phy *gphy);
+static int cdns_torrent_phy_on(struct phy *gphy);
+static int cdns_torrent_phy_off(struct phy *gphy);
 
-static const struct phy_ops cdns_dp_phy_ops = {
-	.init		= cdns_dp_phy_init,
-	.exit		= cdns_dp_phy_exit,
-	.configure	= cdns_dp_phy_configure,
-	.power_on	= cdns_dp_phy_on,
-	.power_off	= cdns_dp_phy_off,
+static const struct phy_ops cdns_torrent_phy_ops = {
+	.init		= cdns_torrent_dp_init,
+	.exit		= cdns_torrent_dp_exit,
+	.configure	= cdns_torrent_dp_configure,
+	.power_on	= cdns_torrent_phy_on,
+	.power_off	= cdns_torrent_phy_off,
 	.owner		= THIS_MODULE,
 };
 
@@ -228,18 +228,18 @@ static const struct phy_ops cdns_dp_phy_ops = {
 	_cdns_dp_phy_write_phy(cdns_phy, offset, val); \
 })
 
-static void _cdns_dp_phy_write_phy(struct cdns_dp_phy *cdns_phy, u32 offset, u16 val)
+static void _cdns_dp_phy_write_phy(struct cdns_torrent_phy *cdns_phy, u32 offset, u16 val)
 {
 	writew(val, cdns_phy->sd_base + offset);
 }
 #else
-static void cdns_dp_phy_write_phy(struct cdns_dp_phy *cdns_phy, u32 offset, u16 val)
+static void cdns_dp_phy_write_phy(struct cdns_torrent_phy *cdns_phy, u32 offset, u16 val)
 {
 	writew(val, cdns_phy->sd_base + offset);
 }
 #endif
 
-static u16 cdns_dp_phy_read_phy(struct cdns_dp_phy *cdns_phy, u32 offset)
+static u16 cdns_dp_phy_read_phy(struct cdns_torrent_phy *cdns_phy, u32 offset)
 {
 	return readw(cdns_phy->sd_base + offset);
 }
@@ -257,18 +257,18 @@ static u16 cdns_dp_phy_read_phy(struct cdns_dp_phy *cdns_phy, u32 offset)
 	_cdns_dp_phy_write_dp(cdns_phy, offset, val); \
 })
 
-static void _cdns_dp_phy_write_dp(struct cdns_dp_phy *cdns_phy, u32 offset, u16 val)
+static void _cdns_dp_phy_write_dp(struct cdns_torrent_phy *cdns_phy, u32 offset, u16 val)
 {
 	writel(val, cdns_phy->base + offset);
 }
 #else
-static void cdns_dp_phy_write_dp(struct cdns_dp_phy *cdns_phy, u32 offset, u16 val)
+static void cdns_dp_phy_write_dp(struct cdns_torrent_phy *cdns_phy, u32 offset, u16 val)
 {
 	writel(val, cdns_phy->base + offset);
 }
 #endif
 
-static u32 cdns_dp_phy_read_dp(struct cdns_dp_phy *cdns_phy, u32 offset)
+static u32 cdns_dp_phy_read_dp(struct cdns_torrent_phy *cdns_phy, u32 offset)
 {
 	return readl(cdns_phy->base + offset);
 }
@@ -325,12 +325,12 @@ static const struct coefficients voltage_coeffs[4][4] = {
 	}
 };
 
-static int cdns_dp_phy_init(struct phy *phy)
+static int cdns_torrent_dp_init(struct phy *phy)
 {
 	unsigned char lane_bits;
 	int r;
 
-	struct cdns_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
 
 	r = clk_prepare_enable(cdns_phy->clk);
 	if (r) {
@@ -358,13 +358,13 @@ static int cdns_dp_phy_init(struct phy *phy)
 	cdns_dp_phy_write_dp(cdns_phy, PHY_AUX_CTRL, 0x0003); /* enable AUX */
 
 	/* PHY PMA registers configuration function */
-	cdns_dp_phy_pma_cfg(cdns_phy);
+	cdns_torrent_dp_pma_cfg(cdns_phy);
 
 	/*
 	 * Set lines power state to A0
 	 * Set lines pll clk enable to 0
 	 */
-	cdns_dp_phy_set_a0_pll(cdns_phy, cdns_phy->num_lanes);
+	cdns_torrent_dp_set_a0_pll(cdns_phy, cdns_phy->num_lanes);
 
 	/*
 	 * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on
@@ -379,32 +379,32 @@ static int cdns_dp_phy_init(struct phy *phy)
 	/* PHY PMA registers configuration functions */
 	/* Initialize PHY with max supported link rate, without SSC. */
 	if (cdns_phy->ref_clk_rate ==  REF_CLK_19_2MHz)
-		cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(cdns_phy, cdns_phy->max_bit_rate, false);
+		cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, cdns_phy->max_bit_rate, false);
 	else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
-		cdns_dp_phy_pma_cmn_vco_cfg_25mhz(cdns_phy, cdns_phy->max_bit_rate, false);
-	cdns_dp_phy_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate, cdns_phy->num_lanes);
+		cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, cdns_phy->max_bit_rate, false);
+	cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate, cdns_phy->num_lanes);
 
 	/* take out of reset */
 	cdns_dp_phy_write_field(cdns_phy, PHY_RESET, 8, 1, 1);
-	cdns_dp_phy_on(phy);
-	r = cdns_dp_phy_wait_pma_cmn_ready(cdns_phy);
+	cdns_torrent_phy_on(phy);
+	r = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
 	if (r)
 		return r;
 
-	r = cdns_dp_phy_run(cdns_phy);
+	r = cdns_torrent_dp_run(cdns_phy);
 
 	return r;
 }
 
-static int cdns_dp_phy_exit(struct phy *phy)
+static int cdns_torrent_dp_exit(struct phy *phy)
 {
-	struct cdns_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
 
 	clk_disable_unprepare(cdns_phy->clk);
 	return 0;
 }
 
-static int cdns_dp_phy_wait_pma_cmn_ready(struct cdns_dp_phy *cdns_phy)
+static int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
 {
 	unsigned int reg;
 	int ret;
@@ -420,23 +420,23 @@ static int cdns_dp_phy_wait_pma_cmn_ready(struct cdns_dp_phy *cdns_phy)
 	return 0;
 }
 
-static void cdns_dp_phy_pma_cfg(struct cdns_dp_phy *cdns_phy)
+static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy)
 {
 	unsigned int i;
 
 	if (cdns_phy->ref_clk_rate ==  REF_CLK_19_2MHz)
 		/* PMA common configuration 19.2MHz */
-		cdns_dp_phy_pma_cmn_cfg_19_2mhz(cdns_phy);
+		cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
 	else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
 		/* PMA common configuration 25MHz */
-		cdns_dp_phy_pma_cmn_cfg_25mhz(cdns_phy);
+		cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
 
 	/* PMA lane configuration to deal with multi-link operation */
 	for (i = 0; i < cdns_phy->num_lanes; i++)
-		cdns_dp_phy_pma_lane_cfg(cdns_phy, i);
+		cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
 }
 
-static void cdns_dp_phy_pma_cmn_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy)
+static void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
 {
 	/* refclock registers - assumes 19.2 MHz refclock */
 	cdns_dp_phy_write_phy(cdns_phy, CMN_SSM_BIAS_TMR, 0x0014);
@@ -481,7 +481,7 @@ static void cdns_dp_phy_pma_cmn_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy)
  * Set registers responsible for enabling and configuring SSC, with second and
  * third register values provided by parameters.
  */
-static void cdns_dp_phy_enable_ssc_19_2mhz(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
 					   u32 ctrl2_val, u32 ctrl3_val)
 {
 	cdns_dp_phy_write_phy(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x0001);
@@ -494,7 +494,7 @@ static void cdns_dp_phy_enable_ssc_19_2mhz(struct cdns_dp_phy *cdns_phy,
 	cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_SS_CTRL4_M0, 0x0003);
 }
 
-static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
 						u32 rate, bool ssc)
 {
 
@@ -514,7 +514,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x00BC);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_19_2mhz(cdns_phy, 0x033A, 0x006A);
+			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A, 0x006A);
 		break;
 	/* Setting VCO for 9.72GHz */
 	case 1620:
@@ -531,7 +531,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x0152);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 0x0069);
+			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 0x0069);
 		break;
 	/* Setting VCO for 8.64GHz */
 	case 2160:
@@ -547,7 +547,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x012C);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_19_2mhz(cdns_phy, 0x0536, 0x0069);
+			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536, 0x0069);
 		break;
 	/* Setting VCO for 8.1GHz */
 	case 8100:
@@ -562,7 +562,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x011A);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_19_2mhz(cdns_phy, 0x04D7, 0x006A);
+			cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7, 0x006A);
 		break;
 	}
 
@@ -594,7 +594,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(struct cdns_dp_phy *cdns_phy,
 }
 
 
-static void cdns_dp_phy_pma_cmn_cfg_25mhz(struct cdns_dp_phy *cdns_phy)
+static void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
 {
 	/* refclock registers - assumes 25 MHz refclock */
 	cdns_dp_phy_write_phy(cdns_phy, CMN_SSM_BIAS_TMR, 0x0019);
@@ -638,7 +638,7 @@ static void cdns_dp_phy_pma_cmn_cfg_25mhz(struct cdns_dp_phy *cdns_phy)
  * Set registers responsible for enabling and configuring SSC, with second
  * register value provided by a parameter.
  */
-static void cdns_dp_phy_enable_ssc_25mhz(struct cdns_dp_phy *cdns_phy, u32 ctrl2_val)
+static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy, u32 ctrl2_val)
 {
 	cdns_dp_phy_write_phy(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x0001);
 	cdns_dp_phy_write_phy(cdns_phy, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
@@ -650,7 +650,7 @@ static void cdns_dp_phy_enable_ssc_25mhz(struct cdns_dp_phy *cdns_phy, u32 ctrl2
 	cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_SS_CTRL4_M0, 0x0003);
 }
 
-static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
 					      u32 rate, bool ssc)
 {
 	/* Assumes 25 MHz refclock */
@@ -667,7 +667,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x0120);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_25mhz(cdns_phy, 0x0423);
+			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
 		break;
 	/* Setting VCO for 9.72GHz */
 	case 1620:
@@ -682,7 +682,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x0104);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_25mhz(cdns_phy, 0x03B9);
+			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
 		break;
 	/* Setting VCO for 8.64GHz */
 	case 2160:
@@ -696,7 +696,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x00E7);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_25mhz(cdns_phy, 0x034F);
+			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
 		break;
 	/* Setting VCO for 8.1GHz */
 	case 8100:
@@ -709,7 +709,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
 		cdns_dp_phy_write_phy(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x00D8);
 		if (ssc)
-			cdns_dp_phy_enable_ssc_25mhz(cdns_phy, 0x031A);
+			cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
 		break;
 	}
 
@@ -744,7 +744,7 @@ static void cdns_dp_phy_pma_cmn_vco_cfg_25mhz(struct cdns_dp_phy *cdns_phy,
 }
 
 
-static void cdns_dp_phy_pma_cmn_rate(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
 				     u32 rate, u32 lanes)
 {
 	unsigned int clk_sel_val = 0;
@@ -789,7 +789,7 @@ static void cdns_dp_phy_pma_cmn_rate(struct cdns_dp_phy *cdns_phy,
 				      hsclk_div_val);
 }
 
-static void cdns_dp_phy_pma_lane_cfg(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
 				     unsigned int lane)
 {
 	/* Per lane, refclock-dependent receiver detection setting */
@@ -817,7 +817,7 @@ static void cdns_dp_phy_pma_lane_cfg(struct cdns_dp_phy *cdns_phy,
 	cdns_dp_phy_write_phy(cdns_phy, XCVR_DIAG_HSCLK_SEL(lane), 0x0000);
 }
 
-static int cdns_dp_phy_run(struct cdns_dp_phy *cdns_phy)
+static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy)
 {
 	unsigned int read_val;
 	int ret;
@@ -836,16 +836,16 @@ static int cdns_dp_phy_run(struct cdns_dp_phy *cdns_phy)
 
 	ndelay(100);
 
-	ret = cdns_dp_phy_set_power_state(cdns_phy, cdns_phy->num_lanes, POWERSTATE_A2);
+	ret = cdns_torrent_dp_set_power_state(cdns_phy, cdns_phy->num_lanes, POWERSTATE_A2);
 	if (ret)
 		return ret;
 
-	ret = cdns_dp_phy_set_power_state(cdns_phy, cdns_phy->num_lanes, POWERSTATE_A0);
+	ret = cdns_torrent_dp_set_power_state(cdns_phy, cdns_phy->num_lanes, POWERSTATE_A0);
 
 	return ret;
 }
 
-static void cdns_dp_phy_write_field(struct cdns_dp_phy *cdns_phy,
+static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
 				    unsigned int offset,
 				    unsigned char start_bit,
 				    unsigned char num_bits,
@@ -859,25 +859,25 @@ static void cdns_dp_phy_write_field(struct cdns_dp_phy *cdns_phy,
 								 start_bit))));
 }
 
-static int cdns_dp_phy_on(struct phy *phy)
+static int cdns_torrent_phy_on(struct phy *phy)
 {
-	struct cdns_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
 
 	/* Take the PHY lane group out of reset */
 	return reset_control_deassert(cdns_phy->phy_rst);
 }
 
-static int cdns_dp_phy_off(struct phy *phy)
+static int cdns_torrent_phy_off(struct phy *phy)
 {
-	struct cdns_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
 
 	return reset_control_assert(cdns_phy->phy_rst);
 }
 
-static int cdns_dp_phy_probe(struct platform_device *pdev)
+static int cdns_torrent_phy_probe(struct platform_device *pdev)
 {
 	struct resource *regs;
-	struct cdns_dp_phy *cdns_phy;
+	struct cdns_torrent_phy *cdns_phy;
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct phy *phy;
@@ -889,9 +889,9 @@ static int cdns_dp_phy_probe(struct platform_device *pdev)
 
 	cdns_phy->dev = &pdev->dev;
 
-	phy = devm_phy_create(dev, NULL, &cdns_dp_phy_ops);
+	phy = devm_phy_create(dev, NULL, &cdns_torrent_phy_ops);
 	if (IS_ERR(phy)) {
-		dev_err(dev, "failed to create DisplayPort PHY\n");
+		dev_err(dev, "failed to create Torrent PHY\n");
 		return PTR_ERR(phy);
 	}
 
@@ -964,7 +964,7 @@ static int cdns_dp_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
-static int cdns_dp_phy_set_power_state(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
 				       u32 num_lanes,
 				       enum phy_powerstate powerstate)
 {
@@ -1026,7 +1026,7 @@ static int cdns_dp_phy_set_power_state(struct cdns_dp_phy *cdns_phy,
 /*
  * Enable or disable PLL for selected lanes.
  */
-static int cdns_dp_phy_set_pll_en(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy,
 				  struct phy_configure_opts_dp *dp,
 				  bool enable)
 {
@@ -1078,7 +1078,7 @@ static int cdns_dp_phy_set_pll_en(struct cdns_dp_phy *cdns_phy,
  * Perform register operations related to setting link rate, once powerstate is
  * set and PLL disable request was processed.
  */
-static int cdns_dp_phy_configure_rate(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
 				      struct phy_configure_opts_dp *dp)
 {
 	u32 ret;
@@ -1100,14 +1100,14 @@ static int cdns_dp_phy_configure_rate(struct cdns_dp_phy *cdns_phy,
 	/* DP Rate Change - VCO Output settings. */
 	if (cdns_phy->ref_clk_rate ==  REF_CLK_19_2MHz) {
 		/* PMA common configuration 19.2MHz */
-		cdns_dp_phy_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc);
-		cdns_dp_phy_pma_cmn_cfg_19_2mhz(cdns_phy);
+		cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, dp->ssc);
+		cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
 	} else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) {
 		/* PMA common configuration 25MHz */
-		cdns_dp_phy_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc);
-		cdns_dp_phy_pma_cmn_cfg_25mhz(cdns_phy);
+		cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, dp->ssc);
+		cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
 	}
-	cdns_dp_phy_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
+	cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
 
 	/* Enable the cmn_pll0_en. */
 	cdns_dp_phy_write_phy(cdns_phy, PHY_PMA_PLL_RAW_CTRL, 0x3);
@@ -1124,7 +1124,7 @@ static int cdns_dp_phy_configure_rate(struct cdns_dp_phy *cdns_phy,
 /*
  * Verify, that parameters to configure PHY with are correct.
  */
-static int cdns_dp_phy_verify_config(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_verify_config(struct cdns_torrent_phy *cdns_phy,
 				     struct phy_configure_opts_dp *dp)
 {
 	u8 i;
@@ -1182,7 +1182,7 @@ static int cdns_dp_phy_verify_config(struct cdns_dp_phy *cdns_phy,
 }
 
 /* Set power state A0 and PLL clock enable to 0 on enabled lanes. */
-static void cdns_dp_phy_set_a0_pll(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy,
 				   u32 num_lanes)
 {
 	u32 pwr_state = cdns_dp_phy_read_dp(cdns_phy, PHY_PMA_XCVR_POWER_STATE_REQ);
@@ -1211,7 +1211,7 @@ static void cdns_dp_phy_set_a0_pll(struct cdns_dp_phy *cdns_phy,
 }
 
 /* Configure lane count as required. */
-static int cdns_dp_phy_set_lanes(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy,
 				 struct phy_configure_opts_dp *dp)
 {
 	u32 value;
@@ -1235,14 +1235,14 @@ static int cdns_dp_phy_set_lanes(struct cdns_dp_phy *cdns_phy,
 	value = (value & 0x0000FFF0) | (0x0000000E & lane_mask);
 	cdns_dp_phy_write_dp(cdns_phy, PHY_RESET, value);
 
-	cdns_dp_phy_set_a0_pll(cdns_phy, dp->lanes);
+	cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes);
 
 	/* release phy_l0*_reset_n based on used laneCount */
 	value = (value & 0x0000FFF0) | (0x0000000F & lane_mask);
 	cdns_dp_phy_write_dp(cdns_phy, PHY_RESET, value);
 
 	/* Wait, until PHY gets ready after releasing PHY reset signal. */
-	ret = cdns_dp_phy_wait_pma_cmn_ready(cdns_phy);
+	ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
 	if (ret)
 		return ret;
 
@@ -1251,37 +1251,37 @@ static int cdns_dp_phy_set_lanes(struct cdns_dp_phy *cdns_phy,
 	/* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
 	cdns_dp_phy_write_dp(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
 
-	ret = cdns_dp_phy_run(cdns_phy);
+	ret = cdns_torrent_dp_run(cdns_phy);
 
 	return ret;
 }
 
 /* Configure link rate as required. */
-static int cdns_dp_phy_set_rate(struct cdns_dp_phy *cdns_phy,
+static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy,
 				struct phy_configure_opts_dp *dp)
 {
 	u32 ret;
 
-	ret = cdns_dp_phy_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A3);
+	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A3);
 	if (ret)
 		return ret;
-	ret = cdns_dp_phy_set_pll_en(cdns_phy, dp, false);
+	ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false);
 	if (ret)
 		return ret;
 	ndelay(200);
 
-	ret = cdns_dp_phy_configure_rate(cdns_phy, dp);
+	ret = cdns_torrent_dp_configure_rate(cdns_phy, dp);
 	if (ret)
 		return ret;
 	ndelay(200);
 
-	ret = cdns_dp_phy_set_pll_en(cdns_phy, dp, true);
+	ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true);
 	if (ret)
 		return ret;
-	ret = cdns_dp_phy_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A2);
+	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A2);
 	if (ret)
 		return ret;
-	ret = cdns_dp_phy_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A0);
+	ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, POWERSTATE_A0);
 	if (ret)
 		return ret;
 	ndelay(900);
@@ -1290,7 +1290,7 @@ static int cdns_dp_phy_set_rate(struct cdns_dp_phy *cdns_phy,
 }
 
 /* Configure voltage swing and pre-emphasis for all enabled lanes. */
-static void cdns_dp_phy_set_voltages(struct cdns_dp_phy *cdns_phy,
+static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy,
 				     struct phy_configure_opts_dp *dp)
 {
 	u8 lane;
@@ -1323,9 +1323,9 @@ static void cdns_dp_phy_set_voltages(struct cdns_dp_phy *cdns_phy,
 	}
 };
 
-static int cdns_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+static int cdns_torrent_dp_configure(struct phy *phy, union phy_configure_opts *opts)
 {
-	struct cdns_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
 	int ret;
 
 	dev_dbg(&phy->dev,
@@ -1342,51 +1342,51 @@ static int cdns_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts
 		(opts->dp.set_voltages && opts->dp.lanes > 3)	? opts->dp.pre[3]	: -1,
 		opts->dp.ssc);
 
-	ret = cdns_dp_phy_verify_config(cdns_phy, &opts->dp);
+	ret = cdns_torrent_dp_verify_config(cdns_phy, &opts->dp);
 	if (ret) {
 		dev_err(&phy->dev, "invalid params for phy configure\n");
 		return ret;
 	}
 
 	if (opts->dp.set_lanes) {
-		ret = cdns_dp_phy_set_lanes(cdns_phy, &opts->dp);
+		ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp);
 		if (ret) {
-			dev_err(&phy->dev, "cdns_dp_phy_set_lanes failed\n");
+			dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n");
 			return ret;
 		}
 	}
 
 	if (opts->dp.set_rate) {
-		ret = cdns_dp_phy_set_rate(cdns_phy, &opts->dp);
+		ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp);
 		if (ret) {
-			dev_err(&phy->dev, "cdns_dp_phy_set_rate failed\n");
+			dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n");
 			return ret;
 		}
 	}
 
 	if (opts->dp.set_voltages)
-		cdns_dp_phy_set_voltages(cdns_phy, &opts->dp);
+		cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp);
 
 	return ret;
 }
 
-static const struct of_device_id cdns_dp_phy_of_match[] = {
+static const struct of_device_id cdns_torrent_phy_of_match[] = {
 	{
-		.compatible = "cdns,dp-phy"
+		.compatible = "cdns,torrent-phy"
 	},
 	{}
 };
-MODULE_DEVICE_TABLE(of, cdns_dp_phy_of_match);
+MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match);
 
-static struct platform_driver cdns_dp_phy_driver = {
-	.probe	= cdns_dp_phy_probe,
+static struct platform_driver cdns_torrent_phy_driver = {
+	.probe	= cdns_torrent_phy_probe,
 	.driver = {
-		.name	= "cdns-dp-phy",
-		.of_match_table	= cdns_dp_phy_of_match,
+		.name	= "cdns-torrent-phy",
+		.of_match_table	= cdns_torrent_phy_of_match,
 	}
 };
-module_platform_driver(cdns_dp_phy_driver);
+module_platform_driver(cdns_torrent_phy_driver);
 
 MODULE_AUTHOR("Cadence Design Systems, Inc.");
-MODULE_DESCRIPTION("Cadence MHDP PHY driver");
+MODULE_DESCRIPTION("Cadence Torrent PHY driver");
 MODULE_LICENSE("GPL v2");

+ 113 - 40
drivers/phy/ti/phy-j721e-wiz.c

@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/reset-controller.h>
+#include <dt-bindings/phy/phy.h>
 
 #define WIZ_SERDES_CTRL		0x404
 #define WIZ_SERDES_TOP_CTRL	0x408
@@ -29,7 +30,8 @@
 
 #define WIZ_MAX_LANES		4
 #define WIZ_MUX_NUM_CLOCKS	3
-#define WIZ_DIV_NUM_CLOCKS	2
+#define WIZ_DIV_NUM_CLOCKS_16G	2
+#define WIZ_DIV_NUM_CLOCKS_10G	1
 
 #define WIZ_SERDES_TYPEC_LN10_SWAP	BIT(30)
 
@@ -57,8 +59,10 @@ static const struct reg_field pll1_refclk_mux_sel =
 					REG_FIELD(WIZ_SERDES_RST, 29, 29);
 static const struct reg_field pll0_refclk_mux_sel =
 					REG_FIELD(WIZ_SERDES_RST, 28, 28);
-static const struct reg_field refclk_dig_sel =
+static const struct reg_field refclk_dig_sel_16g =
 					REG_FIELD(WIZ_SERDES_RST, 24, 25);
+static const struct reg_field refclk_dig_sel_10g =
+					REG_FIELD(WIZ_SERDES_RST, 24, 24);
 static const struct reg_field pma_cmn_refclk_int_mode =
 					REG_FIELD(WIZ_SERDES_TOP_CTRL, 28, 29);
 static const struct reg_field pma_cmn_refclk_mode =
@@ -75,6 +79,8 @@ static const struct reg_field p_enable[WIZ_MAX_LANES] = {
 	REG_FIELD(WIZ_LANECTL(3), 30, 31),
 };
 
+enum p_enable { P_ENABLE = 2, P_ENABLE_FORCE = 1, P_ENABLE_DISABLE = 0 };
+
 static const struct reg_field p_align[WIZ_MAX_LANES] = {
 	REG_FIELD(WIZ_LANECTL(0), 29, 29),
 	REG_FIELD(WIZ_LANECTL(1), 29, 29),
@@ -126,7 +132,7 @@ struct wiz_clk_div_sel {
 	const char		*node_name;
 };
 
-static struct wiz_clk_mux_sel clk_mux_sel[] = {
+static struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
 	{
 		/*
 		 * Mux value to be configured for each of the input clocks
@@ -145,6 +151,25 @@ static struct wiz_clk_mux_sel clk_mux_sel[] = {
 	},
 };
 
+static struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
+	{
+		/*
+		 * Mux value to be configured for each of the input clocks
+		 * in the order populated in device tree
+		 */
+		.table = { 1, 0 },
+		.node_name = "pll0_refclk",
+	},
+	{
+		.table = { 1, 0 },
+		.node_name = "pll1_refclk",
+	},
+	{
+		.table = { 1, 0 },
+		.node_name = "refclk_dig",
+	},
+};
+
 static struct clk_div_table clk_div_table[] = {
 	{ .val = 0, .div = 1, },
 	{ .val = 1, .div = 2, },
@@ -163,10 +188,16 @@ static struct wiz_clk_div_sel clk_div_sel[] = {
 	},
 };
 
+enum wiz_type {
+	J721E_WIZ_16G,
+	J721E_WIZ_10G,
+};
+
 struct wiz {
 	struct regmap		*regmap;
 	struct wiz_clk_mux_sel	*clk_mux_sel;
 	struct wiz_clk_div_sel	*clk_div_sel;
+	unsigned int		clk_div_sel_num;
 	struct regmap_field	*por_en;
 	struct regmap_field	*phy_reset_n;
 	struct regmap_field	*p_enable[WIZ_MAX_LANES];
@@ -185,7 +216,8 @@ struct wiz {
 	struct gpio_desc	*gpio_typec_dir;
 	int			typec_dir_delay;
 
-	bool used_for_dp;
+	enum wiz_type type;
+	u32 lane_modes[WIZ_MAX_LANES];
 };
 
 static int wiz_reset(struct wiz *wiz)
@@ -208,12 +240,17 @@ static int wiz_reset(struct wiz *wiz)
 static int wiz_mode_select(struct wiz *wiz)
 {
 	u32 num_lanes = wiz->num_lanes;
+	enum wiz_lane_standard_mode mode;
 	int ret;
 	int i;
 
 	for (i = 0; i < num_lanes; i++) {
-		ret = regmap_field_write(wiz->p_standard_mode[i],
-					 LANE_MODE_GEN4);
+		if (wiz->lane_modes[i] == PHY_TYPE_DP)
+			mode = LANE_MODE_GEN1;
+		else
+			mode = LANE_MODE_GEN4;
+
+		ret = regmap_field_write(wiz->p_standard_mode[i], mode);
 		if (ret)
 			return ret;
 	}
@@ -263,21 +300,6 @@ static int wiz_init(struct wiz *wiz)
 		return ret;
 	}
 
-	/* INIT HACK to get DP working. Values from Brian */
-	if (wiz->used_for_dp) {
-		regmap_write(wiz->regmap, 0x408, 0x30000000);
-		regmap_write(wiz->regmap, 0x40c, 0x39000000);
-		regmap_write(wiz->regmap, 0x480, 0x70000000);
-		regmap_write(wiz->regmap, 0x4c0, 0x80000000);
-		regmap_write(wiz->regmap, 0x500, 0x80000000);
-		regmap_write(wiz->regmap, 0x540, 0x80000000);
-		regmap_write(wiz->regmap, 0x484, 0x10001);
-		regmap_write(wiz->regmap, 0x4c4, 0x10001);
-		regmap_write(wiz->regmap, 0x504, 0x10001);
-		regmap_write(wiz->regmap, 0x544, 0x10001);
-		regmap_write(wiz->regmap, 0x5FC, 0x00000);
-	}
-
 	return 0;
 }
 
@@ -325,12 +347,14 @@ static int wiz_regfield_init(struct wiz *wiz)
 		return PTR_ERR(clk_div_sel->field);
 	}
 
-	clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK1];
-	clk_div_sel->field = devm_regmap_field_alloc(dev, regmap,
-						     pma_cmn_refclk1_dig_div);
-	if (IS_ERR(clk_div_sel->field)) {
-		dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
-		return PTR_ERR(clk_div_sel->field);
+	if (wiz->type == J721E_WIZ_16G) {
+		clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK1];
+		clk_div_sel->field = devm_regmap_field_alloc(dev, regmap,
+							     pma_cmn_refclk1_dig_div);
+		if (IS_ERR(clk_div_sel->field)) {
+			dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
+			return PTR_ERR(clk_div_sel->field);
+		}
 	}
 
 	clk_mux_sel = &wiz->clk_mux_sel[PLL0_REFCLK];
@@ -350,8 +374,15 @@ static int wiz_regfield_init(struct wiz *wiz)
 	}
 
 	clk_mux_sel = &wiz->clk_mux_sel[REFCLK_DIG];
-	clk_mux_sel->field = devm_regmap_field_alloc(dev, regmap,
-						     refclk_dig_sel);
+	if (wiz->type == J721E_WIZ_10G)
+		clk_mux_sel->field =
+			devm_regmap_field_alloc(dev, regmap,
+						refclk_dig_sel_10g);
+	else
+		clk_mux_sel->field =
+			devm_regmap_field_alloc(dev, regmap,
+						refclk_dig_sel_16g);
+
 	if (IS_ERR(clk_mux_sel->field)) {
 		dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
 		return PTR_ERR(clk_mux_sel->field);
@@ -637,7 +668,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 		of_node_put(clk_node);
 	}
 
-	for (i = 0; i < WIZ_DIV_NUM_CLOCKS; i++) {
+	for (i = 0; i < wiz->clk_div_sel_num; i++) {
 		node_name = clk_div_sel[i].node_name;
 		clk_node = of_get_child_by_name(node, node_name);
 		if (!clk_node) {
@@ -677,7 +708,7 @@ static int wiz_phy_reset_assert(struct reset_controller_dev *rcdev,
 		return ret;
 	}
 
-	ret = regmap_field_write(wiz->p_enable[id - 1], false);
+	ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE);
 	return ret;
 }
 
@@ -708,7 +739,11 @@ static int wiz_phy_reset_deassert(struct reset_controller_dev *rcdev,
 		return ret;
 	}
 
-	ret = regmap_field_write(wiz->p_enable[id - 1], true);
+	if (wiz->lane_modes[id - 1] == PHY_TYPE_DP)
+		ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
+	else
+		ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE);
+
 	return ret;
 }
 
@@ -726,18 +761,40 @@ static struct regmap_config wiz_regmap_config = {
 
 static const struct of_device_id wiz_id_table[] = {
 	{
-		.compatible = "ti,j721e-wiz",
+		.compatible = "ti,j721e-wiz-16g", .data = (void *) J721E_WIZ_16G
+	},
+	{
+		.compatible = "ti,j721e-wiz-10g", .data = (void *) J721E_WIZ_10G
 	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, wiz_id_table);
 
-static void wiz_check_dp_usage(struct wiz *wiz, struct device_node *child_node)
+static int wiz_get_lane_mode(struct device *dev, int lane_number,
+			     u32 *lane_mode)
 {
-	const char *compat;
+	char property_name[11]; /* 11 is length of "lane0-mode\0" */
+	int ret;
+
+	ret = snprintf(property_name, sizeof(property_name), "lane%u-mode",
+		       lane_number);
+
+	if (ret != 10) { /* 10 is length of "lane0-mode" */
+		dev_err(dev, "%s: bad lane number %d (ret = %d)\n",
+			__func__, lane_number, ret);
+		return -ENOTSUPP;
+	}
+
+	ret = of_property_read_u32(dev->of_node, property_name, lane_mode);
+	if (ret == -EINVAL) {
+		*lane_mode = PHY_NONE;
+		return 0;
+	} else if (ret) {
+		dev_err(dev, "Getting \"%s\" property failed: %d\n",
+			property_name, ret);
+	}
 
-	if (of_property_read_string(child_node, "compatible", &compat) == 0)
-		wiz->used_for_dp = !strcmp("cdns,dp-phy", compat);
+	return ret;
 }
 
 static int wiz_probe(struct platform_device *pdev)
@@ -753,11 +810,14 @@ static int wiz_probe(struct platform_device *pdev)
 	struct wiz *wiz;
 	u32 num_lanes;
 	int ret;
+	int i;
 
 	wiz = devm_kzalloc(dev, sizeof(*wiz), GFP_KERNEL);
 	if (!wiz)
 		return -ENOMEM;
 
+	wiz->type = (enum wiz_type) of_device_get_match_data(dev);
+
 	child_node = of_get_child_by_name(node, "serdes");
 	if (!child_node) {
 		dev_err(dev, "Failed to get SERDES child DT node\n");
@@ -810,12 +870,27 @@ static int wiz_probe(struct platform_device *pdev)
 		}
 	}
 
+	for (i = 0; i < num_lanes; i++) {
+		ret = wiz_get_lane_mode(dev, i, &wiz->lane_modes[i]);
+		if (ret)
+			return ret;
+	}
+
 	wiz->dev = dev;
 	wiz->regmap = regmap;
 	wiz->num_lanes = num_lanes;
-	wiz->clk_mux_sel = clk_mux_sel;
+	if (wiz->type == J721E_WIZ_10G)
+		wiz->clk_mux_sel = clk_mux_sel_10g;
+	else
+		wiz->clk_mux_sel = clk_mux_sel_16g;
+
 	wiz->clk_div_sel = clk_div_sel;
 
+	if (wiz->type == J721E_WIZ_10G)
+		wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G;
+	else
+		wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_16G;
+
 	platform_set_drvdata(pdev, wiz);
 
 	ret = wiz_regfield_init(wiz);
@@ -858,8 +933,6 @@ static int wiz_probe(struct platform_device *pdev)
 	}
 	wiz->serdes_pdev = serdes_pdev;
 
-	wiz_check_dp_usage(wiz, child_node);
-
 	ret = wiz_init(wiz);
 	if (ret) {
 		dev_err(dev, "WIZ initialization failed\n");

+ 1 - 0
include/dt-bindings/phy/phy.h

@@ -16,5 +16,6 @@
 #define PHY_TYPE_USB2		3
 #define PHY_TYPE_USB3		4
 #define PHY_TYPE_UFS		5
+#define PHY_TYPE_DP		6
 
 #endif /* _DT_BINDINGS_PHY */

+ 1 - 1
ti_config_fragments/audio_display.cfg

@@ -34,7 +34,7 @@ CONFIG_DRM_CDNS_MHDP=m
 CONFIG_DRM_CDNS_DSI=n
 
 CONFIG_PHY_J721E_WIZ=y
-CONFIG_PHY_CADENCE_DP=y
+CONFIG_PHY_CADENCE_TORRENT=y
 
 # SGX driver needs legacy support
 CONFIG_DRM_LEGACY=y