* [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer
@ 2024-11-12 17:01 Abel Vesa
2024-11-12 17:01 ` [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings Abel Vesa
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The Parade PS8830 is a Type-C multi-protocol retimer that is controlled
via I2C. It provides altmode and orientation handling and usually sits
between the Type-C port and the PHY.
It is currently used alongside Qualcomm Snapdragon X Elite SoCs on quite
a few laptops already.
This new driver adds support for the following 3 modes:
- DP 4lanes (pin assignments C and E)
- DP 2lanes + USB3 (pin assignment D)
- USB3
This retimer is a LTTPR (Link-Training Tunable PHY Repeater) which means
it can support link training from source to itself. This means that the
DP driver needs to be aware of the repeater presence and to handle
the link training accordingly. This is currently missing from msm dp
driver, but there is already a patchset [1] on the list that adds it.
Once done, full external DP will be working on all X1E laptops that make
use of this retimer.
NOTE: Currently, due to both LTTPR missing support in msm DP and a
reported crash that can happen on DP unplug, the DP DT patches are not
supposed to be merged yet. That patch is only shared for testing purposes.
Once those 2 issues have been resolved, the MDSS DP 0-2 enablement patch
will be respun.
The LTTPR patchset is already on the list:
[1] https://lore.kernel.org/all/20241031-drm-dp-msm-add-lttpr-transparent-mode-set-v1-0-cafbb9855f40@linaro.org/
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
Changes in v5:
- Renamed binding schema to be the same as the compatible.
- Dropped the ps8830,boot-on from the schema.
- Added register offsets and bits names to the driver, like Konrad
suggested.
- Reordered the vregs and clocks enabling, as per Johan's request.
- Used the dev_err_probe for regmap init failure and dropped the
multiple regulator disable calls, replacing it with single call to
helper, as Christophe suggested. Also replaced dev_err with
dev_err_probe on typec_switch_register and typec_mux_register failure.
- Added some new pinctrl specific properties to all pmic provided
gpios that control retimer vregs.
- Re-ordered alphabetically the retimers default state pinconfs.
- Added the T14s patches with same exact support, as per Johan's
request.
- Link to v4: https://lore.kernel.org/r/20241101-x1e80100-ps8830-v4-0-f0f7518b263e@linaro.org
Changes in v4:
- Renamed the driver and bindings schema to ps883x to allow future
support for the PS8833.
- Dropped the dedicated DT property for keeping the retimers from
resetting on probe, and replaced that with a read to figure out
if it has been already configured or not. This involves leaving the
reset gpio as-is on probe if the retimer has been already configured.
- Replaced the fwnode_typec_switch_get() call with typec_switch_get()
- Replaced the fwnode_typec_mux_get() call with typec_mux_get()
- Dropped the clock name, as there is only one clock. As per Bjorn's
suggestion.
- Dropped regcache as it seems it is not needed.
- Re-worded all commit messages to explain better the problem and the
proposed changes.
- Link to v3: https://lore.kernel.org/r/20241022-x1e80100-ps8830-v3-0-68a95f351e99@linaro.org
Changes in v3:
- Reworked the schema binding by using the usb/usb-switch.yaml defined
port graph and properties. Addressed all comments from Johan and
Dmitry.
- Dropped the manual caching of the config values on regmap write in the
driver.
- Reordered the DP pin assignment states within the switch clause, as
Dmitry suggested.
- Added SVID check to not allow any altmode other than DP.
- Added DT patches (retimer for USB orientation handling and DP
enablement). Did this in order to offer a full picture of how it all
fits together.
- Split the DP enablement in DT in a separate patchset so the USB
handling can be merged separately.
- Added ps8830,boot-on to let the driver know it is supposed to skip
resetting the retimer on driver probe, as the bootloader might already
let it in a pre-configured state.
- Marked all retimer voltage regulators as boot-on since we want to
maintain the state for coldplug orientation.
- Added pinconf for all retimer0 gpios.
- Didn't pick up Konrad's T-b tags and Krzysztof's R-b tag as the rework
is quite extensive. Especially because of the ps8830,boot-on and what
it does.
- Link to v2: https://lore.kernel.org/r/20241004-x1e80100-ps8830-v2-0-5cd8008c8c40@linaro.org
Changes in v2:
- Addressed all comments from Johan and Konrad.
- Reworked the handling of the vregs so it would be more cleaner.
Dropped the usage of bulk regulators API and handled them separately.
Also discribed all regulators according to data sheet.
- Added all delays according to data sheet.
- Fixed coldplug (on boot) orientation detection.
- Didn't pick Krzysztof's R-b tag because the bindings changed w.r.t
supplies.
- Link to v1: https://lore.kernel.org/r/20240829-x1e80100-ps8830-v1-0-bcc4790b1d45@linaro.org
---
Abel Vesa (6):
dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings
usb: typec: Add support for Parade PS8830 Type-C Retimer
arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers
arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers
arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support
.../devicetree/bindings/usb/parade,ps8830.yaml | 119 ++++++
.../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 321 +++++++++++++-
arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 474 ++++++++++++++++++++-
drivers/usb/typec/mux/Kconfig | 10 +
drivers/usb/typec/mux/Makefile | 1 +
drivers/usb/typec/mux/ps883x.c | 437 +++++++++++++++++++
6 files changed, 1352 insertions(+), 10 deletions(-)
---
base-commit: 28955f4fa2823e39f1ecfb3a37a364563527afbc
change-id: 20240521-x1e80100-ps8830-d5ccca95b557
Best regards,
--
Abel Vesa <abel.vesa@linaro.org>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-11-15 16:44 ` Rob Herring
2024-11-12 17:01 ` [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer Abel Vesa
` (5 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
controlled over I2C. It usually sits between a USB/DisplayPort PHY and the
Type-C connector, and provides orientation and altmode handling.
Currently, it is found on all boards featuring the Qualcomm Snapdragon
X Elite SoCs.
Document bindings for its new driver. Future-proof the schema for the
PS8833 variant, which seems to be similar to PS8830.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
.../devicetree/bindings/usb/parade,ps8830.yaml | 119 +++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/parade,ps8830.yaml b/Documentation/devicetree/bindings/usb/parade,ps8830.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2f20d20a2bdfe2499588dc621c14cd16ab159002
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/parade,ps8830.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/parade,ps8830.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Parade PS883x USB and DisplayPort Retimer
+
+maintainers:
+ - Abel Vesa <abel.vesa@linaro.org>
+
+properties:
+ compatible:
+ enum:
+ - parade,ps8830
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: XO Clock
+
+ reset-gpios:
+ maxItems: 1
+
+ vdd-supply:
+ description: power supply (1.07V)
+
+ vdd33-supply:
+ description: power supply (3.3V)
+
+ vdd33-cap-supply:
+ description: power supply (3.3V)
+
+ vddar-supply:
+ description: power supply (1.07V)
+
+ vddat-supply:
+ description: power supply (1.07V)
+
+ vddio-supply:
+ description: power supply (1.2V or 1.8V)
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - reset-gpios
+ - vdd-supply
+ - vdd33-supply
+ - vdd33-cap-supply
+ - vddat-supply
+ - vddio-supply
+ - orientation-switch
+ - retimer-switch
+
+allOf:
+ - $ref: usb-switch.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x8>;
+
+ clocks = <&clk_rtmr_xo>;
+
+ vdd-supply = <&vreg_rtmr_1p15>;
+ vdd33-supply = <&vreg_rtmr_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr_3p3>;
+ vddar-supply = <&vreg_rtmr_1p15>;
+ vddat-supply = <&vreg_rtmr_1p15>;
+ vddio-supply = <&vreg_rtmr_1p8>;
+
+ reset-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>;
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&typec_con_ss>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ remote-endpoint = <&usb_phy_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ endpoint {
+ remote-endpoint = <&typec_dp_aux>;
+ };
+ };
+ };
+ };
+ };
+...
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
2024-11-12 17:01 ` [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-12-04 16:24 ` Johan Hovold
2024-11-12 17:01 ` [PATCH v5 3/6] arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers Abel Vesa
` (4 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
controlled over I2C. It usually sits between a USB/DisplayPort PHY
and the Type-C connector, and provides orientation and altmode handling.
The boards that use this retimer are the ones featuring the Qualcomm
Snapdragon X Elite SoCs.
Add a driver with support for the following modes:
- DisplayPort 4-lanes
- DisplayPort 2-lanes + USB3
- USB3
There is another variant of this retimer which is called PS8833. It seems
to be really similar to the PS8830, so future-proof this driver by
naming it ps883x.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/usb/typec/mux/Kconfig | 10 +
drivers/usb/typec/mux/Makefile | 1 +
drivers/usb/typec/mux/ps883x.c | 437 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 448 insertions(+)
diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 67381b4ef4f68f4a6e73f157365ee24d0ab7109a..6dd8f961b593261fde1d39b238b981966e463599 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -56,6 +56,16 @@ config TYPEC_MUX_NB7VPQ904M
Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
redriver chip found on some devices with a Type-C port.
+config TYPEC_MUX_PS883X
+ tristate "Parade PS883x Type-C retimer driver"
+ depends on I2C
+ depends on DRM || DRM=n
+ select DRM_AUX_BRIDGE if DRM_BRIDGE && OF
+ select REGMAP_I2C
+ help
+ Say Y or M if your system has a Parade PS883x Type-C retimer chip
+ found on some devices with a Type-C port.
+
config TYPEC_MUX_PTN36502
tristate "NXP PTN36502 Type-C redriver driver"
depends on I2C
diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
index 60879446da9365183567d3374a2fb7b5171fb3d7..b4f599eb5053b8f20e9a41409b0a2d9a03d850b6 100644
--- a/drivers/usb/typec/mux/Makefile
+++ b/drivers/usb/typec/mux/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_TYPEC_MUX_PI3USB30532) += pi3usb30532.o
obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) += intel_pmc_mux.o
obj-$(CONFIG_TYPEC_MUX_IT5205) += it5205.o
obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o
+obj-$(CONFIG_TYPEC_MUX_PS883X) += ps883x.o
obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o
obj-$(CONFIG_TYPEC_MUX_TUSB1046) += tusb1046.o
obj-$(CONFIG_TYPEC_MUX_WCD939X_USBSS) += wcd939x-usbss.o
diff --git a/drivers/usb/typec/mux/ps883x.c b/drivers/usb/typec/mux/ps883x.c
new file mode 100644
index 0000000000000000000000000000000000000000..3650e5d124727d9b9833302092331bf7f6f7b003
--- /dev/null
+++ b/drivers/usb/typec/mux/ps883x.c
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Parade ps883x usb retimer driver
+ *
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <drm/bridge/aux-bridge.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_retimer.h>
+
+#define REG_USB_PORT_CONN_STATUS_0 0x00
+
+#define CONN_STATUS_0_CONNECTION_PRESENT BIT(0)
+#define CONN_STATUS_0_ORIENTATION_REVERSED BIT(1)
+#define CONN_STATUS_0_USB_3_1_CONNECTED BIT(5)
+
+#define REG_USB_PORT_CONN_STATUS_1 0x01
+
+#define CONN_STATUS_1_DP_CONNECTED BIT(0)
+#define CONN_STATUS_1_DP_SINK_REQUESTED BIT(1)
+#define CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D BIT(2)
+#define CONN_STATUS_1_DP_HPD_LEVEL BIT(7)
+
+#define REG_USB_PORT_CONN_STATUS_2 0x02
+
+struct ps883x_retimer {
+ struct i2c_client *client;
+ struct gpio_desc *reset_gpio;
+ struct regmap *regmap;
+ struct typec_switch_dev *sw;
+ struct typec_retimer *retimer;
+ struct clk *xo_clk;
+ struct regulator *vdd_supply;
+ struct regulator *vdd33_supply;
+ struct regulator *vdd33_cap_supply;
+ struct regulator *vddat_supply;
+ struct regulator *vddar_supply;
+ struct regulator *vddio_supply;
+
+ struct typec_switch *typec_switch;
+ struct typec_mux *typec_mux;
+
+ struct mutex lock; /* protect non-concurrent retimer & switch */
+
+ enum typec_orientation orientation;
+ unsigned long mode;
+ unsigned int svid;
+};
+
+static void ps883x_configure(struct ps883x_retimer *retimer, int cfg0,
+ int cfg1, int cfg2)
+{
+ regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_0, cfg0);
+ regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_1, cfg1);
+ regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_2, cfg2);
+}
+
+static int ps883x_set(struct ps883x_retimer *retimer)
+{
+ int cfg0 = CONN_STATUS_0_CONNECTION_PRESENT;
+ int cfg1 = 0x00;
+ int cfg2 = 0x00;
+
+ if (retimer->orientation == TYPEC_ORIENTATION_NONE ||
+ retimer->mode == TYPEC_STATE_SAFE) {
+ ps883x_configure(retimer, cfg0, cfg1, cfg2);
+ return 0;
+ }
+
+ if (retimer->mode != TYPEC_STATE_USB && retimer->svid != USB_TYPEC_DP_SID)
+ return -EINVAL;
+
+ if (retimer->orientation == TYPEC_ORIENTATION_REVERSE)
+ cfg0 |= CONN_STATUS_0_ORIENTATION_REVERSED;
+
+ switch (retimer->mode) {
+ case TYPEC_STATE_USB:
+ cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED;
+ break;
+
+ case TYPEC_DP_STATE_C:
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_SINK_REQUESTED |
+ CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ case TYPEC_DP_STATE_D:
+ cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED;
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_SINK_REQUESTED |
+ CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ case TYPEC_DP_STATE_E:
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ ps883x_configure(retimer, cfg0, cfg1, cfg2);
+
+ return 0;
+}
+
+static int ps883x_sw_set(struct typec_switch_dev *sw,
+ enum typec_orientation orientation)
+{
+ struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
+ int ret = 0;
+
+ ret = typec_switch_set(retimer->typec_switch, orientation);
+ if (ret)
+ return ret;
+
+ mutex_lock(&retimer->lock);
+
+ if (retimer->orientation != orientation) {
+ retimer->orientation = orientation;
+
+ ret = ps883x_set(retimer);
+ }
+
+ mutex_unlock(&retimer->lock);
+
+ return ret;
+}
+
+static int ps883x_retimer_set(struct typec_retimer *rtmr,
+ struct typec_retimer_state *state)
+{
+ struct ps883x_retimer *retimer = typec_retimer_get_drvdata(rtmr);
+ struct typec_mux_state mux_state;
+ int ret = 0;
+
+ mutex_lock(&retimer->lock);
+
+ if (state->mode != retimer->mode) {
+ retimer->mode = state->mode;
+
+ if (state->alt)
+ retimer->svid = state->alt->svid;
+ else
+ retimer->svid = 0; // No SVID
+
+ ret = ps883x_set(retimer);
+ }
+
+ mutex_unlock(&retimer->lock);
+
+ if (ret)
+ return ret;
+
+ mux_state.alt = state->alt;
+ mux_state.data = state->data;
+ mux_state.mode = state->mode;
+
+ return typec_mux_set(retimer->typec_mux, &mux_state);
+}
+
+static int ps883x_enable_vregs(struct ps883x_retimer *retimer)
+{
+ struct device *dev = &retimer->client->dev;
+ int ret;
+
+ ret = regulator_enable(retimer->vdd33_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD 3.3V regulator: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_enable(retimer->vdd33_cap_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD 3.3V CAP regulator: %d\n", ret);
+ goto err_vdd33_disable;
+ }
+
+ usleep_range(4000, 10000);
+
+ ret = regulator_enable(retimer->vdd_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD regulator: %d\n", ret);
+ goto err_vdd33_cap_disable;
+ }
+
+ ret = regulator_enable(retimer->vddar_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD AR regulator: %d\n", ret);
+ goto err_vdd_disable;
+ }
+
+ ret = regulator_enable(retimer->vddat_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD AT regulator: %d\n", ret);
+ goto err_vddar_disable;
+ }
+
+ ret = regulator_enable(retimer->vddio_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD IO regulator: %d\n", ret);
+ goto err_vddat_disable;
+ }
+
+ return 0;
+
+err_vddat_disable:
+ regulator_disable(retimer->vddat_supply);
+err_vddar_disable:
+ regulator_disable(retimer->vddar_supply);
+err_vdd_disable:
+ regulator_disable(retimer->vdd_supply);
+err_vdd33_cap_disable:
+ regulator_disable(retimer->vdd33_cap_supply);
+err_vdd33_disable:
+ regulator_disable(retimer->vdd33_supply);
+
+ return ret;
+}
+
+static void ps883x_disable_vregs(struct ps883x_retimer *retimer)
+{
+ regulator_disable(retimer->vddio_supply);
+ regulator_disable(retimer->vddat_supply);
+ regulator_disable(retimer->vddar_supply);
+ regulator_disable(retimer->vdd_supply);
+ regulator_disable(retimer->vdd33_cap_supply);
+ regulator_disable(retimer->vdd33_supply);
+}
+
+static int ps883x_get_vregs(struct ps883x_retimer *retimer)
+{
+ struct device *dev = &retimer->client->dev;
+
+ retimer->vdd_supply = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(retimer->vdd_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd_supply),
+ "failed to get VDD\n");
+
+ retimer->vdd33_supply = devm_regulator_get(dev, "vdd33");
+ if (IS_ERR(retimer->vdd33_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd33_supply),
+ "failed to get VDD 3.3V\n");
+
+ retimer->vdd33_cap_supply = devm_regulator_get(dev, "vdd33-cap");
+ if (IS_ERR(retimer->vdd33_cap_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd33_cap_supply),
+ "failed to get VDD CAP 3.3V\n");
+
+ retimer->vddat_supply = devm_regulator_get(dev, "vddat");
+ if (IS_ERR(retimer->vddat_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddat_supply),
+ "failed to get VDD AT\n");
+
+ retimer->vddar_supply = devm_regulator_get(dev, "vddar");
+ if (IS_ERR(retimer->vddar_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddar_supply),
+ "failed to get VDD AR\n");
+
+ retimer->vddio_supply = devm_regulator_get(dev, "vddio");
+ if (IS_ERR(retimer->vddio_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddio_supply),
+ "failed to get VDD IO\n");
+
+ return 0;
+}
+
+static const struct regmap_config ps883x_retimer_regmap = {
+ .max_register = 0x1f,
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int ps883x_retimer_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct typec_switch_desc sw_desc = { };
+ struct typec_retimer_desc rtmr_desc = { };
+ struct ps883x_retimer *retimer;
+ int ret;
+
+ retimer = devm_kzalloc(dev, sizeof(*retimer), GFP_KERNEL);
+ if (!retimer)
+ return -ENOMEM;
+
+ retimer->client = client;
+
+ mutex_init(&retimer->lock);
+
+ retimer->regmap = devm_regmap_init_i2c(client, &ps883x_retimer_regmap);
+ if (IS_ERR(retimer->regmap))
+ return dev_err_probe(dev, PTR_ERR(retimer->regmap),
+ "failed to allocate register map\n");
+
+ ret = ps883x_get_vregs(retimer);
+ if (ret)
+ return ret;
+
+ retimer->xo_clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(retimer->xo_clk))
+ return dev_err_probe(dev, PTR_ERR(retimer->xo_clk),
+ "failed to get xo clock\n");
+
+ retimer->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+ if (IS_ERR(retimer->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(retimer->reset_gpio),
+ "failed to get reset gpio\n");
+
+ retimer->typec_switch = typec_switch_get(dev);
+ if (IS_ERR(retimer->typec_switch))
+ return dev_err_probe(dev, PTR_ERR(retimer->typec_switch),
+ "failed to acquire orientation-switch\n");
+
+ retimer->typec_mux = typec_mux_get(dev);
+ if (IS_ERR(retimer->typec_mux)) {
+ ret = dev_err_probe(dev, PTR_ERR(retimer->typec_mux),
+ "failed to acquire mode-mux\n");
+ goto err_switch_put;
+ }
+
+ ret = drm_aux_bridge_register(dev);
+ if (ret)
+ goto err_mux_put;
+
+ ret = ps883x_enable_vregs(retimer);
+ if (ret)
+ goto err_mux_put;
+
+ ret = clk_prepare_enable(retimer->xo_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable XO: %d\n", ret);
+ goto err_vregs_disable;
+ }
+
+ sw_desc.drvdata = retimer;
+ sw_desc.fwnode = dev_fwnode(dev);
+ sw_desc.set = ps883x_sw_set;
+
+ retimer->sw = typec_switch_register(dev, &sw_desc);
+ if (IS_ERR(retimer->sw)) {
+ ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
+ "failed to register typec switch\n");
+ goto err_clk_disable;
+ }
+
+ rtmr_desc.drvdata = retimer;
+ rtmr_desc.fwnode = dev_fwnode(dev);
+ rtmr_desc.set = ps883x_retimer_set;
+
+ retimer->retimer = typec_retimer_register(dev, &rtmr_desc);
+ if (IS_ERR(retimer->retimer)) {
+ ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
+ "failed to register typec retimer\n");
+ goto err_switch_unregister;
+ }
+
+ /* skip resetting if already configured */
+ if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
+ CONN_STATUS_0_CONNECTION_PRESENT))
+ return 0;
+
+ gpiod_direction_output(retimer->reset_gpio, 1);
+
+ /* VDD IO supply enable to reset release delay */
+ usleep_range(4000, 14000);
+
+ gpiod_set_value(retimer->reset_gpio, 0);
+
+ /* firmware initialization delay */
+ msleep(60);
+
+ return 0;
+
+err_switch_unregister:
+ typec_switch_unregister(retimer->sw);
+err_vregs_disable:
+ ps883x_disable_vregs(retimer);
+err_clk_disable:
+ clk_disable_unprepare(retimer->xo_clk);
+err_mux_put:
+ typec_mux_put(retimer->typec_mux);
+err_switch_put:
+ typec_switch_put(retimer->typec_switch);
+
+ return ret;
+}
+
+static void ps883x_retimer_remove(struct i2c_client *client)
+{
+ struct ps883x_retimer *retimer = i2c_get_clientdata(client);
+
+ typec_retimer_unregister(retimer->retimer);
+ typec_switch_unregister(retimer->sw);
+
+ gpiod_set_value(retimer->reset_gpio, 1);
+
+ clk_disable_unprepare(retimer->xo_clk);
+
+ ps883x_disable_vregs(retimer);
+
+ typec_mux_put(retimer->typec_mux);
+ typec_switch_put(retimer->typec_switch);
+}
+
+static const struct of_device_id ps883x_retimer_of_table[] = {
+ { .compatible = "parade,ps8830" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ps883x_retimer_of_table);
+
+static struct i2c_driver ps883x_retimer_driver = {
+ .driver = {
+ .name = "ps883x_retimer",
+ .of_match_table = ps883x_retimer_of_table,
+ },
+ .probe = ps883x_retimer_probe,
+ .remove = ps883x_retimer_remove,
+};
+
+module_i2c_driver(ps883x_retimer_driver);
+
+MODULE_DESCRIPTION("Parade ps883x Type-C Retimer driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 3/6] arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
2024-11-12 17:01 ` [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings Abel Vesa
2024-11-12 17:01 ` [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-11-12 17:01 ` [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support Abel Vesa
` (3 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The X Elite CRD board comes with 3 Parade PS8830 retimers, one for each
Type-C port. These handle the orientation and altmode switching and are
controlled over I2C. In the connection chain, they sit between the
USB/DisplayPort combo PHY and the Type-C connector.
Describe the retimers and all gpio controlled voltage regulators used by
each retimer. Also, modify the pmic glink graph to include the retimers in
between the SuperSpeed/Sideband in endpoints and the QMP PHY out endpoints.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 450 +++++++++++++++++++++++++++++-
1 file changed, 444 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
index 39f9d9cdc10d8e79824b72288e2529536144fa9e..659520404adec33c3551f8d0a5ae3db9e0a18d44 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -100,7 +100,15 @@ port@1 {
reg = <1>;
pmic_glink_ss0_ss_in: endpoint {
- remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ remote-endpoint = <&retimer_ss0_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss0_con_sbu_in: endpoint {
+ remote-endpoint = <&retimer_ss0_con_sbu_out>;
};
};
};
@@ -129,7 +137,15 @@ port@1 {
reg = <1>;
pmic_glink_ss1_ss_in: endpoint {
- remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ remote-endpoint = <&retimer_ss1_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss1_con_sbu_in: endpoint {
+ remote-endpoint = <&retimer_ss1_con_sbu_out>;
};
};
};
@@ -158,7 +174,15 @@ port@1 {
reg = <1>;
pmic_glink_ss2_ss_in: endpoint {
- remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+ remote-endpoint = <&retimer_ss2_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss2_con_sbu_in: endpoint {
+ remote-endpoint = <&retimer_ss2_con_sbu_out>;
};
};
};
@@ -311,6 +335,150 @@ vreg_nvme: regulator-nvme {
regulator-boot-on;
};
+ vreg_rtmr0_1p15: regulator-rtmr0-1p15 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_1P15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+
+ gpio = <&pmc8380_5_gpios 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_pwr_1p15_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr0_1p8: regulator-rtmr0-1p8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&pm8550ve_9_gpios 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_1p8_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr0_3p3: regulator-rtmr0-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_3p3_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_1p15: regulator-rtmr1-1p15 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_1P15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+
+ gpio = <&tlmm 188 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_1p15_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_1p8: regulator-rtmr1-1p8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 175 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_1p8_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_3p3: regulator-rtmr1-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 186 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_3p3_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr2_1p15: regulator-rtmr2-1p15 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR2_1P15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+
+ gpio = <&tlmm 189 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb2_pwr_1p15_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr2_1p8: regulator-rtmr2-1p8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR2_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 126 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb2_pwr_1p8_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr2_3p3: regulator-rtmr2-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR2_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 187 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb2_pwr_3p3_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
vph_pwr: regulator-vph-pwr {
compatible = "regulator-fixed";
@@ -735,6 +903,178 @@ keyboard@3a {
};
};
+&i2c1 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x08>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK5>;
+
+ vdd-supply = <&vreg_rtmr2_1p15>;
+ vdd33-supply = <&vreg_rtmr2_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr2_3p3>;
+ vddar-supply = <&vreg_rtmr2_1p15>;
+ vddat-supply = <&vreg_rtmr2_1p15>;
+ vddio-supply = <&vreg_rtmr2_1p8>;
+
+ reset-gpios = <&tlmm 185 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&rtmr2_default>;
+ pinctrl-names = "default";
+
+ orientation-switch;
+ retimer-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ retimer_ss2_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss2_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ retimer_ss2_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ retimer_ss2_con_sbu_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss2_con_sbu_in>;
+ };
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x08>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK3>;
+
+ vdd-supply = <&vreg_rtmr0_1p15>;
+ vdd33-supply = <&vreg_rtmr0_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr0_3p3>;
+ vddar-supply = <&vreg_rtmr0_1p15>;
+ vddat-supply = <&vreg_rtmr0_1p15>;
+ vddio-supply = <&vreg_rtmr0_1p8>;
+
+ reset-gpios = <&pm8550_gpios 10 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&rtmr0_default>;
+ pinctrl-names = "default";
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ retimer_ss0_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ retimer_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ retimer_ss0_con_sbu_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss0_con_sbu_in>;
+ };
+ };
+ };
+ };
+};
+
+&i2c7 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x8>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK4>;
+
+ vdd-supply = <&vreg_rtmr1_1p15>;
+ vdd33-supply = <&vreg_rtmr1_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr1_3p3>;
+ vddar-supply = <&vreg_rtmr1_1p15>;
+ vddat-supply = <&vreg_rtmr1_1p15>;
+ vddio-supply = <&vreg_rtmr1_1p8>;
+
+ reset-gpios = <&tlmm 176 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&rtmr1_default>;
+ pinctrl-names = "default";
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ retimer_ss1_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ retimer_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ retimer_ss1_con_sbu_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss1_con_sbu_in>;
+ };
+ };
+
+ };
+ };
+};
+
&i2c8 {
clock-frequency = <400000>;
@@ -883,6 +1223,26 @@ &pcie6a_phy {
status = "okay";
};
+&pm8550_gpios {
+ rtmr0_default: rtmr0-reset-n-active-state {
+ pins = "gpio10";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+
+ usb0_3p3_reg_en: usb0-3p3-reg-en-state {
+ pins = "gpio11";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
&pm8550ve_8_gpios {
misc_3p3_reg_en: misc-3p3-reg-en-state {
pins = "gpio6";
@@ -896,6 +1256,17 @@ misc_3p3_reg_en: misc-3p3-reg-en-state {
};
};
+&pm8550ve_9_gpios {
+ usb0_1p8_reg_en: usb0-1p8-reg-en-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
&pmc8380_3_gpios {
edp_bl_en: edp-bl-en-state {
pins = "gpio4";
@@ -906,6 +1277,17 @@ edp_bl_en: edp-bl-en-state {
};
};
+&pmc8380_5_gpios {
+ usb0_pwr_1p15_reg_en: usb0-pwr-1p15-reg-en-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
&qupv3_0 {
status = "okay";
};
@@ -1135,6 +1517,20 @@ wake-n-pins {
};
};
+ rtmr1_default: rtmr1-reset-n-active-state {
+ pins = "gpio176";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ rtmr2_default: rtmr2-reset-n-active-state {
+ pins = "gpio185";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
tpad_default: tpad-default-state {
pins = "gpio3";
function = "gpio";
@@ -1156,6 +1552,48 @@ reset-n-pins {
};
};
+ usb1_pwr_1p15_reg_en: usb1-pwr-1p15-reg-en-state {
+ pins = "gpio188";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb1_pwr_1p8_reg_en: usb1-pwr-1p8-reg-en-state {
+ pins = "gpio175";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb1_pwr_3p3_reg_en: usb1-pwr-3p3-reg-en-state {
+ pins = "gpio186";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb2_pwr_1p15_reg_en: usb2-pwr-1p15-reg-en-state {
+ pins = "gpio189";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb2_pwr_1p8_reg_en: usb2-pwr-1p8-reg-en-state {
+ pins = "gpio126";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb2_pwr_3p3_reg_en: usb2-pwr-3p3-reg-en-state {
+ pins = "gpio187";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
wcd_default: wcd-reset-n-active-state {
pins = "gpio191";
function = "gpio";
@@ -1202,7 +1640,7 @@ &usb_1_ss0_dwc3_hs {
};
&usb_1_ss0_qmpphy_out {
- remote-endpoint = <&pmic_glink_ss0_ss_in>;
+ remote-endpoint = <&retimer_ss0_ss_in>;
};
&usb_1_ss1_hsphy {
@@ -1230,7 +1668,7 @@ &usb_1_ss1_dwc3_hs {
};
&usb_1_ss1_qmpphy_out {
- remote-endpoint = <&pmic_glink_ss1_ss_in>;
+ remote-endpoint = <&retimer_ss1_ss_in>;
};
&usb_1_ss2_hsphy {
@@ -1258,5 +1696,5 @@ &usb_1_ss2_dwc3_hs {
};
&usb_1_ss2_qmpphy_out {
- remote-endpoint = <&pmic_glink_ss2_ss_in>;
+ remote-endpoint = <&retimer_ss2_ss_in>;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
` (2 preceding siblings ...)
2024-11-12 17:01 ` [PATCH v5 3/6] arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-11-12 17:05 ` Abel Vesa
2024-11-12 17:01 ` [PATCH v5 5/6] arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers Abel Vesa
` (2 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The X Elite CRD provides external DisplayPort on all 3 USB Type-C ports.
Each one of this ports is connected to a dedicated DisplayPort
controller.
Due to support missing in the USB/DisplayPort combo PHY driver,
the external DisplayPort is limited to 2 lanes.
So enable all 3 remaining DisplayPort controllers and limit their data
lanes number to 2.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
index 659520404adec33c3551f8d0a5ae3db9e0a18d44..6dc2ebbf6d27fbbf0f224e58cd39ffd33792c6a1 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -1125,6 +1125,30 @@ &mdss {
status = "okay";
};
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+};
+
+&mdss_dp1 {
+ status = "okay";
+};
+
+&mdss_dp1_out {
+ data-lanes = <0 1>;
+};
+
+&mdss_dp2 {
+ status = "okay";
+};
+
+&mdss_dp2_out {
+ data-lanes = <0 1>;
+};
+
&mdss_dp3 {
compatible = "qcom,x1e80100-dp";
/delete-property/ #sound-dai-cells;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 5/6] arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
` (3 preceding siblings ...)
2024-11-12 17:01 ` [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-11-12 17:01 ` [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support Abel Vesa
2024-11-15 15:13 ` [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Rob Herring (Arm)
6 siblings, 0 replies; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The Lenovo ThinkPad T14s Gen6 laptop comes with 3 Parade PS8830 retimers,
one for each Type-C port. These handle the orientation and altmode
switching and are controlled over I2C. In the connection chain, they sit
between the USB/DisplayPort combo PHY and the Type-C connector.
Describe the retimers and all gpio controlled voltage regulators used by
each retimer. Also, modify the pmic glink graph to include the retimers in
between the SuperSpeed/Sideband in endpoints and the QMP PHY out
endpoints.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
.../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 305 ++++++++++++++++++++-
1 file changed, 301 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
index 975550139e1024420ed335a2a46e4d54df7ee423..ea3ecc7c5bda24f3a0a7bb027b456462b11daf4d 100644
--- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
+++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
@@ -66,7 +66,15 @@ port@1 {
reg = <1>;
pmic_glink_ss0_ss_in: endpoint {
- remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ remote-endpoint = <&retimer_ss0_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss0_con_sbu_in: endpoint {
+ remote-endpoint = <&retimer_ss0_con_sbu_out>;
};
};
};
@@ -95,7 +103,15 @@ port@1 {
reg = <1>;
pmic_glink_ss1_ss_in: endpoint {
- remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ remote-endpoint = <&retimer_ss1_ss_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss1_con_sbu_in: endpoint {
+ remote-endpoint = <&retimer_ss1_con_sbu_out>;
};
};
};
@@ -143,6 +159,102 @@ vreg_nvme: regulator-nvme {
regulator-boot-on;
};
+ vreg_rtmr0_1p15: regulator-rtmr0-1p15 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_1P15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+
+ gpio = <&pmc8380_5_gpios 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_pwr_1p15_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr0_1p8: regulator-rtmr0-1p8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&pm8550ve_9_gpios 8 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_1p8_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr0_3p3: regulator-rtmr0-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR0_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pm8550_gpios 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb0_3p3_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_1p15: regulator-rtmr1-1p15 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_1P15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+
+ gpio = <&tlmm 188 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_1p15_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_1p8: regulator-rtmr1-1p8 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_1P8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 175 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_1p8_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vreg_rtmr1_3p3: regulator-rtmr1-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_RTMR1_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 186 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&usb1_pwr_3p3_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
vph_pwr: regulator-vph-pwr {
compatible = "regulator-fixed";
@@ -495,6 +607,121 @@ keyboard@3a {
};
};
+&i2c3 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x08>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK3>;
+
+ vdd-supply = <&vreg_rtmr0_1p15>;
+ vdd33-supply = <&vreg_rtmr0_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr0_3p3>;
+ vddar-supply = <&vreg_rtmr0_1p15>;
+ vddat-supply = <&vreg_rtmr0_1p15>;
+ vddio-supply = <&vreg_rtmr0_1p8>;
+
+ reset-gpios = <&pm8550_gpios 10 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&rtmr0_default>;
+ pinctrl-names = "default";
+
+ orientation-switch;
+ retimer-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ retimer_ss0_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ retimer_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ retimer_ss0_con_sbu_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss0_con_sbu_in>;
+ };
+ };
+ };
+ };
+};
+
+&i2c7 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ typec-mux@8 {
+ compatible = "parade,ps8830";
+ reg = <0x8>;
+
+ clocks = <&rpmhcc RPMH_RF_CLK4>;
+
+ vdd-supply = <&vreg_rtmr1_1p15>;
+ vdd33-supply = <&vreg_rtmr1_3p3>;
+ vdd33-cap-supply = <&vreg_rtmr1_3p3>;
+ vddar-supply = <&vreg_rtmr1_1p15>;
+ vddat-supply = <&vreg_rtmr1_1p15>;
+ vddio-supply = <&vreg_rtmr1_1p8>;
+
+ reset-gpios = <&tlmm 176 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&rtmr1_default>;
+ pinctrl-names = "default";
+
+ retimer-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ retimer_ss1_ss_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ retimer_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ retimer_ss1_con_sbu_out: endpoint {
+ remote-endpoint = <&pmic_glink_ss1_con_sbu_in>;
+ };
+ };
+
+ };
+ };
+};
+
&i2c8 {
clock-frequency = <400000>;
@@ -599,6 +826,37 @@ &pcie6a_phy {
status = "okay";
};
+&pm8550_gpios {
+ rtmr0_default: rtmr0-reset-n-active-state {
+ pins = "gpio10";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+
+ usb0_3p3_reg_en: usb0-3p3-reg-en-state {
+ pins = "gpio11";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
+&pm8550ve_9_gpios {
+ usb0_1p8_reg_en: usb0-1p8-reg-en-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
&pmc8380_3_gpios {
edp_bl_en: edp-bl-en-state {
pins = "gpio4";
@@ -609,6 +867,17 @@ edp_bl_en: edp-bl-en-state {
};
};
+&pmc8380_5_gpios {
+ usb0_pwr_1p15_reg_en: usb0-pwr-1p15-reg-en-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>; /* 1.8V */
+ bias-disable;
+ input-disable;
+ output-enable;
+ };
+};
+
&qupv3_0 {
status = "okay";
};
@@ -744,6 +1013,34 @@ wake-n-pins {
};
};
+ rtmr1_default: rtmr1-reset-n-active-state {
+ pins = "gpio176";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb1_pwr_1p15_reg_en: usb1-pwr-1p15-reg-en-state {
+ pins = "gpio188";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb1_pwr_1p8_reg_en: usb1-pwr-1p8-reg-en-state {
+ pins = "gpio175";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb1_pwr_3p3_reg_en: usb1-pwr-3p3-reg-en-state {
+ pins = "gpio186";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
wcd_default: wcd-reset-n-active-state {
pins = "gpio191";
function = "gpio";
@@ -778,7 +1075,7 @@ &usb_1_ss0_dwc3_hs {
};
&usb_1_ss0_qmpphy_out {
- remote-endpoint = <&pmic_glink_ss0_ss_in>;
+ remote-endpoint = <&retimer_ss0_ss_in>;
};
&usb_1_ss1_hsphy {
@@ -806,5 +1103,5 @@ &usb_1_ss1_dwc3_hs {
};
&usb_1_ss1_qmpphy_out {
- remote-endpoint = <&pmic_glink_ss1_ss_in>;
+ remote-endpoint = <&retimer_ss1_ss_in>;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
` (4 preceding siblings ...)
2024-11-12 17:01 ` [PATCH v5 5/6] arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers Abel Vesa
@ 2024-11-12 17:01 ` Abel Vesa
2024-11-12 17:05 ` Abel Vesa
2024-11-15 15:13 ` [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Rob Herring (Arm)
6 siblings, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:01 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree, Abel Vesa
The Lenovo ThinkPad T14s Gen6 provides external DisplayPort on all
2 USB Type-C ports. Each one of this ports is connected to a dedicated
DisplayPort controller.
Due to support missing in the USB/DisplayPort combo PHY driver,
the external DisplayPort is limited to 2 lanes.
So enable the first and second DisplayPort controllers and limit their
data lanes number to 2.
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
.../boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
index ea3ecc7c5bda24f3a0a7bb027b456462b11daf4d..b08a173f0cfe2a2fc241a4e689d35b5e7e03d7e1 100644
--- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
+++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
@@ -746,6 +746,22 @@ &mdss {
status = "okay";
};
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+};
+
+&mdss_dp1 {
+ status = "okay";
+};
+
+&mdss_dp1_out {
+ data-lanes = <0 1>;
+};
+
&mdss_dp3 {
compatible = "qcom,x1e80100-dp";
/delete-property/ #sound-dai-cells;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support
2024-11-12 17:01 ` [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support Abel Vesa
@ 2024-11-12 17:05 ` Abel Vesa
0 siblings, 0 replies; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:05 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree
On 24-11-12 19:01:15, Abel Vesa wrote:
> The Lenovo ThinkPad T14s Gen6 provides external DisplayPort on all
> 2 USB Type-C ports. Each one of this ports is connected to a dedicated
> DisplayPort controller.
>
> Due to support missing in the USB/DisplayPort combo PHY driver,
> the external DisplayPort is limited to 2 lanes.
>
> So enable the first and second DisplayPort controllers and limit their
> data lanes number to 2.
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Please do not merge this specific patch.
It is provided just for context and testing purposes.
See the cover note for more details.
> ---
> .../boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
> index ea3ecc7c5bda24f3a0a7bb027b456462b11daf4d..b08a173f0cfe2a2fc241a4e689d35b5e7e03d7e1 100644
> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts
> @@ -746,6 +746,22 @@ &mdss {
> status = "okay";
> };
>
> +&mdss_dp0 {
> + status = "okay";
> +};
> +
> +&mdss_dp0_out {
> + data-lanes = <0 1>;
> +};
> +
> +&mdss_dp1 {
> + status = "okay";
> +};
> +
> +&mdss_dp1_out {
> + data-lanes = <0 1>;
> +};
> +
> &mdss_dp3 {
> compatible = "qcom,x1e80100-dp";
> /delete-property/ #sound-dai-cells;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
2024-11-12 17:01 ` [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support Abel Vesa
@ 2024-11-12 17:05 ` Abel Vesa
2024-11-13 6:03 ` Greg Kroah-Hartman
0 siblings, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2024-11-12 17:05 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: Rajendra Nayak, Sibi Sankar, Johan Hovold, Dmitry Baryshkov,
Trilok Soni, Christophe JAILLET, linux-kernel, linux-usb,
linux-arm-msm, devicetree
On 24-11-12 19:01:13, Abel Vesa wrote:
> The X Elite CRD provides external DisplayPort on all 3 USB Type-C ports.
> Each one of this ports is connected to a dedicated DisplayPort
> controller.
>
> Due to support missing in the USB/DisplayPort combo PHY driver,
> the external DisplayPort is limited to 2 lanes.
>
> So enable all 3 remaining DisplayPort controllers and limit their data
> lanes number to 2.
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Please do not merge this specific patch.
It is provided just for context and testing purposes.
See the cover note for more details.
> ---
> arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> index 659520404adec33c3551f8d0a5ae3db9e0a18d44..6dc2ebbf6d27fbbf0f224e58cd39ffd33792c6a1 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> @@ -1125,6 +1125,30 @@ &mdss {
> status = "okay";
> };
>
> +&mdss_dp0 {
> + status = "okay";
> +};
> +
> +&mdss_dp0_out {
> + data-lanes = <0 1>;
> +};
> +
> +&mdss_dp1 {
> + status = "okay";
> +};
> +
> +&mdss_dp1_out {
> + data-lanes = <0 1>;
> +};
> +
> +&mdss_dp2 {
> + status = "okay";
> +};
> +
> +&mdss_dp2_out {
> + data-lanes = <0 1>;
> +};
> +
> &mdss_dp3 {
> compatible = "qcom,x1e80100-dp";
> /delete-property/ #sound-dai-cells;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
2024-11-12 17:05 ` Abel Vesa
@ 2024-11-13 6:03 ` Greg Kroah-Hartman
2025-01-06 14:24 ` Abel Vesa
0 siblings, 1 reply; 18+ messages in thread
From: Greg Kroah-Hartman @ 2024-11-13 6:03 UTC (permalink / raw)
To: Abel Vesa
Cc: Heikki Krogerus, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Rajendra Nayak, Sibi Sankar,
Johan Hovold, Dmitry Baryshkov, Trilok Soni, Christophe JAILLET,
linux-kernel, linux-usb, linux-arm-msm, devicetree
On Tue, Nov 12, 2024 at 07:05:29PM +0200, Abel Vesa wrote:
> On 24-11-12 19:01:13, Abel Vesa wrote:
> > The X Elite CRD provides external DisplayPort on all 3 USB Type-C ports.
> > Each one of this ports is connected to a dedicated DisplayPort
> > controller.
> >
> > Due to support missing in the USB/DisplayPort combo PHY driver,
> > the external DisplayPort is limited to 2 lanes.
> >
> > So enable all 3 remaining DisplayPort controllers and limit their data
> > lanes number to 2.
> >
> > Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
>
> Please do not merge this specific patch.
Please do not mix patches that should, and should not, be applied in the
same series as that plays havoc with our tools that want to take a whole
series at once. Stuff like this just makes me delete the whole series
from my review queue, and if you got sent something like this, I imagine
you would do the same :(
thanks,
greg k-h
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
` (5 preceding siblings ...)
2024-11-12 17:01 ` [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support Abel Vesa
@ 2024-11-15 15:13 ` Rob Herring (Arm)
6 siblings, 0 replies; 18+ messages in thread
From: Rob Herring (Arm) @ 2024-11-15 15:13 UTC (permalink / raw)
To: Abel Vesa
Cc: Rajendra Nayak, linux-kernel, Trilok Soni, Conor Dooley,
Greg Kroah-Hartman, Heikki Krogerus, Konrad Dybcio,
Dmitry Baryshkov, Christophe JAILLET, linux-usb, Johan Hovold,
linux-arm-msm, devicetree, Krzysztof Kozlowski, Sibi Sankar,
Bjorn Andersson
On Tue, 12 Nov 2024 19:01:09 +0200, Abel Vesa wrote:
> The Parade PS8830 is a Type-C multi-protocol retimer that is controlled
> via I2C. It provides altmode and orientation handling and usually sits
> between the Type-C port and the PHY.
>
> It is currently used alongside Qualcomm Snapdragon X Elite SoCs on quite
> a few laptops already.
>
> This new driver adds support for the following 3 modes:
> - DP 4lanes (pin assignments C and E)
> - DP 2lanes + USB3 (pin assignment D)
> - USB3
>
> This retimer is a LTTPR (Link-Training Tunable PHY Repeater) which means
> it can support link training from source to itself. This means that the
> DP driver needs to be aware of the repeater presence and to handle
> the link training accordingly. This is currently missing from msm dp
> driver, but there is already a patchset [1] on the list that adds it.
> Once done, full external DP will be working on all X1E laptops that make
> use of this retimer.
>
> NOTE: Currently, due to both LTTPR missing support in msm DP and a
> reported crash that can happen on DP unplug, the DP DT patches are not
> supposed to be merged yet. That patch is only shared for testing purposes.
> Once those 2 issues have been resolved, the MDSS DP 0-2 enablement patch
> will be respun.
>
> The LTTPR patchset is already on the list:
> [1] https://lore.kernel.org/all/20241031-drm-dp-msm-add-lttpr-transparent-mode-set-v1-0-cafbb9855f40@linaro.org/
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
> ---
> Changes in v5:
> - Renamed binding schema to be the same as the compatible.
> - Dropped the ps8830,boot-on from the schema.
> - Added register offsets and bits names to the driver, like Konrad
> suggested.
> - Reordered the vregs and clocks enabling, as per Johan's request.
> - Used the dev_err_probe for regmap init failure and dropped the
> multiple regulator disable calls, replacing it with single call to
> helper, as Christophe suggested. Also replaced dev_err with
> dev_err_probe on typec_switch_register and typec_mux_register failure.
> - Added some new pinctrl specific properties to all pmic provided
> gpios that control retimer vregs.
> - Re-ordered alphabetically the retimers default state pinconfs.
> - Added the T14s patches with same exact support, as per Johan's
> request.
> - Link to v4: https://lore.kernel.org/r/20241101-x1e80100-ps8830-v4-0-f0f7518b263e@linaro.org
>
> Changes in v4:
> - Renamed the driver and bindings schema to ps883x to allow future
> support for the PS8833.
> - Dropped the dedicated DT property for keeping the retimers from
> resetting on probe, and replaced that with a read to figure out
> if it has been already configured or not. This involves leaving the
> reset gpio as-is on probe if the retimer has been already configured.
> - Replaced the fwnode_typec_switch_get() call with typec_switch_get()
> - Replaced the fwnode_typec_mux_get() call with typec_mux_get()
> - Dropped the clock name, as there is only one clock. As per Bjorn's
> suggestion.
> - Dropped regcache as it seems it is not needed.
> - Re-worded all commit messages to explain better the problem and the
> proposed changes.
> - Link to v3: https://lore.kernel.org/r/20241022-x1e80100-ps8830-v3-0-68a95f351e99@linaro.org
>
> Changes in v3:
> - Reworked the schema binding by using the usb/usb-switch.yaml defined
> port graph and properties. Addressed all comments from Johan and
> Dmitry.
> - Dropped the manual caching of the config values on regmap write in the
> driver.
> - Reordered the DP pin assignment states within the switch clause, as
> Dmitry suggested.
> - Added SVID check to not allow any altmode other than DP.
> - Added DT patches (retimer for USB orientation handling and DP
> enablement). Did this in order to offer a full picture of how it all
> fits together.
> - Split the DP enablement in DT in a separate patchset so the USB
> handling can be merged separately.
> - Added ps8830,boot-on to let the driver know it is supposed to skip
> resetting the retimer on driver probe, as the bootloader might already
> let it in a pre-configured state.
> - Marked all retimer voltage regulators as boot-on since we want to
> maintain the state for coldplug orientation.
> - Added pinconf for all retimer0 gpios.
> - Didn't pick up Konrad's T-b tags and Krzysztof's R-b tag as the rework
> is quite extensive. Especially because of the ps8830,boot-on and what
> it does.
> - Link to v2: https://lore.kernel.org/r/20241004-x1e80100-ps8830-v2-0-5cd8008c8c40@linaro.org
>
> Changes in v2:
> - Addressed all comments from Johan and Konrad.
> - Reworked the handling of the vregs so it would be more cleaner.
> Dropped the usage of bulk regulators API and handled them separately.
> Also discribed all regulators according to data sheet.
> - Added all delays according to data sheet.
> - Fixed coldplug (on boot) orientation detection.
> - Didn't pick Krzysztof's R-b tag because the bindings changed w.r.t
> supplies.
> - Link to v1: https://lore.kernel.org/r/20240829-x1e80100-ps8830-v1-0-bcc4790b1d45@linaro.org
>
> ---
> Abel Vesa (6):
> dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings
> usb: typec: Add support for Parade PS8830 Type-C Retimer
> arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers
> arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
> arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers
> arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support
>
> .../devicetree/bindings/usb/parade,ps8830.yaml | 119 ++++++
> .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 321 +++++++++++++-
> arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 474 ++++++++++++++++++++-
> drivers/usb/typec/mux/Kconfig | 10 +
> drivers/usb/typec/mux/Makefile | 1 +
> drivers/usb/typec/mux/ps883x.c | 437 +++++++++++++++++++
> 6 files changed, 1352 insertions(+), 10 deletions(-)
> ---
> base-commit: 28955f4fa2823e39f1ecfb3a37a364563527afbc
> change-id: 20240521-x1e80100-ps8830-d5ccca95b557
>
> Best regards,
> --
> Abel Vesa <abel.vesa@linaro.org>
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y qcom/x1e78100-lenovo-thinkpad-t14s.dtb qcom/x1e80100-crd.dtb' for 20241112-x1e80100-ps8830-v5-0-4ad83af4d162@linaro.org:
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtb: usb@a2f8800: interrupt-names: ['pwr_event', 'dp_hs_phy_irq', 'dm_hs_phy_irq'] is too short
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
arch/arm64/boot/dts/qcom/x1e80100-crd.dtb: usb@a2f8800: interrupt-names: ['pwr_event', 'dp_hs_phy_irq', 'dm_hs_phy_irq'] is too short
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings
2024-11-12 17:01 ` [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings Abel Vesa
@ 2024-11-15 16:44 ` Rob Herring
0 siblings, 0 replies; 18+ messages in thread
From: Rob Herring @ 2024-11-15 16:44 UTC (permalink / raw)
To: Abel Vesa
Cc: Heikki Krogerus, Greg Kroah-Hartman, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Rajendra Nayak,
Sibi Sankar, Johan Hovold, Dmitry Baryshkov, Trilok Soni,
Christophe JAILLET, linux-kernel, linux-usb, linux-arm-msm,
devicetree
On Tue, Nov 12, 2024 at 07:01:10PM +0200, Abel Vesa wrote:
> The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> controlled over I2C. It usually sits between a USB/DisplayPort PHY and the
> Type-C connector, and provides orientation and altmode handling.
>
> Currently, it is found on all boards featuring the Qualcomm Snapdragon
> X Elite SoCs.
>
> Document bindings for its new driver. Future-proof the schema for the
> PS8833 variant, which seems to be similar to PS8830.
>
> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
> ---
> .../devicetree/bindings/usb/parade,ps8830.yaml | 119 +++++++++++++++++++++
> 1 file changed, 119 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/usb/parade,ps8830.yaml b/Documentation/devicetree/bindings/usb/parade,ps8830.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..2f20d20a2bdfe2499588dc621c14cd16ab159002
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/parade,ps8830.yaml
> @@ -0,0 +1,119 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/usb/parade,ps8830.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Parade PS883x USB and DisplayPort Retimer
> +
> +maintainers:
> + - Abel Vesa <abel.vesa@linaro.org>
> +
> +properties:
> + compatible:
> + enum:
> + - parade,ps8830
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + items:
> + - description: XO Clock
> +
> + reset-gpios:
> + maxItems: 1
> +
> + vdd-supply:
> + description: power supply (1.07V)
> +
> + vdd33-supply:
> + description: power supply (3.3V)
> +
> + vdd33-cap-supply:
> + description: power supply (3.3V)
> +
> + vddar-supply:
> + description: power supply (1.07V)
> +
> + vddat-supply:
> + description: power supply (1.07V)
> +
> + vddio-supply:
> + description: power supply (1.2V or 1.8V)
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - reset-gpios
> + - vdd-supply
> + - vdd33-supply
> + - vdd33-cap-supply
> + - vddat-supply
> + - vddio-supply
> + - orientation-switch
> + - retimer-switch
> +
> +allOf:
> + - $ref: usb-switch.yaml#
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + i2c {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + typec-mux@8 {
> + compatible = "parade,ps8830";
> + reg = <0x8>;
> +
> + clocks = <&clk_rtmr_xo>;
> +
> + vdd-supply = <&vreg_rtmr_1p15>;
> + vdd33-supply = <&vreg_rtmr_3p3>;
> + vdd33-cap-supply = <&vreg_rtmr_3p3>;
> + vddar-supply = <&vreg_rtmr_1p15>;
> + vddat-supply = <&vreg_rtmr_1p15>;
> + vddio-supply = <&vreg_rtmr_1p8>;
> +
> + reset-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>;
> +
> + retimer-switch;
> + orientation-switch;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + endpoint {
> + remote-endpoint = <&typec_con_ss>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + endpoint {
> + remote-endpoint = <&usb_phy_ss>;
> + };
> + };
> +
> + port@2 {
No such port defined in usb-switch.yaml and you didn't define it here.
> + reg = <2>;
> +
> + endpoint {
> + remote-endpoint = <&typec_dp_aux>;
> + };
> + };
> + };
> + };
> + };
> +...
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2024-11-12 17:01 ` [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer Abel Vesa
@ 2024-12-04 16:24 ` Johan Hovold
2024-12-05 23:05 ` Bjorn Andersson
2025-01-06 14:14 ` Abel Vesa
0 siblings, 2 replies; 18+ messages in thread
From: Johan Hovold @ 2024-12-04 16:24 UTC (permalink / raw)
To: Abel Vesa
Cc: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Rajendra Nayak, Sibi Sankar, Dmitry Baryshkov, Trilok Soni,
Christophe JAILLET, linux-kernel, linux-usb, linux-arm-msm,
devicetree
On Tue, Nov 12, 2024 at 07:01:11PM +0200, Abel Vesa wrote:
> The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> controlled over I2C. It usually sits between a USB/DisplayPort PHY
> and the Type-C connector, and provides orientation and altmode handling.
>
> The boards that use this retimer are the ones featuring the Qualcomm
> Snapdragon X Elite SoCs.
> +static int ps883x_sw_set(struct typec_switch_dev *sw,
> + enum typec_orientation orientation)
> +{
> + struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
> + int ret = 0;
> +
> + ret = typec_switch_set(retimer->typec_switch, orientation);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&retimer->lock);
> +
> + if (retimer->orientation != orientation) {
> + retimer->orientation = orientation;
> +
> + ret = ps883x_set(retimer);
> + }
> +
> + mutex_unlock(&retimer->lock);
> +
> + return ret;
> +}
This seems to indicate a bigger problem, but I see this function called
during early resume while the i2c controller is suspended:
[ 54.213900] ------------[ cut here ]------------
[ 54.213942] i2c i2c-2: Transfer while suspended
[ 54.214125] WARNING: CPU: 0 PID: 126 at drivers/i2c/i2c-core.h:56 __i2c_transfer+0x874/0x968 [i2c_core]
...
[ 54.214833] CPU: 0 UID: 0 PID: 126 Comm: kworker/0:2 Not tainted 6.13.0-rc1 #11
[ 54.214844] Hardware name: Qualcomm CRD, BIOS 6.0.231221.BOOT.MXF.2.4-00348.1-HAMOA-1 12/21/2023
[ 54.214852] Workqueue: events pmic_glink_altmode_worker [pmic_glink_altmode]
...
[ 54.215090] Call trace:
[ 54.215097] __i2c_transfer+0x874/0x968 [i2c_core] (P)
[ 54.215112] __i2c_transfer+0x874/0x968 [i2c_core] (L)
[ 54.215126] i2c_transfer+0x94/0xf0 [i2c_core]
[ 54.215140] i2c_transfer_buffer_flags+0x5c/0x90 [i2c_core]
[ 54.215153] regmap_i2c_write+0x20/0x58 [regmap_i2c]
[ 54.215166] _regmap_raw_write_impl+0x740/0x894
[ 54.215184] _regmap_bus_raw_write+0x60/0x7c
[ 54.215192] _regmap_write+0x60/0x1b4
[ 54.215200] regmap_write+0x4c/0x78
[ 54.215207] ps883x_set+0xb0/0x10c [ps883x]
[ 54.215219] ps883x_sw_set+0x74/0x98 [ps883x]
[ 54.215227] typec_switch_set+0x58/0x90 [typec]
[ 54.215248] pmic_glink_altmode_worker+0x3c/0x23c [pmic_glink_altmode]
[ 54.215257] process_one_work+0x20c/0x610
[ 54.215274] worker_thread+0x23c/0x378
[ 54.215283] kthread+0x124/0x128
[ 54.215291] ret_from_fork+0x10/0x20
[ 54.215303] irq event stamp: 28140
[ 54.215309] hardirqs last enabled at (28139): [<ffffd15e3bc2a434>] __up_console_sem+0x6c/0x80
[ 54.215325] hardirqs last disabled at (28140): [<ffffd15e3c596aa4>] el1_dbg+0x24/0x8c
[ 54.215341] softirqs last enabled at (28120): [<ffffd15e3bb9b82c>] handle_softirqs+0x4c4/0x4dc
[ 54.215355] softirqs last disabled at (27961): [<ffffd15e3bb501ec>] __do_softirq+0x14/0x20
[ 54.215363] ---[ end trace 0000000000000000 ]---
[ 54.216889] Enabling non-boot CPUs ...
This can be reproduced on the CRD (or T14s) by disconnecting, for
example, a mass storage device while the laptop is suspended.
> +static int ps883x_retimer_set(struct typec_retimer *rtmr,
> + struct typec_retimer_state *state)
> +{
> + struct ps883x_retimer *retimer = typec_retimer_get_drvdata(rtmr);
> + struct typec_mux_state mux_state;
> + int ret = 0;
> +
> + mutex_lock(&retimer->lock);
> +
> + if (state->mode != retimer->mode) {
> + retimer->mode = state->mode;
> +
> + if (state->alt)
> + retimer->svid = state->alt->svid;
> + else
> + retimer->svid = 0; // No SVID
Nit: I'd prefer if you avoid c99 comments for consistency.
> + ret = ps883x_set(retimer);
> + }
> +
> + mutex_unlock(&retimer->lock);
> +
> + if (ret)
> + return ret;
> +
> + mux_state.alt = state->alt;
> + mux_state.data = state->data;
> + mux_state.mode = state->mode;
> +
> + return typec_mux_set(retimer->typec_mux, &mux_state);
> +}
> +static int ps883x_retimer_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + struct typec_switch_desc sw_desc = { };
> + struct typec_retimer_desc rtmr_desc = { };
> + struct ps883x_retimer *retimer;
> + int ret;
> +
> + retimer = devm_kzalloc(dev, sizeof(*retimer), GFP_KERNEL);
> + if (!retimer)
> + return -ENOMEM;
> +
> + retimer->client = client;
> +
> + mutex_init(&retimer->lock);
> +
> + retimer->regmap = devm_regmap_init_i2c(client, &ps883x_retimer_regmap);
> + if (IS_ERR(retimer->regmap))
> + return dev_err_probe(dev, PTR_ERR(retimer->regmap),
> + "failed to allocate register map\n");
> +
> + ret = ps883x_get_vregs(retimer);
> + if (ret)
> + return ret;
> +
> + retimer->xo_clk = devm_clk_get(dev, NULL);
> + if (IS_ERR(retimer->xo_clk))
> + return dev_err_probe(dev, PTR_ERR(retimer->xo_clk),
> + "failed to get xo clock\n");
> +
> + retimer->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
GPIOD_ASIS is documented as requiring you to later set the direction,
but this does not happen unconditionally below.
> + if (IS_ERR(retimer->reset_gpio))
> + return dev_err_probe(dev, PTR_ERR(retimer->reset_gpio),
> + "failed to get reset gpio\n");
> +
> + retimer->typec_switch = typec_switch_get(dev);
> + if (IS_ERR(retimer->typec_switch))
> + return dev_err_probe(dev, PTR_ERR(retimer->typec_switch),
> + "failed to acquire orientation-switch\n");
> +
> + retimer->typec_mux = typec_mux_get(dev);
> + if (IS_ERR(retimer->typec_mux)) {
> + ret = dev_err_probe(dev, PTR_ERR(retimer->typec_mux),
> + "failed to acquire mode-mux\n");
> + goto err_switch_put;
> + }
> +
> + ret = drm_aux_bridge_register(dev);
> + if (ret)
> + goto err_mux_put;
> +
> + ret = ps883x_enable_vregs(retimer);
> + if (ret)
> + goto err_mux_put;
> +
> + ret = clk_prepare_enable(retimer->xo_clk);
> + if (ret) {
> + dev_err(dev, "failed to enable XO: %d\n", ret);
> + goto err_vregs_disable;
> + }
> +
> + sw_desc.drvdata = retimer;
> + sw_desc.fwnode = dev_fwnode(dev);
> + sw_desc.set = ps883x_sw_set;
> +
> + retimer->sw = typec_switch_register(dev, &sw_desc);
> + if (IS_ERR(retimer->sw)) {
> + ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
> + "failed to register typec switch\n");
> + goto err_clk_disable;
> + }
> +
> + rtmr_desc.drvdata = retimer;
> + rtmr_desc.fwnode = dev_fwnode(dev);
> + rtmr_desc.set = ps883x_retimer_set;
> +
> + retimer->retimer = typec_retimer_register(dev, &rtmr_desc);
> + if (IS_ERR(retimer->retimer)) {
> + ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
> + "failed to register typec retimer\n");
> + goto err_switch_unregister;
> + }
The registration functions do not return -EPROBE_DEFER so I'd prefer if
you switch back to dev_err() here as we already discussed. A driver must
not probe defer after having registered child devices so it's important
to document which functions can actually trigger a probe deferral.
I know there's been a recent change to the dev_err_probe() suggesting
that it could be used anyway, but I think that's a really bad idea and
I'm considering sending a revert for that.
> +
> + /* skip resetting if already configured */
> + if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
> + CONN_STATUS_0_CONNECTION_PRESENT))
> + return 0;
What if the device is held in reset? This looks like it only works if
the boot firmware has already enabled the retimer. Otherwise you may
return success from probe here with the retimer still in reset.
> + gpiod_direction_output(retimer->reset_gpio, 1);
> +
> + /* VDD IO supply enable to reset release delay */
> + usleep_range(4000, 14000);
> +
> + gpiod_set_value(retimer->reset_gpio, 0);
> +
> + /* firmware initialization delay */
> + msleep(60);
> +
> + return 0;
> +
> +err_switch_unregister:
> + typec_switch_unregister(retimer->sw);
> +err_vregs_disable:
> + ps883x_disable_vregs(retimer);
> +err_clk_disable:
> + clk_disable_unprepare(retimer->xo_clk);
> +err_mux_put:
> + typec_mux_put(retimer->typec_mux);
> +err_switch_put:
> + typec_switch_put(retimer->typec_switch);
> +
> + return ret;
> +}
> +
> +static void ps883x_retimer_remove(struct i2c_client *client)
> +{
> + struct ps883x_retimer *retimer = i2c_get_clientdata(client);
> +
> + typec_retimer_unregister(retimer->retimer);
> + typec_switch_unregister(retimer->sw);
> +
> + gpiod_set_value(retimer->reset_gpio, 1);
> +
> + clk_disable_unprepare(retimer->xo_clk);
> +
> + ps883x_disable_vregs(retimer);
> +
> + typec_mux_put(retimer->typec_mux);
> + typec_switch_put(retimer->typec_switch);
> +}
Johan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2024-12-04 16:24 ` Johan Hovold
@ 2024-12-05 23:05 ` Bjorn Andersson
2024-12-07 21:45 ` Abel Vesa
2025-01-06 14:14 ` Abel Vesa
1 sibling, 1 reply; 18+ messages in thread
From: Bjorn Andersson @ 2024-12-05 23:05 UTC (permalink / raw)
To: Johan Hovold
Cc: Abel Vesa, Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Rajendra Nayak,
Sibi Sankar, Dmitry Baryshkov, Trilok Soni, Christophe JAILLET,
linux-kernel, linux-usb, linux-arm-msm, devicetree
On Wed, Dec 04, 2024 at 05:24:54PM +0100, Johan Hovold wrote:
> On Tue, Nov 12, 2024 at 07:01:11PM +0200, Abel Vesa wrote:
> > The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> > controlled over I2C. It usually sits between a USB/DisplayPort PHY
> > and the Type-C connector, and provides orientation and altmode handling.
> >
> > The boards that use this retimer are the ones featuring the Qualcomm
> > Snapdragon X Elite SoCs.
>
> > +static int ps883x_sw_set(struct typec_switch_dev *sw,
> > + enum typec_orientation orientation)
> > +{
> > + struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
> > + int ret = 0;
> > +
> > + ret = typec_switch_set(retimer->typec_switch, orientation);
> > + if (ret)
> > + return ret;
> > +
> > + mutex_lock(&retimer->lock);
> > +
> > + if (retimer->orientation != orientation) {
> > + retimer->orientation = orientation;
> > +
> > + ret = ps883x_set(retimer);
> > + }
> > +
> > + mutex_unlock(&retimer->lock);
> > +
> > + return ret;
> > +}
>
> This seems to indicate a bigger problem, but I see this function called
> during early resume while the i2c controller is suspended:
>
> [ 54.213900] ------------[ cut here ]------------
> [ 54.213942] i2c i2c-2: Transfer while suspended
> [ 54.214125] WARNING: CPU: 0 PID: 126 at drivers/i2c/i2c-core.h:56 __i2c_transfer+0x874/0x968 [i2c_core]
> ...
> [ 54.214833] CPU: 0 UID: 0 PID: 126 Comm: kworker/0:2 Not tainted 6.13.0-rc1 #11
> [ 54.214844] Hardware name: Qualcomm CRD, BIOS 6.0.231221.BOOT.MXF.2.4-00348.1-HAMOA-1 12/21/2023
> [ 54.214852] Workqueue: events pmic_glink_altmode_worker [pmic_glink_altmode]
> ...
> [ 54.215090] Call trace:
> [ 54.215097] __i2c_transfer+0x874/0x968 [i2c_core] (P)
> [ 54.215112] __i2c_transfer+0x874/0x968 [i2c_core] (L)
> [ 54.215126] i2c_transfer+0x94/0xf0 [i2c_core]
> [ 54.215140] i2c_transfer_buffer_flags+0x5c/0x90 [i2c_core]
> [ 54.215153] regmap_i2c_write+0x20/0x58 [regmap_i2c]
> [ 54.215166] _regmap_raw_write_impl+0x740/0x894
> [ 54.215184] _regmap_bus_raw_write+0x60/0x7c
> [ 54.215192] _regmap_write+0x60/0x1b4
> [ 54.215200] regmap_write+0x4c/0x78
> [ 54.215207] ps883x_set+0xb0/0x10c [ps883x]
> [ 54.215219] ps883x_sw_set+0x74/0x98 [ps883x]
> [ 54.215227] typec_switch_set+0x58/0x90 [typec]
> [ 54.215248] pmic_glink_altmode_worker+0x3c/0x23c [pmic_glink_altmode]
> [ 54.215257] process_one_work+0x20c/0x610
> [ 54.215274] worker_thread+0x23c/0x378
> [ 54.215283] kthread+0x124/0x128
> [ 54.215291] ret_from_fork+0x10/0x20
> [ 54.215303] irq event stamp: 28140
> [ 54.215309] hardirqs last enabled at (28139): [<ffffd15e3bc2a434>] __up_console_sem+0x6c/0x80
> [ 54.215325] hardirqs last disabled at (28140): [<ffffd15e3c596aa4>] el1_dbg+0x24/0x8c
> [ 54.215341] softirqs last enabled at (28120): [<ffffd15e3bb9b82c>] handle_softirqs+0x4c4/0x4dc
> [ 54.215355] softirqs last disabled at (27961): [<ffffd15e3bb501ec>] __do_softirq+0x14/0x20
> [ 54.215363] ---[ end trace 0000000000000000 ]---
> [ 54.216889] Enabling non-boot CPUs ...
>
> This can be reproduced on the CRD (or T14s) by disconnecting, for
> example, a mass storage device while the laptop is suspended.
>
I wonder if this is because drivers/rpmsg/qcom_glink_smem.c line 309
registers the GLINK interrupt as IRQF_NO_SUSPEND as a remnant from being
used for rpm communication...
This is no longer needed (glink/rpm code path is now different), but
iirc the cleanup got stuck in the question of dealing with wakeup
capabilities (and priorities).
Regards,
Bjorn
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2024-12-05 23:05 ` Bjorn Andersson
@ 2024-12-07 21:45 ` Abel Vesa
0 siblings, 0 replies; 18+ messages in thread
From: Abel Vesa @ 2024-12-07 21:45 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Johan Hovold, Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Rajendra Nayak,
Sibi Sankar, Dmitry Baryshkov, Trilok Soni, Christophe JAILLET,
linux-kernel, linux-usb, linux-arm-msm, devicetree
On 24-12-05 17:05:17, Bjorn Andersson wrote:
> On Wed, Dec 04, 2024 at 05:24:54PM +0100, Johan Hovold wrote:
> > On Tue, Nov 12, 2024 at 07:01:11PM +0200, Abel Vesa wrote:
> > > The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> > > controlled over I2C. It usually sits between a USB/DisplayPort PHY
> > > and the Type-C connector, and provides orientation and altmode handling.
> > >
> > > The boards that use this retimer are the ones featuring the Qualcomm
> > > Snapdragon X Elite SoCs.
> >
> > > +static int ps883x_sw_set(struct typec_switch_dev *sw,
> > > + enum typec_orientation orientation)
> > > +{
> > > + struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
> > > + int ret = 0;
> > > +
> > > + ret = typec_switch_set(retimer->typec_switch, orientation);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + mutex_lock(&retimer->lock);
> > > +
> > > + if (retimer->orientation != orientation) {
> > > + retimer->orientation = orientation;
> > > +
> > > + ret = ps883x_set(retimer);
> > > + }
> > > +
> > > + mutex_unlock(&retimer->lock);
> > > +
> > > + return ret;
> > > +}
> >
> > This seems to indicate a bigger problem, but I see this function called
> > during early resume while the i2c controller is suspended:
> >
> > [ 54.213900] ------------[ cut here ]------------
> > [ 54.213942] i2c i2c-2: Transfer while suspended
> > [ 54.214125] WARNING: CPU: 0 PID: 126 at drivers/i2c/i2c-core.h:56 __i2c_transfer+0x874/0x968 [i2c_core]
> > ...
> > [ 54.214833] CPU: 0 UID: 0 PID: 126 Comm: kworker/0:2 Not tainted 6.13.0-rc1 #11
> > [ 54.214844] Hardware name: Qualcomm CRD, BIOS 6.0.231221.BOOT.MXF.2.4-00348.1-HAMOA-1 12/21/2023
> > [ 54.214852] Workqueue: events pmic_glink_altmode_worker [pmic_glink_altmode]
> > ...
> > [ 54.215090] Call trace:
> > [ 54.215097] __i2c_transfer+0x874/0x968 [i2c_core] (P)
> > [ 54.215112] __i2c_transfer+0x874/0x968 [i2c_core] (L)
> > [ 54.215126] i2c_transfer+0x94/0xf0 [i2c_core]
> > [ 54.215140] i2c_transfer_buffer_flags+0x5c/0x90 [i2c_core]
> > [ 54.215153] regmap_i2c_write+0x20/0x58 [regmap_i2c]
> > [ 54.215166] _regmap_raw_write_impl+0x740/0x894
> > [ 54.215184] _regmap_bus_raw_write+0x60/0x7c
> > [ 54.215192] _regmap_write+0x60/0x1b4
> > [ 54.215200] regmap_write+0x4c/0x78
> > [ 54.215207] ps883x_set+0xb0/0x10c [ps883x]
> > [ 54.215219] ps883x_sw_set+0x74/0x98 [ps883x]
> > [ 54.215227] typec_switch_set+0x58/0x90 [typec]
> > [ 54.215248] pmic_glink_altmode_worker+0x3c/0x23c [pmic_glink_altmode]
> > [ 54.215257] process_one_work+0x20c/0x610
> > [ 54.215274] worker_thread+0x23c/0x378
> > [ 54.215283] kthread+0x124/0x128
> > [ 54.215291] ret_from_fork+0x10/0x20
> > [ 54.215303] irq event stamp: 28140
> > [ 54.215309] hardirqs last enabled at (28139): [<ffffd15e3bc2a434>] __up_console_sem+0x6c/0x80
> > [ 54.215325] hardirqs last disabled at (28140): [<ffffd15e3c596aa4>] el1_dbg+0x24/0x8c
> > [ 54.215341] softirqs last enabled at (28120): [<ffffd15e3bb9b82c>] handle_softirqs+0x4c4/0x4dc
> > [ 54.215355] softirqs last disabled at (27961): [<ffffd15e3bb501ec>] __do_softirq+0x14/0x20
> > [ 54.215363] ---[ end trace 0000000000000000 ]---
> > [ 54.216889] Enabling non-boot CPUs ...
> >
> > This can be reproduced on the CRD (or T14s) by disconnecting, for
> > example, a mass storage device while the laptop is suspended.
> >
>
> I wonder if this is because drivers/rpmsg/qcom_glink_smem.c line 309
> registers the GLINK interrupt as IRQF_NO_SUSPEND as a remnant from being
> used for rpm communication...
Yes. Seems like dropping the flag fixes this.
>
> This is no longer needed (glink/rpm code path is now different), but
> iirc the cleanup got stuck in the question of dealing with wakeup
> capabilities (and priorities).
I'll send a patch to drop the flag and we then can debate there if it's
the right thing to do w.r.t. wakeup.
>
> Regards,
> Bjorn
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2024-12-04 16:24 ` Johan Hovold
2024-12-05 23:05 ` Bjorn Andersson
@ 2025-01-06 14:14 ` Abel Vesa
2025-01-07 9:46 ` Johan Hovold
1 sibling, 1 reply; 18+ messages in thread
From: Abel Vesa @ 2025-01-06 14:14 UTC (permalink / raw)
To: Johan Hovold
Cc: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Rajendra Nayak, Sibi Sankar, Dmitry Baryshkov, Trilok Soni,
Christophe JAILLET, linux-kernel, linux-usb, linux-arm-msm,
devicetree
On 24-12-04 17:24:54, Johan Hovold wrote:
> On Tue, Nov 12, 2024 at 07:01:11PM +0200, Abel Vesa wrote:
> > The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> > controlled over I2C. It usually sits between a USB/DisplayPort PHY
> > and the Type-C connector, and provides orientation and altmode handling.
> >
> > The boards that use this retimer are the ones featuring the Qualcomm
> > Snapdragon X Elite SoCs.
>
> > +static int ps883x_sw_set(struct typec_switch_dev *sw,
> > + enum typec_orientation orientation)
> > +{
> > + struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
> > + int ret = 0;
> > +
> > + ret = typec_switch_set(retimer->typec_switch, orientation);
> > + if (ret)
> > + return ret;
> > +
> > + mutex_lock(&retimer->lock);
> > +
> > + if (retimer->orientation != orientation) {
> > + retimer->orientation = orientation;
> > +
> > + ret = ps883x_set(retimer);
> > + }
> > +
> > + mutex_unlock(&retimer->lock);
> > +
> > + return ret;
> > +}
>
> This seems to indicate a bigger problem, but I see this function called
> during early resume while the i2c controller is suspended:
>
> [ 54.213900] ------------[ cut here ]------------
> [ 54.213942] i2c i2c-2: Transfer while suspended
> [ 54.214125] WARNING: CPU: 0 PID: 126 at drivers/i2c/i2c-core.h:56 __i2c_transfer+0x874/0x968 [i2c_core]
> ...
> [ 54.214833] CPU: 0 UID: 0 PID: 126 Comm: kworker/0:2 Not tainted 6.13.0-rc1 #11
> [ 54.214844] Hardware name: Qualcomm CRD, BIOS 6.0.231221.BOOT.MXF.2.4-00348.1-HAMOA-1 12/21/2023
> [ 54.214852] Workqueue: events pmic_glink_altmode_worker [pmic_glink_altmode]
> ...
> [ 54.215090] Call trace:
> [ 54.215097] __i2c_transfer+0x874/0x968 [i2c_core] (P)
> [ 54.215112] __i2c_transfer+0x874/0x968 [i2c_core] (L)
> [ 54.215126] i2c_transfer+0x94/0xf0 [i2c_core]
> [ 54.215140] i2c_transfer_buffer_flags+0x5c/0x90 [i2c_core]
> [ 54.215153] regmap_i2c_write+0x20/0x58 [regmap_i2c]
> [ 54.215166] _regmap_raw_write_impl+0x740/0x894
> [ 54.215184] _regmap_bus_raw_write+0x60/0x7c
> [ 54.215192] _regmap_write+0x60/0x1b4
> [ 54.215200] regmap_write+0x4c/0x78
> [ 54.215207] ps883x_set+0xb0/0x10c [ps883x]
> [ 54.215219] ps883x_sw_set+0x74/0x98 [ps883x]
> [ 54.215227] typec_switch_set+0x58/0x90 [typec]
> [ 54.215248] pmic_glink_altmode_worker+0x3c/0x23c [pmic_glink_altmode]
> [ 54.215257] process_one_work+0x20c/0x610
> [ 54.215274] worker_thread+0x23c/0x378
> [ 54.215283] kthread+0x124/0x128
> [ 54.215291] ret_from_fork+0x10/0x20
> [ 54.215303] irq event stamp: 28140
> [ 54.215309] hardirqs last enabled at (28139): [<ffffd15e3bc2a434>] __up_console_sem+0x6c/0x80
> [ 54.215325] hardirqs last disabled at (28140): [<ffffd15e3c596aa4>] el1_dbg+0x24/0x8c
> [ 54.215341] softirqs last enabled at (28120): [<ffffd15e3bb9b82c>] handle_softirqs+0x4c4/0x4dc
> [ 54.215355] softirqs last disabled at (27961): [<ffffd15e3bb501ec>] __do_softirq+0x14/0x20
> [ 54.215363] ---[ end trace 0000000000000000 ]---
> [ 54.216889] Enabling non-boot CPUs ...
>
> This can be reproduced on the CRD (or T14s) by disconnecting, for
> example, a mass storage device while the laptop is suspended.
Sorry for the late reply.
According to Bjorn's reply, this needs to be fixed in qcom-glink-smem
driver due to the IRQF_NO_SUSPEND flag for the glink-smem interrupt.
TBF, this whole series is going to be delayed by that fix being needed anyway.
>
> > +static int ps883x_retimer_set(struct typec_retimer *rtmr,
> > + struct typec_retimer_state *state)
> > +{
> > + struct ps883x_retimer *retimer = typec_retimer_get_drvdata(rtmr);
> > + struct typec_mux_state mux_state;
> > + int ret = 0;
> > +
> > + mutex_lock(&retimer->lock);
> > +
> > + if (state->mode != retimer->mode) {
> > + retimer->mode = state->mode;
> > +
> > + if (state->alt)
> > + retimer->svid = state->alt->svid;
> > + else
> > + retimer->svid = 0; // No SVID
>
> Nit: I'd prefer if you avoid c99 comments for consistency.
Yes, will drop.
>
> > + ret = ps883x_set(retimer);
> > + }
> > +
> > + mutex_unlock(&retimer->lock);
> > +
> > + if (ret)
> > + return ret;
> > +
> > + mux_state.alt = state->alt;
> > + mux_state.data = state->data;
> > + mux_state.mode = state->mode;
> > +
> > + return typec_mux_set(retimer->typec_mux, &mux_state);
> > +}
>
> > +static int ps883x_retimer_probe(struct i2c_client *client)
> > +{
> > + struct device *dev = &client->dev;
> > + struct typec_switch_desc sw_desc = { };
> > + struct typec_retimer_desc rtmr_desc = { };
> > + struct ps883x_retimer *retimer;
> > + int ret;
> > +
> > + retimer = devm_kzalloc(dev, sizeof(*retimer), GFP_KERNEL);
> > + if (!retimer)
> > + return -ENOMEM;
> > +
> > + retimer->client = client;
> > +
> > + mutex_init(&retimer->lock);
> > +
> > + retimer->regmap = devm_regmap_init_i2c(client, &ps883x_retimer_regmap);
> > + if (IS_ERR(retimer->regmap))
> > + return dev_err_probe(dev, PTR_ERR(retimer->regmap),
> > + "failed to allocate register map\n");
> > +
> > + ret = ps883x_get_vregs(retimer);
> > + if (ret)
> > + return ret;
> > +
> > + retimer->xo_clk = devm_clk_get(dev, NULL);
> > + if (IS_ERR(retimer->xo_clk))
> > + return dev_err_probe(dev, PTR_ERR(retimer->xo_clk),
> > + "failed to get xo clock\n");
> > +
> > + retimer->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
>
> GPIOD_ASIS is documented as requiring you to later set the direction,
> but this does not happen unconditionally below.
Yes. Will do that after the read that figures out if the retimer is
already left configured or not.
>
> > + if (IS_ERR(retimer->reset_gpio))
> > + return dev_err_probe(dev, PTR_ERR(retimer->reset_gpio),
> > + "failed to get reset gpio\n");
> > +
> > + retimer->typec_switch = typec_switch_get(dev);
> > + if (IS_ERR(retimer->typec_switch))
> > + return dev_err_probe(dev, PTR_ERR(retimer->typec_switch),
> > + "failed to acquire orientation-switch\n");
> > +
> > + retimer->typec_mux = typec_mux_get(dev);
> > + if (IS_ERR(retimer->typec_mux)) {
> > + ret = dev_err_probe(dev, PTR_ERR(retimer->typec_mux),
> > + "failed to acquire mode-mux\n");
> > + goto err_switch_put;
> > + }
> > +
> > + ret = drm_aux_bridge_register(dev);
> > + if (ret)
> > + goto err_mux_put;
> > +
> > + ret = ps883x_enable_vregs(retimer);
> > + if (ret)
> > + goto err_mux_put;
> > +
> > + ret = clk_prepare_enable(retimer->xo_clk);
> > + if (ret) {
> > + dev_err(dev, "failed to enable XO: %d\n", ret);
> > + goto err_vregs_disable;
> > + }
> > +
> > + sw_desc.drvdata = retimer;
> > + sw_desc.fwnode = dev_fwnode(dev);
> > + sw_desc.set = ps883x_sw_set;
> > +
> > + retimer->sw = typec_switch_register(dev, &sw_desc);
> > + if (IS_ERR(retimer->sw)) {
> > + ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
> > + "failed to register typec switch\n");
> > + goto err_clk_disable;
> > + }
> > +
> > + rtmr_desc.drvdata = retimer;
> > + rtmr_desc.fwnode = dev_fwnode(dev);
> > + rtmr_desc.set = ps883x_retimer_set;
> > +
> > + retimer->retimer = typec_retimer_register(dev, &rtmr_desc);
> > + if (IS_ERR(retimer->retimer)) {
> > + ret = dev_err_probe(dev, PTR_ERR(retimer->sw),
> > + "failed to register typec retimer\n");
> > + goto err_switch_unregister;
> > + }
>
> The registration functions do not return -EPROBE_DEFER so I'd prefer if
> you switch back to dev_err() here as we already discussed. A driver must
> not probe defer after having registered child devices so it's important
> to document which functions can actually trigger a probe deferral.
>
> I know there's been a recent change to the dev_err_probe() suggesting
> that it could be used anyway, but I think that's a really bad idea and
> I'm considering sending a revert for that.
Makes sense to me. Will switch back to dev_err().
>
> > +
> > + /* skip resetting if already configured */
> > + if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
> > + CONN_STATUS_0_CONNECTION_PRESENT))
> > + return 0;
>
> What if the device is held in reset? This looks like it only works if
> the boot firmware has already enabled the retimer. Otherwise you may
> return success from probe here with the retimer still in reset.
Please correct me if I'm wrong, but if the read above fails or reads
anything else than "connection present", then below we go through the
resetting sequence. If it reads "connection present", then retimer can't
be in reset.
And here is where the direction setting mentioned above would have to
happen if the "connection is present" as well, not just for when the
repeater is in reset, which is handled below.
>
> > + gpiod_direction_output(retimer->reset_gpio, 1);
> > +
> > + /* VDD IO supply enable to reset release delay */
> > + usleep_range(4000, 14000);
> > +
> > + gpiod_set_value(retimer->reset_gpio, 0);
> > +
> > + /* firmware initialization delay */
> > + msleep(60);
> > +
> > + return 0;
> > +
> > +err_switch_unregister:
> > + typec_switch_unregister(retimer->sw);
> > +err_vregs_disable:
> > + ps883x_disable_vregs(retimer);
> > +err_clk_disable:
> > + clk_disable_unprepare(retimer->xo_clk);
> > +err_mux_put:
> > + typec_mux_put(retimer->typec_mux);
> > +err_switch_put:
> > + typec_switch_put(retimer->typec_switch);
> > +
> > + return ret;
> > +}
> > +
> > +static void ps883x_retimer_remove(struct i2c_client *client)
> > +{
> > + struct ps883x_retimer *retimer = i2c_get_clientdata(client);
> > +
> > + typec_retimer_unregister(retimer->retimer);
> > + typec_switch_unregister(retimer->sw);
> > +
> > + gpiod_set_value(retimer->reset_gpio, 1);
> > +
> > + clk_disable_unprepare(retimer->xo_clk);
> > +
> > + ps883x_disable_vregs(retimer);
> > +
> > + typec_mux_put(retimer->typec_mux);
> > + typec_switch_put(retimer->typec_switch);
> > +}
>
> Johan
Thanks for reviewing,
Abel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support
2024-11-13 6:03 ` Greg Kroah-Hartman
@ 2025-01-06 14:24 ` Abel Vesa
0 siblings, 0 replies; 18+ messages in thread
From: Abel Vesa @ 2025-01-06 14:24 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Heikki Krogerus, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Rajendra Nayak, Sibi Sankar,
Johan Hovold, Dmitry Baryshkov, Trilok Soni, Christophe JAILLET,
linux-kernel, linux-usb, linux-arm-msm, devicetree
On 24-11-13 07:03:38, Greg Kroah-Hartman wrote:
> On Tue, Nov 12, 2024 at 07:05:29PM +0200, Abel Vesa wrote:
> > On 24-11-12 19:01:13, Abel Vesa wrote:
> > > The X Elite CRD provides external DisplayPort on all 3 USB Type-C ports.
> > > Each one of this ports is connected to a dedicated DisplayPort
> > > controller.
> > >
> > > Due to support missing in the USB/DisplayPort combo PHY driver,
> > > the external DisplayPort is limited to 2 lanes.
> > >
> > > So enable all 3 remaining DisplayPort controllers and limit their data
> > > lanes number to 2.
> > >
> > > Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
> >
> > Please do not merge this specific patch.
>
> Please do not mix patches that should, and should not, be applied in the
> same series as that plays havoc with our tools that want to take a whole
> series at once. Stuff like this just makes me delete the whole series
> from my review queue, and if you got sent something like this, I imagine
> you would do the same :(
Sorry about that and for the late reply.
Will send the patches that are for testing purposes only as a separate
patchset.
>
> thanks,
>
> greg k-h
Thanks for reviewing,
Abel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer
2025-01-06 14:14 ` Abel Vesa
@ 2025-01-07 9:46 ` Johan Hovold
0 siblings, 0 replies; 18+ messages in thread
From: Johan Hovold @ 2025-01-07 9:46 UTC (permalink / raw)
To: Abel Vesa
Cc: Heikki Krogerus, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Rajendra Nayak, Sibi Sankar, Dmitry Baryshkov, Trilok Soni,
Christophe JAILLET, linux-kernel, linux-usb, linux-arm-msm,
devicetree
On Mon, Jan 06, 2025 at 04:14:39PM +0200, Abel Vesa wrote:
> On 24-12-04 17:24:54, Johan Hovold wrote:
> > On Tue, Nov 12, 2024 at 07:01:11PM +0200, Abel Vesa wrote:
> > > + /* skip resetting if already configured */
> > > + if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
> > > + CONN_STATUS_0_CONNECTION_PRESENT))
> > > + return 0;
> >
> > What if the device is held in reset? This looks like it only works if
> > the boot firmware has already enabled the retimer. Otherwise you may
> > return success from probe here with the retimer still in reset.
>
> Please correct me if I'm wrong, but if the read above fails or reads
> anything else than "connection present", then below we go through the
> resetting sequence. If it reads "connection present", then retimer can't
> be in reset.
regmap_test_bits() returns a negative errno if the read fails, so you
need to check that the return value is 1 here to avoid returning success
from probe on failure.
Johan
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-01-07 9:46 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-12 17:01 [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Abel Vesa
2024-11-12 17:01 ` [PATCH v5 1/6] dt-bindings: usb: Add Parade PS8830 Type-C retimer bindings Abel Vesa
2024-11-15 16:44 ` Rob Herring
2024-11-12 17:01 ` [PATCH v5 2/6] usb: typec: Add support for Parade PS8830 Type-C Retimer Abel Vesa
2024-12-04 16:24 ` Johan Hovold
2024-12-05 23:05 ` Bjorn Andersson
2024-12-07 21:45 ` Abel Vesa
2025-01-06 14:14 ` Abel Vesa
2025-01-07 9:46 ` Johan Hovold
2024-11-12 17:01 ` [PATCH v5 3/6] arm64: dts: qcom: x1e80100-crd: Describe the Parade PS8830 retimers Abel Vesa
2024-11-12 17:01 ` [PATCH v5 4/6] arm64: dts: qcom: x1e80100-crd: Enable external DisplayPort support Abel Vesa
2024-11-12 17:05 ` Abel Vesa
2024-11-13 6:03 ` Greg Kroah-Hartman
2025-01-06 14:24 ` Abel Vesa
2024-11-12 17:01 ` [PATCH v5 5/6] arm64: dts: qcom: x1e80100-t14s: Describe the Parade PS8830 retimers Abel Vesa
2024-11-12 17:01 ` [PATCH v5 6/6] arm64: dts: qcom: x1e80100-t14s: Enable external DisplayPort support Abel Vesa
2024-11-12 17:05 ` Abel Vesa
2024-11-15 15:13 ` [PATCH v5 0/6] usb: typec: Add new driver for Parade PS8830 Type-C Retimer Rob Herring (Arm)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).