* [PATCH v3 01/17] drm/atomic-helper: Introduce lane remapping support to bridges
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check Stephen Boyd
` (15 subsequent siblings)
16 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Add support to the DRM atomic logic to support lane remapping between
bridges, encoders and connectors. Typically lane mapping is handled
statically in firmware, e.g. on DT we use the data-lanes property to
assign lanes when connecting display bridges. Lane assignment is dynamic
with USB-C DisplayPort altmodes, e.g. pin conf D assigns 2 lanes of DP
to pins on the USB-C connector while pin conf C assigns 4 lanes of DP to
pins on the USB-C connector. The lane assignment can't be set statically
because the DP altmode repurposes USB-C pins for the DP lanes while also
limiting the number of DP lanes or their pin assignment at runtime.
Bridge drivers should point their 'struct drm_bus_cfg::lanes' pointer to
an allocated array of 'struct drm_lane_cfg' structures and indicate the
size of this allocated array with 'struct drm_bus_cfg::num_lanes' in
their atomic_check() callback. The previous bridge in the bridge chain
can look at this information by calling
drm_bridge_next_bridge_lane_cfg() in their atomic_check() callback to
figure out what lanes need to be logically assigned to the physical
output lanes to satisfy the next bridge's lane assignment.
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: <dri-devel@lists.freedesktop.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 2 ++
drivers/gpu/drm/drm_bridge.c | 34 +++++++++++++++++++++++
include/drm/drm_atomic.h | 31 +++++++++++++++++++++
include/drm/drm_bridge.h | 4 +++
4 files changed, 71 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 519228eb1095..12d574458e7b 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -779,6 +779,8 @@ EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
struct drm_bridge_state *state)
{
+ kfree(state->input_bus_cfg.lanes);
+ kfree(state->output_bus_cfg.lanes);
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index d44f055dbe3e..bd18c1e91dee 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -822,6 +822,40 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
+/**
+ * drm_bridge_next_bridge_lane_cfg - get the lane configuration of the next bridge
+ * @bridge: bridge control structure
+ * @state: new atomic state
+ * @num_lanes: will contain the size of the returned array
+ *
+ * This function is typically called from &drm_bridge_funcs.atomic_check().
+ * The @bridge driver calls this function to determine what the next bridge in
+ * the bridge chain requires for the physical to logical lane assignments.
+ *
+ * Return: Lane configuration array of size @num_lanes for the next bridge
+ * after @bridge in the bridge chain, or NULL if the lane configuration is
+ * unchanged from the default.
+ */
+const struct drm_lane_cfg *
+drm_bridge_next_bridge_lane_cfg(struct drm_bridge *bridge,
+ struct drm_atomic_state *state,
+ u8 *num_lanes)
+{
+ const struct drm_bridge_state *next_bridge_state;
+ struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
+
+ next_bridge_state = drm_atomic_get_new_bridge_state(state, next_bridge);
+ if (!next_bridge_state) {
+ *num_lanes = 0;
+ return NULL;
+ }
+
+ *num_lanes = next_bridge_state->input_bus_cfg.num_lanes;
+
+ return next_bridge_state->input_bus_cfg.lanes;
+}
+EXPORT_SYMBOL(drm_bridge_next_bridge_lane_cfg);
+
static int drm_atomic_bridge_check(struct drm_bridge *bridge,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 4d7f4c5f2001..e1a38d0742f1 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -1122,6 +1122,27 @@ drm_atomic_crtc_effectively_active(const struct drm_crtc_state *state)
return state->active || state->self_refresh_active;
}
+/**
+ * struct drm_lane_cfg - lane configuration
+ *
+ * This structure stores the lane configuration of a physical bus between
+ * two components in an output pipeline, usually between two bridges, an
+ * encoder and a bridge, or a bridge and a connector.
+ *
+ * The lane configuration is stored in &drm_bus_cfg.
+ */
+struct drm_lane_cfg {
+ /**
+ * @logical: Logical lane number
+ */
+ u8 logical;
+
+ /**
+ * @inverted: True if lane polarity is inverted, false otherwise
+ */
+ bool inverted;
+};
+
/**
* struct drm_bus_cfg - bus configuration
*
@@ -1152,6 +1173,16 @@ struct drm_bus_cfg {
* @flags: DRM_BUS_* flags used on this bus
*/
u32 flags;
+
+ /**
+ * @lanes: Lane mapping for this bus
+ */
+ struct drm_lane_cfg *lanes;
+
+ /**
+ * @num_lanes: Number of lanes in @lanes
+ */
+ u8 num_lanes;
};
/**
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 75019d16be64..064d3c8600a9 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -963,6 +963,10 @@ drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
struct drm_connector_state *conn_state,
u32 output_fmt,
unsigned int *num_input_fmts);
+const struct drm_lane_cfg *
+drm_bridge_next_bridge_lane_cfg(struct drm_bridge *bridge,
+ struct drm_atomic_state *state,
+ u8 *num_lanes);
enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge);
int drm_bridge_get_modes(struct drm_bridge *bridge,
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 01/17] drm/atomic-helper: Introduce lane remapping support to bridges Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:09 ` Andy Shevchenko
2024-08-19 22:38 ` [PATCH v3 03/17] usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n Stephen Boyd
` (14 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Verify during drm_atomic_bridge_check() that the lane assignment set in
a bridge's atomic_check() callback is going to be satisfied by the
previous bridge. If the next bridge is requiring something besides the
default 1:1 lane assignment on its input then there must be an output
lane assignment on the previous bridge's output. Otherwise the next
bridge won't get the lanes assigned that it needs.
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: <dri-devel@lists.freedesktop.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/drm_bridge.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index bd18c1e91dee..68c7a321b9b3 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -860,6 +860,10 @@ static int drm_atomic_bridge_check(struct drm_bridge *bridge,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
+ u8 num_input_lanes, num_output_lanes = 0;
+ const struct drm_lane_cfg *input_lanes;
+ int i;
+
if (bridge->funcs->atomic_check) {
struct drm_bridge_state *bridge_state;
int ret;
@@ -873,12 +877,24 @@ static int drm_atomic_bridge_check(struct drm_bridge *bridge,
crtc_state, conn_state);
if (ret)
return ret;
+ num_output_lanes = bridge_state->output_bus_cfg.num_lanes;
} else if (bridge->funcs->mode_fixup) {
if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode,
&crtc_state->adjusted_mode))
return -EINVAL;
}
+ input_lanes = drm_bridge_next_bridge_lane_cfg(bridge,
+ crtc_state->state,
+ &num_input_lanes);
+ /*
+ * Ensure this bridge is aware that the next bridge wants to
+ * reassign lanes.
+ */
+ for (i = 0; i < num_input_lanes; i++)
+ if (i != input_lanes[i].logical && !num_output_lanes)
+ return -ENOTSUPP;
+
return 0;
}
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-19 22:38 ` [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check Stephen Boyd
@ 2024-08-20 10:09 ` Andy Shevchenko
2024-08-20 17:12 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 10:09 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
> Verify during drm_atomic_bridge_check() that the lane assignment set in
> a bridge's atomic_check() callback is going to be satisfied by the
> previous bridge. If the next bridge is requiring something besides the
> default 1:1 lane assignment on its input then there must be an output
> lane assignment on the previous bridge's output. Otherwise the next
> bridge won't get the lanes assigned that it needs.
> Cc: Andrzej Hajda <andrzej.hajda@intel.com>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Robert Foss <rfoss@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: <dri-devel@lists.freedesktop.org>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Yeah, I really think that the appearance of this thousandth time in the Git
history has almost no value and just pollutes the commit message makes it not
very well readable. The only outcome is exercising the compression algo used
by Git.
...
> + int i;
unsigned?
...
> + /*
> + * Ensure this bridge is aware that the next bridge wants to
> + * reassign lanes.
> + */
> + for (i = 0; i < num_input_lanes; i++)
> + if (i != input_lanes[i].logical && !num_output_lanes)
> + return -ENOTSUPP;
Besides missing {} this code is internal to the Linux kernel. Is it okay?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-20 10:09 ` Andy Shevchenko
@ 2024-08-20 17:12 ` Stephen Boyd
2024-08-20 17:17 ` Andy Shevchenko
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:12 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 03:09:29)
> On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
> > Verify during drm_atomic_bridge_check() that the lane assignment set in
> > a bridge's atomic_check() callback is going to be satisfied by the
> > previous bridge. If the next bridge is requiring something besides the
> > default 1:1 lane assignment on its input then there must be an output
> > lane assignment on the previous bridge's output. Otherwise the next
> > bridge won't get the lanes assigned that it needs.
>
> > Cc: Andrzej Hajda <andrzej.hajda@intel.com>
> > Cc: Neil Armstrong <neil.armstrong@linaro.org>
> > Cc: Robert Foss <rfoss@kernel.org>
> > Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> > Cc: Jonas Karlman <jonas@kwiboo.se>
> > Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Maxime Ripard <mripard@kernel.org>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Cc: David Airlie <airlied@gmail.com>
> > Cc: Daniel Vetter <daniel@ffwll.ch>
> > Cc: <dri-devel@lists.freedesktop.org>
> > Cc: Pin-yen Lin <treapking@chromium.org>
> > Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>
> Yeah, I really think that the appearance of this thousandth time in the Git
> history has almost no value and just pollutes the commit message makes it not
> very well readable. The only outcome is exercising the compression algo used
> by Git.
I'll leave the decision up to the maintainers.
>
> ...
>
> > + /*
> > + * Ensure this bridge is aware that the next bridge wants to
> > + * reassign lanes.
> > + */
> > + for (i = 0; i < num_input_lanes; i++)
> > + if (i != input_lanes[i].logical && !num_output_lanes)
> > + return -ENOTSUPP;
>
> Besides missing {} this code is internal to the Linux kernel. Is it okay?
>
ENOTSUPP is used by select_bus_fmt_recursive() so I simply followed that
style.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-20 17:12 ` Stephen Boyd
@ 2024-08-20 17:17 ` Andy Shevchenko
2024-08-20 17:24 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 17:17 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Tue, Aug 20, 2024 at 10:12:55AM -0700, Stephen Boyd wrote:
> Quoting Andy Shevchenko (2024-08-20 03:09:29)
> > On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
...
> > Yeah, I really think that the appearance of this thousandth time in the Git
> > history has almost no value and just pollutes the commit message makes it not
> > very well readable. The only outcome is exercising the compression algo used
> > by Git.
>
> I'll leave the decision up to the maintainers.
Sure!
...
> > > + /*
> > > + * Ensure this bridge is aware that the next bridge wants to
> > > + * reassign lanes.
> > > + */
> > > + for (i = 0; i < num_input_lanes; i++)
> > > + if (i != input_lanes[i].logical && !num_output_lanes)
> > > + return -ENOTSUPP;
> >
> > Besides missing {} this code is internal to the Linux kernel. Is it okay?
>
> ENOTSUPP is used by select_bus_fmt_recursive() so I simply followed that
> style.
Okay, just be aware of that side effect of that code, also checkpatch may
complain (however it might be false positive).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-20 17:17 ` Andy Shevchenko
@ 2024-08-20 17:24 ` Stephen Boyd
2024-08-20 17:29 ` Andy Shevchenko
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:24 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 10:17:46)
> On Tue, Aug 20, 2024 at 10:12:55AM -0700, Stephen Boyd wrote:
> > Quoting Andy Shevchenko (2024-08-20 03:09:29)
> > > On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
> > > > + /*
> > > > + * Ensure this bridge is aware that the next bridge wants to
> > > > + * reassign lanes.
> > > > + */
> > > > + for (i = 0; i < num_input_lanes; i++)
> > > > + if (i != input_lanes[i].logical && !num_output_lanes)
> > > > + return -ENOTSUPP;
> > >
> > > Besides missing {} this code is internal to the Linux kernel. Is it okay?
> >
> > ENOTSUPP is used by select_bus_fmt_recursive() so I simply followed that
> > style.
>
> Okay, just be aware of that side effect of that code, also checkpatch may
> complain (however it might be false positive).
Yes checkpatch complained but didn't enlighten me. Please tell me the
side effect as I'm unaware!
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-20 17:24 ` Stephen Boyd
@ 2024-08-20 17:29 ` Andy Shevchenko
2024-08-20 17:33 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 17:29 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Tue, Aug 20, 2024 at 10:24:47AM -0700, Stephen Boyd wrote:
> Quoting Andy Shevchenko (2024-08-20 10:17:46)
> > On Tue, Aug 20, 2024 at 10:12:55AM -0700, Stephen Boyd wrote:
> > > Quoting Andy Shevchenko (2024-08-20 03:09:29)
> > > > On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
...
> > > > > + /*
> > > > > + * Ensure this bridge is aware that the next bridge wants to
> > > > > + * reassign lanes.
> > > > > + */
> > > > > + for (i = 0; i < num_input_lanes; i++)
> > > > > + if (i != input_lanes[i].logical && !num_output_lanes)
> > > > > + return -ENOTSUPP;
> > > >
> > > > Besides missing {} this code is internal to the Linux kernel. Is it okay?
> > >
> > > ENOTSUPP is used by select_bus_fmt_recursive() so I simply followed that
> > > style.
> >
> > Okay, just be aware of that side effect of that code, also checkpatch may
> > complain (however it might be false positive).
>
> Yes checkpatch complained but didn't enlighten me. Please tell me the
> side effect as I'm unaware!
I already told you above, if this code ever appears in user space it will be
printed as a number and very much confuse the user!
That's why usage of this code either has to be documented or be subsystem
_known_ practice (GPIO library comes to my mind as it uses it internally,\
but filters for user space).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check
2024-08-20 17:29 ` Andy Shevchenko
@ 2024-08-20 17:33 ` Stephen Boyd
0 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:33 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 10:29:41)
> On Tue, Aug 20, 2024 at 10:24:47AM -0700, Stephen Boyd wrote:
> > Quoting Andy Shevchenko (2024-08-20 10:17:46)
> > > On Tue, Aug 20, 2024 at 10:12:55AM -0700, Stephen Boyd wrote:
> > > > Quoting Andy Shevchenko (2024-08-20 03:09:29)
> > > > > On Mon, Aug 19, 2024 at 03:38:16PM -0700, Stephen Boyd wrote:
>
> ...
>
> > > > > > + /*
> > > > > > + * Ensure this bridge is aware that the next bridge wants to
> > > > > > + * reassign lanes.
> > > > > > + */
> > > > > > + for (i = 0; i < num_input_lanes; i++)
> > > > > > + if (i != input_lanes[i].logical && !num_output_lanes)
> > > > > > + return -ENOTSUPP;
> > > > >
> > > > > Besides missing {} this code is internal to the Linux kernel. Is it okay?
> > > >
> > > > ENOTSUPP is used by select_bus_fmt_recursive() so I simply followed that
> > > > style.
> > >
> > > Okay, just be aware of that side effect of that code, also checkpatch may
> > > complain (however it might be false positive).
> >
> > Yes checkpatch complained but didn't enlighten me. Please tell me the
> > side effect as I'm unaware!
>
> I already told you above, if this code ever appears in user space it will be
> printed as a number and very much confuse the user!
>
> That's why usage of this code either has to be documented or be subsystem
> _known_ practice (GPIO library comes to my mind as it uses it internally,\
> but filters for user space).
>
Ok, got it. Thanks!
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 03/17] usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 01/17] drm/atomic-helper: Introduce lane remapping support to bridges Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 02/17] drm/bridge: Verify lane assignment is going to work during atomic_check Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:12 ` Andy Shevchenko
2024-08-19 22:38 ` [PATCH v3 04/17] usb: typec: Add device managed typec_mux_register() Stephen Boyd
` (13 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Ease driver development by adding stubs for the typec_switch APIs when
CONFIG_TYPEC=n. Copy the same method used for the typec_mux APIs to be
consistent.
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
include/linux/usb/typec_mux.h | 42 ++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 2489a7857d8e..094585205264 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -24,16 +24,13 @@ struct typec_switch_desc {
void *drvdata;
};
+#if IS_ENABLED(CONFIG_TYPEC)
+
struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode);
void typec_switch_put(struct typec_switch *sw);
int typec_switch_set(struct typec_switch *sw,
enum typec_orientation orientation);
-static inline struct typec_switch *typec_switch_get(struct device *dev)
-{
- return fwnode_typec_switch_get(dev_fwnode(dev));
-}
-
struct typec_switch_dev *
typec_switch_register(struct device *parent,
const struct typec_switch_desc *desc);
@@ -42,6 +39,41 @@ void typec_switch_unregister(struct typec_switch_dev *sw);
void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data);
void *typec_switch_get_drvdata(struct typec_switch_dev *sw);
+#else
+
+static inline struct typec_switch *
+fwnode_typec_switch_get(struct fwnode_handle *fwnode)
+{
+ return NULL;
+}
+static inline void typec_switch_put(struct typec_switch *sw) {}
+static inline int typec_switch_set(struct typec_switch *sw,
+ enum typec_orientation orientation)
+{
+ return 0;
+}
+
+static inline struct typec_switch_dev *
+typec_switch_register(struct device *parent,
+ const struct typec_switch_desc *desc)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline void typec_switch_unregister(struct typec_switch_dev *sw) {}
+
+static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {}
+static inline void *typec_switch_get_drvdata(struct typec_switch_dev *sw)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+#endif /* CONFIG_TYPEC */
+
+static inline struct typec_switch *typec_switch_get(struct device *dev)
+{
+ return fwnode_typec_switch_get(dev_fwnode(dev));
+}
+
struct typec_mux_state {
struct typec_altmode *alt;
unsigned long mode;
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 03/17] usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n
2024-08-19 22:38 ` [PATCH v3 03/17] usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n Stephen Boyd
@ 2024-08-20 10:12 ` Andy Shevchenko
0 siblings, 0 replies; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 10:12 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:17PM -0700, Stephen Boyd wrote:
> Ease driver development by adding stubs for the typec_switch APIs when
> CONFIG_TYPEC=n. Copy the same method used for the typec_mux APIs to be
> consistent.
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: <linux-usb@vger.kernel.org>
> Cc: Pin-yen Lin <treapking@chromium.org>
Since it's not a DRM subsystem, can we move Cc after the --- line with the same
effect minus Git commit pollution?
...
> +#else
Do you need
#include <linux/err.h>
here? Or is it already included at the top of the file?
> +static inline struct typec_switch *
> +fwnode_typec_switch_get(struct fwnode_handle *fwnode)
> +{
> + return NULL;
> +}
> +static inline void typec_switch_put(struct typec_switch *sw) {}
> +static inline int typec_switch_set(struct typec_switch *sw,
> + enum typec_orientation orientation)
> +{
> + return 0;
> +}
> +
> +static inline struct typec_switch_dev *
> +typec_switch_register(struct device *parent,
> + const struct typec_switch_desc *desc)
> +{
> + return ERR_PTR(-EOPNOTSUPP);
> +}
> +static inline void typec_switch_unregister(struct typec_switch_dev *sw) {}
> +
> +static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {}
> +static inline void *typec_switch_get_drvdata(struct typec_switch_dev *sw)
> +{
> + return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +#endif /* CONFIG_TYPEC */
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 04/17] usb: typec: Add device managed typec_mux_register()
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (2 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 03/17] usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:14 ` Andy Shevchenko
2024-08-19 22:38 ` [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register() Stephen Boyd
` (12 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Simplify driver error paths by adding devm_typec_mux_register() which
will unregister the typec mux when the parent device is unbound.
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/usb/typec/mux.c | 37 +++++++++++++++++++++++++++++++++++
include/linux/usb/typec_mux.h | 7 +++++++
2 files changed, 44 insertions(+)
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 49926d6e72c7..65c60eb56428 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -457,6 +457,43 @@ void typec_mux_unregister(struct typec_mux_dev *mux_dev)
}
EXPORT_SYMBOL_GPL(typec_mux_unregister);
+static void devm_typec_mux_unregister(struct device *dev, void *mux_dev)
+{
+ typec_mux_unregister(*(struct typec_mux_dev **)mux_dev);
+}
+
+/** devm_typec_mux_register - resource managed typec_mux_register()
+ * @parent: Parent device
+ * @desc: Multiplexer description
+ *
+ * Register a typec mux and automatically unregister the typec mux
+ * when @parent is unbound from its driver.
+ *
+ * The arguments to this function are identical to typec_mux_register().
+ *
+ * Return: the typec_mux_dev structure on success, else an error pointer.
+ */
+struct typec_mux_dev *
+devm_typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
+{
+ struct typec_mux_dev **ptr, *mux_dev;
+
+ ptr = devres_alloc(devm_typec_mux_unregister, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ mux_dev = typec_mux_register(parent ,desc);
+ if (!IS_ERR(mux_dev)) {
+ *ptr = mux_dev;
+ devres_add(parent, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return mux_dev;
+}
+EXPORT_SYMBOL_GPL(devm_typec_mux_register);
+
void typec_mux_set_drvdata(struct typec_mux_dev *mux_dev, void *data)
{
dev_set_drvdata(&mux_dev->dev, data);
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 094585205264..c6f49756530d 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -98,6 +98,8 @@ int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state);
struct typec_mux_dev *
typec_mux_register(struct device *parent, const struct typec_mux_desc *desc);
+struct typec_mux_dev *
+devm_typec_mux_register(struct device *parent, const struct typec_mux_desc *desc);
void typec_mux_unregister(struct typec_mux_dev *mux);
void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data);
@@ -122,6 +124,11 @@ typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct typec_mux_dev *
+devm_typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
+{
+ return typec_mux_register(parent, desc);
+}
static inline void typec_mux_unregister(struct typec_mux_dev *mux) {}
static inline void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data) {}
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 04/17] usb: typec: Add device managed typec_mux_register()
2024-08-19 22:38 ` [PATCH v3 04/17] usb: typec: Add device managed typec_mux_register() Stephen Boyd
@ 2024-08-20 10:14 ` Andy Shevchenko
0 siblings, 0 replies; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 10:14 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:18PM -0700, Stephen Boyd wrote:
> Simplify driver error paths by adding devm_typec_mux_register() which
> will unregister the typec mux when the parent device is unbound.
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: <linux-usb@vger.kernel.org>
> Cc: Pin-yen Lin <treapking@chromium.org>
As per previous comment, move these after --- line
(hint: You may have it in your Git commit with --- line,
it will be removed on the receiver side by `git am`)
...
> +/** devm_typec_mux_register - resource managed typec_mux_register()
Wrong comment style.
> + * @parent: Parent device
> + * @desc: Multiplexer description
> + *
> + * Register a typec mux and automatically unregister the typec mux
> + * when @parent is unbound from its driver.
> + *
> + * The arguments to this function are identical to typec_mux_register().
> + *
> + * Return: the typec_mux_dev structure on success, else an error pointer.
> + */
> +struct typec_mux_dev *
> +devm_typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
> +{
> + struct typec_mux_dev **ptr, *mux_dev;
> +
> + ptr = devres_alloc(devm_typec_mux_unregister, sizeof(*ptr), GFP_KERNEL);
> + if (!ptr)
> + return ERR_PTR(-ENOMEM);
> +
> + mux_dev = typec_mux_register(parent ,desc);
> + if (!IS_ERR(mux_dev)) {
> + *ptr = mux_dev;
> + devres_add(parent, ptr);
> + } else {
> + devres_free(ptr);
> + }
What does prevent you from using devm_add_action_or_reset()?
> + return mux_dev;
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (3 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 04/17] usb: typec: Add device managed typec_mux_register() Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:16 ` Andy Shevchenko
2024-08-19 22:38 ` [PATCH v3 06/17] drm/bridge: aux-hpd: Support USB Type-C DP altmodes via DRM lane assignment Stephen Boyd
` (11 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Simplify driver error paths by adding devm_typec_switch_register() which
will unregister the typec switch when the parent device is unbound.
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/usb/typec/mux.c | 27 +++++++++++++++++++++++++++
include/linux/usb/typec_mux.h | 9 +++++++++
2 files changed, 36 insertions(+)
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 65c60eb56428..3531ab03bac4 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -235,6 +235,33 @@ void typec_switch_unregister(struct typec_switch_dev *sw_dev)
}
EXPORT_SYMBOL_GPL(typec_switch_unregister);
+static void devm_typec_switch_unregister(struct device *dev, void *switch_dev)
+{
+ typec_switch_unregister(*(struct typec_switch_dev **)switch_dev);
+}
+
+struct typec_switch_dev *
+devm_typec_switch_register(struct device *parent,
+ const struct typec_switch_desc *desc)
+{
+ struct typec_switch_dev **ptr, *switch_dev;
+
+ ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ switch_dev = typec_switch_register(parent ,desc);
+ if (!IS_ERR(switch_dev)) {
+ *ptr = switch_dev;
+ devres_add(parent, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return switch_dev;
+}
+EXPORT_SYMBOL_GPL(devm_typec_switch_register);
+
void typec_switch_set_drvdata(struct typec_switch_dev *sw_dev, void *data)
{
dev_set_drvdata(&sw_dev->dev, data);
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index c6f49756530d..fe7a05dd71c8 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -34,6 +34,9 @@ int typec_switch_set(struct typec_switch *sw,
struct typec_switch_dev *
typec_switch_register(struct device *parent,
const struct typec_switch_desc *desc);
+struct typec_switch_dev *
+devm_typec_switch_register(struct device *parent,
+ const struct typec_switch_desc *desc);
void typec_switch_unregister(struct typec_switch_dev *sw);
void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data);
@@ -59,6 +62,12 @@ typec_switch_register(struct device *parent,
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct typec_switch_dev *
+devm_typec_switch_register(struct device *parent,
+ const struct typec_switch_desc *desc)
+{
+ return typec_switch_register(parent, desc);
+}
static inline void typec_switch_unregister(struct typec_switch_dev *sw) {}
static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {}
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-19 22:38 ` [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register() Stephen Boyd
@ 2024-08-20 10:16 ` Andy Shevchenko
2024-08-20 17:01 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 10:16 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
> Simplify driver error paths by adding devm_typec_switch_register() which
> will unregister the typec switch when the parent device is unbound.
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: <linux-usb@vger.kernel.org>
> Cc: Pin-yen Lin <treapking@chromium.org>
As per previous patches.
...
> + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> + if (!ptr)
> + return ERR_PTR(-ENOMEM);
> +
> + switch_dev = typec_switch_register(parent ,desc);
> + if (!IS_ERR(switch_dev)) {
> + *ptr = switch_dev;
> + devres_add(parent, ptr);
> + } else {
> + devres_free(ptr);
> + }
devm_add_action_or_reset() ?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-20 10:16 ` Andy Shevchenko
@ 2024-08-20 17:01 ` Stephen Boyd
2024-08-20 17:16 ` Andy Shevchenko
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:01 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 03:16:09)
> On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
> > + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> > + if (!ptr)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + switch_dev = typec_switch_register(parent ,desc);
> > + if (!IS_ERR(switch_dev)) {
> > + *ptr = switch_dev;
> > + devres_add(parent, ptr);
> > + } else {
> > + devres_free(ptr);
> > + }
>
> devm_add_action_or_reset() ?
>
No. We don't want to call the 'action' devm_typec_switch_unregister()
when it fails because that would unregister a switch that has never been
registered.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-20 17:01 ` Stephen Boyd
@ 2024-08-20 17:16 ` Andy Shevchenko
2024-08-20 17:19 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 17:16 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Tue, Aug 20, 2024 at 10:01:07AM -0700, Stephen Boyd wrote:
> Quoting Andy Shevchenko (2024-08-20 03:16:09)
> > On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
> > > + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> > > + if (!ptr)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + switch_dev = typec_switch_register(parent ,desc);
(Side note: wrong location of the white space)
> > > + if (!IS_ERR(switch_dev)) {
(Side note: positive conditional is okay)
> > > + *ptr = switch_dev;
> > > + devres_add(parent, ptr);
> > > + } else {
> > > + devres_free(ptr);
> > > + }
> >
> > devm_add_action_or_reset() ?
>
> No. We don't want to call the 'action' devm_typec_switch_unregister()
> when it fails because that would unregister a switch that has never been
> registered.
Hmm... With devm_add_action_or_reset() we first do things and then try to add
them to the managed resources. In that case it won't be like you described.
What do I miss?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-20 17:16 ` Andy Shevchenko
@ 2024-08-20 17:19 ` Stephen Boyd
2024-08-20 17:23 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:19 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 10:16:40)
> On Tue, Aug 20, 2024 at 10:01:07AM -0700, Stephen Boyd wrote:
> > Quoting Andy Shevchenko (2024-08-20 03:16:09)
> > > On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
> > > > + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> > > > + if (!ptr)
> > > > + return ERR_PTR(-ENOMEM);
> > > > +
> > > > + switch_dev = typec_switch_register(parent ,desc);
>
> (Side note: wrong location of the white space)
Thanks.
>
> > > > + if (!IS_ERR(switch_dev)) {
>
> (Side note: positive conditional is okay)
>
> > > > + *ptr = switch_dev;
> > > > + devres_add(parent, ptr);
> > > > + } else {
> > > > + devres_free(ptr);
> > > > + }
> > >
> > > devm_add_action_or_reset() ?
> >
> > No. We don't want to call the 'action' devm_typec_switch_unregister()
> > when it fails because that would unregister a switch that has never been
> > registered.
>
> Hmm... With devm_add_action_or_reset() we first do things and then try to add
> them to the managed resources. In that case it won't be like you described.
>
> What do I miss?
>
I believe you've missed that this is a wrapper around struct device and
the error path is different (put_device() vs. device_unregister()).
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-20 17:19 ` Stephen Boyd
@ 2024-08-20 17:23 ` Stephen Boyd
2024-08-20 17:27 ` Andy Shevchenko
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:23 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Stephen Boyd (2024-08-20 10:19:48)
> Quoting Andy Shevchenko (2024-08-20 10:16:40)
> > On Tue, Aug 20, 2024 at 10:01:07AM -0700, Stephen Boyd wrote:
> > > Quoting Andy Shevchenko (2024-08-20 03:16:09)
> > > > On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
> > > > > + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> > > > > + if (!ptr)
> > > > > + return ERR_PTR(-ENOMEM);
> > > > > +
> > > > > + switch_dev = typec_switch_register(parent ,desc);
> >
> > (Side note: wrong location of the white space)
>
> Thanks.
>
> >
> > > > > + if (!IS_ERR(switch_dev)) {
> >
> > (Side note: positive conditional is okay)
> >
> > > > > + *ptr = switch_dev;
> > > > > + devres_add(parent, ptr);
> > > > > + } else {
> > > > > + devres_free(ptr);
> > > > > + }
> > > >
> > > > devm_add_action_or_reset() ?
> > >
> > > No. We don't want to call the 'action' devm_typec_switch_unregister()
> > > when it fails because that would unregister a switch that has never been
> > > registered.
> >
> > Hmm... With devm_add_action_or_reset() we first do things and then try to add
> > them to the managed resources. In that case it won't be like you described.
> >
> > What do I miss?
> >
>
> I believe you've missed that this is a wrapper around struct device and
> the error path is different (put_device() vs. device_unregister()).
Or you're suggesting devm_add_action_or_reset() after registering the
switch? Sorry it wasn't clear to me.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register()
2024-08-20 17:23 ` Stephen Boyd
@ 2024-08-20 17:27 ` Andy Shevchenko
0 siblings, 0 replies; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 17:27 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Tue, Aug 20, 2024 at 10:23:06AM -0700, Stephen Boyd wrote:
> Quoting Stephen Boyd (2024-08-20 10:19:48)
> > Quoting Andy Shevchenko (2024-08-20 10:16:40)
> > > On Tue, Aug 20, 2024 at 10:01:07AM -0700, Stephen Boyd wrote:
> > > > Quoting Andy Shevchenko (2024-08-20 03:16:09)
> > > > > On Mon, Aug 19, 2024 at 03:38:19PM -0700, Stephen Boyd wrote:
...
> > > > > > + ptr = devres_alloc(devm_typec_switch_unregister, sizeof(*ptr), GFP_KERNEL);
> > > > > > + if (!ptr)
> > > > > > + return ERR_PTR(-ENOMEM);
> > > > > > +
> > > > > > + switch_dev = typec_switch_register(parent ,desc);
> > >
> > > (Side note: wrong location of the white space)
> >
> > Thanks.
> >
> > >
> > > > > > + if (!IS_ERR(switch_dev)) {
> > >
> > > (Side note: positive conditional is okay)
> > >
> > > > > > + *ptr = switch_dev;
> > > > > > + devres_add(parent, ptr);
> > > > > > + } else {
> > > > > > + devres_free(ptr);
> > > > > > + }
> > > > >
> > > > > devm_add_action_or_reset() ?
> > > >
> > > > No. We don't want to call the 'action' devm_typec_switch_unregister()
> > > > when it fails because that would unregister a switch that has never been
> > > > registered.
> > >
> > > Hmm... With devm_add_action_or_reset() we first do things and then try to add
> > > them to the managed resources. In that case it won't be like you described.
> > >
> > > What do I miss?
> >
> > I believe you've missed that this is a wrapper around struct device and
> > the error path is different (put_device() vs. device_unregister()).
>
> Or you're suggesting devm_add_action_or_reset() after registering the
> switch? Sorry it wasn't clear to me.
Yes, after successful switch registration.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 06/17] drm/bridge: aux-hpd: Support USB Type-C DP altmodes via DRM lane assignment
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (4 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 05/17] usb: typec: Add device managed typec_switch_register() Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation Stephen Boyd
` (10 subsequent siblings)
16 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Extend the aux-hpd bridge driver to support assigning DP lanes to USB
type-c pins based on typec mux state entry. Existing users of this
driver only need the HPD signaling support, so leave that in place and
wrap the code with a variant that supports more features of USB type-c
DP altmode, i.e. pin configurations. Prefix that code with
'drm_dp_typec_bridge' to differentiate it from the existing
'drm_aux_hpd_bridge' code.
Parse the struct typec_mux_state members to determine if DP altmode has
been entered and if HPD is asserted or not. Signal HPD to the drm bridge
chain when HPD is asserted. Similarly, parse the pin assignment and map
the DP lanes to the usb-c output lanes, taking into account any lane
remapping from the data-lanes endpoint property. Pass that lane mapping
to the previous drm_bridge in the bridge chain during the atomic check
phase.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 476 +++++++++++++++++++++++-
include/drm/bridge/aux-bridge.h | 17 +
2 files changed, 481 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 6886db2d9e00..47315a8077a3 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -7,8 +7,14 @@
#include <linux/auxiliary_bus.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/usb/typec.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
+#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_bridge.h>
+#include <drm/drm_print.h>
#include <drm/bridge/aux-bridge.h>
static DEFINE_IDA(drm_aux_hpd_bridge_ida);
@@ -18,6 +24,80 @@ struct drm_aux_hpd_bridge_data {
struct device *dev;
};
+enum dp_lane {
+ DP_ML0 = 0, /* DP pins 1/3 */
+ DP_ML1 = 1, /* DP pins 4/6 */
+ DP_ML2 = 2, /* DP pins 7/9 */
+ DP_ML3 = 3, /* DP pins 10/12 */
+};
+
+#define NUM_DP_ML (DP_ML3 + 1)
+
+enum usb_ss_lane {
+ USB_SSRX1 = 0, /* Type-C pins B11/B10 */
+ USB_SSTX1 = 1, /* Type-C pins A2/A3 */
+ USB_SSTX2 = 2, /* Type-C pins A11/A10 */
+ USB_SSRX2 = 3, /* Type-C pins B2/B3 */
+};
+
+#define NUM_USB_SS (USB_SSRX2 + 1)
+
+struct drm_dp_typec_bridge_data;
+
+/**
+ * struct drm_dp_typec_bridge_typec_port - USB type-c port associated with DP bridge
+ * @lane_mapping: Physical (array index) to logical (array value) USB type-C lane mapping
+ * @mode_switch: DP altmode switch
+ * @typec_data: Back pointer to type-c bridge data
+ */
+struct drm_dp_typec_bridge_typec_port {
+ u32 lane_mapping[NUM_USB_SS];
+ struct typec_mux_dev *mode_switch;
+ struct drm_dp_typec_bridge_data *typec_data;
+};
+
+/**
+ * struct drm_dp_typec_bridge_data - DP over USB type-c drm_bridge
+ * @dp_lanes: Physical (array value) to logical (array index) DP lane mapping
+ * @num_lanes: Number of valid lanes in @dp_lanes
+ * @hpd_bridge: hpd_bridge data
+ */
+struct drm_dp_typec_bridge_data {
+ u8 dp_lanes[NUM_DP_ML];
+ size_t num_lanes;
+ struct drm_aux_hpd_bridge_data hpd_bridge;
+};
+
+static inline struct drm_dp_typec_bridge_data *
+hpd_bridge_to_typec_bridge_data(struct drm_aux_hpd_bridge_data *hpd_data)
+{
+ return container_of(hpd_data, struct drm_dp_typec_bridge_data, hpd_bridge);
+}
+
+static inline struct drm_dp_typec_bridge_data *
+to_drm_dp_typec_bridge_data(struct drm_bridge *bridge)
+{
+ struct drm_aux_hpd_bridge_data *hpd_data;
+
+ hpd_data = container_of(bridge, struct drm_aux_hpd_bridge_data, bridge);
+
+ return hpd_bridge_to_typec_bridge_data(hpd_data);
+}
+
+struct drm_dp_typec_bridge_dev {
+ struct auxiliary_device adev;
+ size_t max_lanes;
+ size_t num_typec_ports;
+};
+
+static inline struct drm_dp_typec_bridge_dev *
+to_drm_dp_typec_bridge_dev(struct device *dev)
+{
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+ return container_of(adev, struct drm_dp_typec_bridge_dev, adev);
+}
+
static void drm_aux_hpd_bridge_release(struct device *dev)
{
struct auxiliary_device *adev = to_auxiliary_dev(dev);
@@ -30,6 +110,22 @@ static void drm_aux_hpd_bridge_release(struct device *dev)
kfree(adev);
}
+static void drm_dp_typec_bridge_release(struct device *dev)
+{
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev;
+ struct auxiliary_device *adev;
+
+ typec_bridge_dev = to_drm_dp_typec_bridge_dev(dev);
+ adev = &typec_bridge_dev->adev;
+
+ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
+
+ of_node_put(adev->dev.platform_data);
+ of_node_put(adev->dev.of_node);
+
+ kfree(typec_bridge_dev);
+}
+
static void drm_aux_hpd_bridge_free_adev(void *_adev)
{
auxiliary_device_uninit(_adev);
@@ -133,6 +229,111 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_n
}
EXPORT_SYMBOL_GPL(drm_dp_hpd_bridge_register);
+/**
+ * devm_drm_dp_typec_bridge_alloc - Allocate a USB type-c DisplayPort bridge
+ * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
+ *
+ * Creates a DRM bridge with the type set to DRM_MODE_CONNECTOR_DisplayPort,
+ * which terminates the bridge chain and is able to send the HPD events along
+ * with remap DP lanes to match USB type-c DP altmode pin assignments.
+ *
+ * Return: device instance that will handle created bridge or an error code
+ * encoded into the pointer.
+ */
+struct drm_dp_typec_bridge_dev *
+devm_drm_dp_typec_bridge_alloc(struct device *parent, struct device_node *np)
+{
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev;
+ struct auxiliary_device *adev;
+ int ret, num_dp_lanes;
+ struct device_node *dp_ep __free(device_node) = NULL;
+ struct device_node *remote_ep;
+ struct device_node *ep_node;
+ struct of_endpoint ep;
+
+ typec_bridge_dev = kzalloc(sizeof(*typec_bridge_dev), GFP_KERNEL);
+ if (!typec_bridge_dev)
+ return ERR_PTR(-ENOMEM);
+ adev = &typec_bridge_dev->adev;
+
+ for_each_endpoint_of_node(np, ep_node) {
+ of_graph_parse_endpoint(ep_node, &ep);
+ /* Only consider available endpoints */
+ if (!of_device_is_available(ep_node))
+ continue;
+ /* Only consider connected nodes */
+ remote_ep = of_graph_get_remote_endpoint(ep_node);
+ of_node_put(remote_ep);
+ if (!remote_ep)
+ continue;
+
+ if (ep.port == 2)
+ dp_ep = of_node_get(ep_node);
+ else if (ep.port == 0)
+ typec_bridge_dev->num_typec_ports++;
+ }
+
+ if (!typec_bridge_dev->num_typec_ports) {
+ kfree(adev);
+ return ERR_PTR(dev_err_probe(parent, -ENODEV, "Missing typec endpoint(s) port@0\n"));
+ }
+
+ if (!dp_ep) {
+ kfree(adev);
+ return ERR_PTR(dev_err_probe(parent, -ENODEV, "Missing DP endpoint port@2\n"));
+ }
+
+ num_dp_lanes = of_property_count_u32_elems(dp_ep, "data-lanes");
+ if (num_dp_lanes < 0)
+ num_dp_lanes = NUM_DP_ML;
+
+ typec_bridge_dev->max_lanes = num_dp_lanes;
+
+ ret = ida_alloc(&drm_aux_hpd_bridge_ida, GFP_KERNEL);
+ if (ret < 0) {
+ kfree(adev);
+ return ERR_PTR(ret);
+ }
+
+ adev->id = ret;
+ adev->name = "dp_typec_bridge";
+ adev->dev.parent = parent;
+ adev->dev.of_node = of_node_get(parent->of_node);
+ adev->dev.release = drm_dp_typec_bridge_release;
+ adev->dev.platform_data = of_node_get(np);
+ ret = auxiliary_device_init(adev);
+ if (ret) {
+ of_node_put(adev->dev.platform_data);
+ of_node_put(adev->dev.of_node);
+ ida_free(&drm_aux_hpd_bridge_ida, adev->id);
+ kfree(adev);
+ return ERR_PTR(ret);
+ }
+
+ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_free_adev, adev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return typec_bridge_dev;
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_typec_bridge_alloc);
+
+/**
+ * devm_drm_dp_typec_bridge_add - register a USB type-c DisplayPort bridge
+ * @dev: struct device to tie registration lifetime to
+ * @typec_bridge_dev: USB type-c DisplayPort bridge to be registered
+ *
+ * Returns: zero on success or a negative errno
+ */
+int devm_drm_dp_typec_bridge_add(struct device *dev, struct drm_dp_typec_bridge_dev *typec_bridge_dev)
+{
+ struct auxiliary_device *adev = &typec_bridge_dev->adev;
+
+ return devm_drm_dp_hpd_bridge_add(dev, adev);
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_typec_bridge_add);
+
/**
* drm_aux_hpd_bridge_notify - notify hot plug detection events
* @dev: device created for the HPD bridge
@@ -161,32 +362,283 @@ static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge,
return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
}
+static int dp_lane_to_typec_lane(enum dp_lane lane)
+{
+ switch (lane) {
+ case DP_ML0:
+ return USB_SSTX2;
+ case DP_ML1:
+ return USB_SSRX2;
+ case DP_ML2:
+ return USB_SSTX1;
+ case DP_ML3:
+ return USB_SSRX1;
+ }
+
+ return -EINVAL;
+}
+
+static int typec_to_dp_lane(enum usb_ss_lane lane)
+{
+ switch (lane) {
+ case USB_SSRX1:
+ return DP_ML3;
+ case USB_SSTX1:
+ return DP_ML2;
+ case USB_SSTX2:
+ return DP_ML0;
+ case USB_SSRX2:
+ return DP_ML1;
+ }
+
+ return -EINVAL;
+}
+
+/**
+ * drm_dp_typec_bridge_assign_pins - Assign DisplayPort (DP) lanes to USB type-c pins
+ * @typec_bridge_dev: Device created for the type-c bridge
+ * @conf: DisplayPort altmode configure command VDO content
+ * @port: The USB type-c output port to assign pins to
+ *
+ * Assign DP lanes to the @port's USB type-c pins for the DP altmode
+ * configuration @conf, while taking into account the USB type-c lane_mapping.
+ * Future atomic checks on this bridge will request the lane assignment from
+ * the previous bridge so that the DP signal is sent to the assigned USB type-c
+ * pins.
+ *
+ * Return: 0 on success, negative value for failure.
+ */
+static int
+drm_dp_typec_bridge_assign_pins(struct drm_dp_typec_bridge_dev *typec_bridge_dev,
+ u32 conf,
+ struct drm_dp_typec_bridge_typec_port *port)
+{
+ enum usb_ss_lane *lane_mapping = port->lane_mapping;
+ struct auxiliary_device *adev = &typec_bridge_dev->adev;
+ struct drm_aux_hpd_bridge_data *hpd_data = auxiliary_get_drvdata(adev);
+ struct drm_dp_typec_bridge_data *data;
+ u8 *dp_lanes;
+ size_t num_lanes, max_lanes;
+ int i, typec_lane;
+ u8 pin_assign;
+
+ if (!hpd_data)
+ return -EINVAL;
+
+ data = hpd_bridge_to_typec_bridge_data(hpd_data);
+ dp_lanes = data->dp_lanes;
+
+ pin_assign = DP_CONF_GET_PIN_ASSIGN(conf);
+ if (pin_assign == DP_PIN_ASSIGN_D)
+ num_lanes = 2;
+ else
+ num_lanes = 4;
+ max_lanes = typec_bridge_dev->max_lanes;
+ data->num_lanes = num_lanes = min(num_lanes, max_lanes);
+
+ for (i = 0; i < num_lanes; i++) {
+ /* Get physical type-c lane for DP lane */
+ typec_lane = dp_lane_to_typec_lane(i);
+ if (typec_lane < 0) {
+ dev_err(&adev->dev, "Invalid type-c lane configuration at DP_ML%d\n", i);
+ return -EINVAL;
+ }
+
+ /* Map physical to logical type-c lane */
+ typec_lane = lane_mapping[typec_lane];
+
+ /* Map logical type-c lane to logical DP lane */
+ dp_lanes[i] = typec_to_dp_lane(typec_lane);
+ }
+
+ return 0;
+}
+
+static int drm_dp_typec_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_dp_typec_bridge_data *data;
+ struct drm_lane_cfg *in_lanes;
+ u8 *dp_lanes;
+ size_t num_lanes;
+ int i;
+
+ data = to_drm_dp_typec_bridge_data(bridge);
+ num_lanes = data->num_lanes;
+ if (!num_lanes)
+ return 0;
+ dp_lanes = data->dp_lanes;
+
+ in_lanes = kcalloc(num_lanes, sizeof(*in_lanes), GFP_KERNEL);
+ if (!in_lanes)
+ return -ENOMEM;
+
+ bridge_state->input_bus_cfg.lanes = in_lanes;
+ bridge_state->input_bus_cfg.num_lanes = num_lanes;
+
+ for (i = 0; i < num_lanes; i++)
+ in_lanes[i].logical = dp_lanes[i];
+
+ return 0;
+}
+
static const struct drm_bridge_funcs drm_aux_hpd_bridge_funcs = {
.attach = drm_aux_hpd_bridge_attach,
};
+static const struct drm_bridge_funcs drm_dp_typec_bridge_funcs = {
+ .attach = drm_aux_hpd_bridge_attach,
+ .atomic_check = drm_dp_typec_bridge_atomic_check,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+};
+
+static int
+drm_dp_typec_bridge_mode_switch_set(struct typec_mux_dev *mode_switch,
+ struct typec_mux_state *state)
+{
+ struct drm_dp_typec_bridge_typec_port *port;
+ const struct typec_displayport_data *dp_data;
+ struct drm_dp_typec_bridge_data *typec_data;
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev;
+ struct device *dev;
+ int ret;
+ enum drm_connector_status status;
+
+ port = typec_mux_get_drvdata(mode_switch);
+ typec_data = port->typec_data;
+ dev = typec_data->hpd_bridge.dev;
+ typec_bridge_dev = to_drm_dp_typec_bridge_dev(dev);
+
+ if (state->mode == TYPEC_STATE_SAFE || state->mode == TYPEC_STATE_USB) {
+ drm_aux_hpd_bridge_notify(dev, connector_status_disconnected);
+ } else if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
+ dp_data = state->data;
+ ret = drm_dp_typec_bridge_assign_pins(typec_bridge_dev, state->mode, port);
+ if (ret)
+ return ret;
+
+ if (dp_data->status & DP_STATUS_HPD_STATE)
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ drm_aux_hpd_bridge_notify(dev, status);
+ }
+
+ return 0;
+}
+
+static int
+drm_dp_typec_bridge_probe_typec_ports(struct drm_dp_typec_bridge_data *typec_data,
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev,
+ struct device_node *np)
+{
+ struct device *dev = &typec_bridge_dev->adev.dev;
+ struct device_node *typec_ep, *remote_ep;
+ struct of_endpoint ep;
+ const u32 mapping[] = { 0, 1, 2, 3 };
+ struct drm_dp_typec_bridge_typec_port *port;
+ size_t num_ports = typec_bridge_dev->num_typec_ports;
+ struct typec_mux_desc mode_switch_desc = { };
+ struct fwnode_handle *fwnode;
+
+ port = devm_kcalloc(dev, num_ports, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ for_each_endpoint_of_node(np, typec_ep) {
+ of_graph_parse_endpoint(typec_ep, &ep);
+ /* Only look at the usbc output port (port@0) */
+ if (ep.port != 0)
+ continue;
+ /* Only consider available endpoints */
+ if (!of_device_is_available(typec_ep))
+ continue;
+ /* Only consider connected nodes */
+ remote_ep = of_graph_get_remote_endpoint(typec_ep);
+ of_node_put(remote_ep);
+ if (!remote_ep)
+ continue;
+
+ port->typec_data = typec_data;
+ if (of_property_read_u32_array(ep.local_node, "data-lanes",
+ port->lane_mapping,
+ ARRAY_SIZE(port->lane_mapping))) {
+ memcpy(port->lane_mapping, mapping, sizeof(mapping));
+ }
+
+ fwnode = of_fwnode_handle(typec_ep);
+
+ mode_switch_desc.set = drm_dp_typec_bridge_mode_switch_set;
+ mode_switch_desc.fwnode = fwnode;
+ mode_switch_desc.name = fwnode_get_name(fwnode);
+ mode_switch_desc.drvdata = port;
+ port->mode_switch = devm_typec_mux_register(dev, &mode_switch_desc);
+ if (IS_ERR(port->mode_switch))
+ return PTR_ERR(port->mode_switch);
+
+ port++;
+ }
+
+ return 0;
+}
+
+enum drm_aux_bridge_type {
+ DRM_AUX_HPD_BRIDGE,
+ DRM_AUX_TYPEC_BRIDGE,
+};
+
static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
const struct auxiliary_device_id *id)
{
- struct drm_aux_hpd_bridge_data *data;
+ struct device *dev = &auxdev->dev;
+ struct drm_aux_hpd_bridge_data *hpd_data;
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev;
+ struct drm_dp_typec_bridge_data *typec_data;
+ struct drm_bridge *bridge;
+ struct device_node *np = dev_get_platdata(dev);
+ u8 dp_lanes[] = { DP_ML0, DP_ML1, DP_ML2, DP_ML3 };
+ int ret;
- data = devm_kzalloc(&auxdev->dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
+ if (id->driver_data == DRM_AUX_HPD_BRIDGE) {
+ hpd_data = devm_kzalloc(dev, sizeof(*hpd_data), GFP_KERNEL);
+ if (!hpd_data)
+ return -ENOMEM;
+ bridge = &hpd_data->bridge;
+ bridge->funcs = &drm_aux_hpd_bridge_funcs;
+ } else if (id->driver_data == DRM_AUX_TYPEC_BRIDGE) {
+ typec_data = devm_kzalloc(dev, sizeof(*typec_data), GFP_KERNEL);
+ if (!typec_data)
+ return -ENOMEM;
+ hpd_data = &typec_data->hpd_bridge;
+ bridge = &hpd_data->bridge;
+ bridge->funcs = &drm_dp_typec_bridge_funcs;
+ typec_bridge_dev = to_drm_dp_typec_bridge_dev(dev);
+ memcpy(typec_data->dp_lanes, dp_lanes, sizeof(typec_data->dp_lanes));
+ ret = drm_dp_typec_bridge_probe_typec_ports(typec_data, typec_bridge_dev, np);
+ if (ret)
+ return ret;
+ } else {
+ return -ENODEV;
+ }
- data->dev = &auxdev->dev;
- data->bridge.funcs = &drm_aux_hpd_bridge_funcs;
- data->bridge.of_node = dev_get_platdata(data->dev);
- data->bridge.ops = DRM_BRIDGE_OP_HPD;
- data->bridge.type = id->driver_data;
+ hpd_data->dev = dev;
+ bridge->of_node = dev_get_platdata(dev);
+ bridge->ops = DRM_BRIDGE_OP_HPD;
+ bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
- auxiliary_set_drvdata(auxdev, data);
+ auxiliary_set_drvdata(auxdev, hpd_data);
- return devm_drm_bridge_add(data->dev, &data->bridge);
+ return devm_drm_bridge_add(dev, bridge);
}
static const struct auxiliary_device_id drm_aux_hpd_bridge_table[] = {
- { .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_MODE_CONNECTOR_DisplayPort, },
+ { .name = KBUILD_MODNAME ".dp_hpd_bridge", .driver_data = DRM_AUX_HPD_BRIDGE, },
+ { .name = KBUILD_MODNAME ".dp_typec_bridge", .driver_data = DRM_AUX_TYPEC_BRIDGE, },
{},
};
MODULE_DEVICE_TABLE(auxiliary, drm_aux_hpd_bridge_table);
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c2f5a855512f..73fc8582ec07 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -20,12 +20,17 @@ static inline int drm_aux_bridge_register(struct device *parent)
}
#endif
+struct drm_dp_typec_bridge_dev;
+
#if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np);
int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np);
void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
+struct drm_dp_typec_bridge_dev *devm_drm_dp_typec_bridge_alloc(struct device *parent,
+ struct device_node *np);
+int devm_drm_dp_typec_bridge_add(struct device *dev, struct drm_dp_typec_bridge_dev *typec_bridge_dev);
#else
static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
struct device_node *np)
@@ -44,6 +49,18 @@ static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
return NULL;
}
+static inline struct drm_dp_typec_bridge_dev *
+devm_drm_dp_typec_bridge_alloc(struct device *parent, struct device_node *np)
+{
+ return NULL;
+}
+
+static inline int devm_drm_dp_typec_bridge_add(struct device *dev,
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev)
+{
+ return 0;
+}
+
static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
{
}
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (5 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 06/17] drm/bridge: aux-hpd: Support USB Type-C DP altmodes via DRM lane assignment Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 8:02 ` kernel test robot
2024-08-19 22:38 ` [PATCH v3 08/17] drm/bridge: dp_typec: Add "no-hpd" support Stephen Boyd
` (9 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Register an orientation switch for each type-c output node to support
flipping the lane mapping when the port is in reverse orientation. Only
do this when the orientation-switch property is present. This is mostly
useful for the case where the DP lanes are directly connected to the
usb-c-connector and the device doesn't have an orientation switch wired
down on the board between the connector and the DP controller.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 74 +++++++++++++++++++++----
1 file changed, 63 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 47315a8077a3..3d33f7936cbc 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -47,12 +47,15 @@ struct drm_dp_typec_bridge_data;
/**
* struct drm_dp_typec_bridge_typec_port - USB type-c port associated with DP bridge
* @lane_mapping: Physical (array index) to logical (array value) USB type-C lane mapping
+ * @orientation: Orientation of USB type-c port
* @mode_switch: DP altmode switch
* @typec_data: Back pointer to type-c bridge data
*/
struct drm_dp_typec_bridge_typec_port {
u32 lane_mapping[NUM_USB_SS];
+ enum typec_orientation orientation;
struct typec_mux_dev *mode_switch;
+ struct typec_switch_dev *orientation_switch;
struct drm_dp_typec_bridge_data *typec_data;
};
@@ -378,17 +381,35 @@ static int dp_lane_to_typec_lane(enum dp_lane lane)
return -EINVAL;
}
-static int typec_to_dp_lane(enum usb_ss_lane lane)
+static int typec_to_dp_lane(enum usb_ss_lane lane,
+ enum typec_orientation orientation)
{
- switch (lane) {
- case USB_SSRX1:
- return DP_ML3;
- case USB_SSTX1:
- return DP_ML2;
- case USB_SSTX2:
- return DP_ML0;
- case USB_SSRX2:
- return DP_ML1;
+ switch (orientation) {
+ case TYPEC_ORIENTATION_NONE:
+ case TYPEC_ORIENTATION_NORMAL:
+ switch (lane) {
+ case USB_SSRX1:
+ return DP_ML3;
+ case USB_SSTX1:
+ return DP_ML2;
+ case USB_SSTX2:
+ return DP_ML0;
+ case USB_SSRX2:
+ return DP_ML1;
+ }
+ break;
+ case TYPEC_ORIENTATION_REVERSE:
+ switch (lane) {
+ case USB_SSRX1:
+ return DP_ML0;
+ case USB_SSTX1:
+ return DP_ML1;
+ case USB_SSTX2:
+ return DP_ML3;
+ case USB_SSRX2:
+ return DP_ML2;
+ }
+ break;
}
return -EINVAL;
@@ -413,6 +434,7 @@ drm_dp_typec_bridge_assign_pins(struct drm_dp_typec_bridge_dev *typec_bridge_dev
u32 conf,
struct drm_dp_typec_bridge_typec_port *port)
{
+ enum typec_orientation orientation = port->orientation;
enum usb_ss_lane *lane_mapping = port->lane_mapping;
struct auxiliary_device *adev = &typec_bridge_dev->adev;
struct drm_aux_hpd_bridge_data *hpd_data = auxiliary_get_drvdata(adev);
@@ -448,7 +470,7 @@ drm_dp_typec_bridge_assign_pins(struct drm_dp_typec_bridge_dev *typec_bridge_dev
typec_lane = lane_mapping[typec_lane];
/* Map logical type-c lane to logical DP lane */
- dp_lanes[i] = typec_to_dp_lane(typec_lane);
+ dp_lanes[i] = typec_to_dp_lane(typec_lane, orientation);
}
return 0;
@@ -496,6 +518,23 @@ static const struct drm_bridge_funcs drm_dp_typec_bridge_funcs = {
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
};
+static int drm_dp_typec_bridge_orientation_set(struct typec_switch_dev *sw,
+ enum typec_orientation orientation)
+{
+ struct drm_dp_typec_bridge_typec_port *port;
+
+ /*
+ * Lane remapping is in drm_dp_typec_bridge_mode_switch_set(). Whenever
+ * an orientation changes the mode will switch in and out of DP mode,
+ * HPD will deassert and reassert so that
+ * drm_dp_typec_bridge_atomic_check() sees the proper state.
+ */
+ port = typec_switch_get_drvdata(sw);
+ port->orientation = orientation;
+
+ return 0;
+}
+
static int
drm_dp_typec_bridge_mode_switch_set(struct typec_mux_dev *mode_switch,
struct typec_mux_state *state)
@@ -544,7 +583,9 @@ drm_dp_typec_bridge_probe_typec_ports(struct drm_dp_typec_bridge_data *typec_dat
struct drm_dp_typec_bridge_typec_port *port;
size_t num_ports = typec_bridge_dev->num_typec_ports;
struct typec_mux_desc mode_switch_desc = { };
+ struct typec_switch_desc orientation_switch_desc = { };
struct fwnode_handle *fwnode;
+ bool orientation = of_property_read_bool(np, "orientation-switch");
port = devm_kcalloc(dev, num_ports, sizeof(*port), GFP_KERNEL);
if (!port)
@@ -581,6 +622,17 @@ drm_dp_typec_bridge_probe_typec_ports(struct drm_dp_typec_bridge_data *typec_dat
if (IS_ERR(port->mode_switch))
return PTR_ERR(port->mode_switch);
+ if (orientation) {
+ orientation_switch_desc.set = drm_dp_typec_bridge_orientation_set,
+ orientation_switch_desc.fwnode = fwnode;
+ orientation_switch_desc.drvdata = port;
+ orientation_switch_desc.name = fwnode_get_name(fwnode);
+ port->orientation_switch = typec_switch_register(dev,
+ &orientation_switch_desc);
+ if (IS_ERR(port->orientation_switch))
+ return PTR_ERR(port->orientation_switch);
+ }
+
port++;
}
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation
2024-08-19 22:38 ` [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation Stephen Boyd
@ 2024-08-20 8:02 ` kernel test robot
0 siblings, 0 replies; 49+ messages in thread
From: kernel test robot @ 2024-08-20 8:02 UTC (permalink / raw)
To: Stephen Boyd, chrome-platform
Cc: oe-kbuild-all, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Andy Shevchenko, Daniel Scally
Hi Stephen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 8400291e289ee6b2bf9779ff1c83a291501f017b]
url: https://github.com/intel-lab-lkp/linux/commits/Stephen-Boyd/drm-atomic-helper-Introduce-lane-remapping-support-to-bridges/20240820-064107
base: 8400291e289ee6b2bf9779ff1c83a291501f017b
patch link: https://lore.kernel.org/r/20240819223834.2049862-8-swboyd%40chromium.org
patch subject: [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20240820/202408201530.jPGxBSCk-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240820/202408201530.jPGxBSCk-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408201530.jPGxBSCk-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/gpu/drm/bridge/aux-hpd-bridge.c:60: warning: Function parameter or struct member 'orientation_switch' not described in 'drm_dp_typec_bridge_typec_port'
vim +60 drivers/gpu/drm/bridge/aux-hpd-bridge.c
c77d47cea15ad1 Stephen Boyd 2024-08-19 46
c77d47cea15ad1 Stephen Boyd 2024-08-19 47 /**
c77d47cea15ad1 Stephen Boyd 2024-08-19 48 * struct drm_dp_typec_bridge_typec_port - USB type-c port associated with DP bridge
c77d47cea15ad1 Stephen Boyd 2024-08-19 49 * @lane_mapping: Physical (array index) to logical (array value) USB type-C lane mapping
9edcc62024ff61 Stephen Boyd 2024-08-19 50 * @orientation: Orientation of USB type-c port
c77d47cea15ad1 Stephen Boyd 2024-08-19 51 * @mode_switch: DP altmode switch
c77d47cea15ad1 Stephen Boyd 2024-08-19 52 * @typec_data: Back pointer to type-c bridge data
c77d47cea15ad1 Stephen Boyd 2024-08-19 53 */
c77d47cea15ad1 Stephen Boyd 2024-08-19 54 struct drm_dp_typec_bridge_typec_port {
c77d47cea15ad1 Stephen Boyd 2024-08-19 55 u32 lane_mapping[NUM_USB_SS];
9edcc62024ff61 Stephen Boyd 2024-08-19 56 enum typec_orientation orientation;
c77d47cea15ad1 Stephen Boyd 2024-08-19 57 struct typec_mux_dev *mode_switch;
9edcc62024ff61 Stephen Boyd 2024-08-19 58 struct typec_switch_dev *orientation_switch;
c77d47cea15ad1 Stephen Boyd 2024-08-19 59 struct drm_dp_typec_bridge_data *typec_data;
c77d47cea15ad1 Stephen Boyd 2024-08-19 @60 };
c77d47cea15ad1 Stephen Boyd 2024-08-19 61
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 08/17] drm/bridge: dp_typec: Add "no-hpd" support
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (6 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 07/17] drm/bridge: dp_typec: Support USB Type-C orientation Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path Stephen Boyd
` (8 subsequent siblings)
16 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Add support for HPD coming from somewhere else in the drm_bridge chain.
Skip signaling HPD sate when "no-hpd" is present in the DT node backing
the dp_typec bridge.
Add this support because some EC firmwares on Trogdor/Strongbad boards
don't properly indicate the state of the DP HPD level on a type-c port.
The EC only indicates that DP mode is entered or exited for a type-c
port. The HPD level is expressed to the DP controller via a pin on the
AP that the EC drives high or low when the type-c port partner (i.e.
monitor) asserts or deasserts HPD.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 3d33f7936cbc..adafda4f128f 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -22,6 +22,7 @@ static DEFINE_IDA(drm_aux_hpd_bridge_ida);
struct drm_aux_hpd_bridge_data {
struct drm_bridge bridge;
struct device *dev;
+ bool no_hpd;
};
enum dp_lane {
@@ -354,6 +355,8 @@ void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status sta
if (!data)
return;
+ if (data->no_hpd)
+ return;
drm_bridge_hpd_notify(&data->bridge, status);
}
@@ -662,6 +665,7 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
return -ENOMEM;
bridge = &hpd_data->bridge;
bridge->funcs = &drm_aux_hpd_bridge_funcs;
+ bridge->ops = DRM_BRIDGE_OP_HPD;
} else if (id->driver_data == DRM_AUX_TYPEC_BRIDGE) {
typec_data = devm_kzalloc(dev, sizeof(*typec_data), GFP_KERNEL);
if (!typec_data)
@@ -670,6 +674,9 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
bridge = &hpd_data->bridge;
bridge->funcs = &drm_dp_typec_bridge_funcs;
typec_bridge_dev = to_drm_dp_typec_bridge_dev(dev);
+ hpd_data->no_hpd = of_property_read_bool(np, "no-hpd");
+ if (!hpd_data->no_hpd)
+ bridge->ops = DRM_BRIDGE_OP_HPD;
memcpy(typec_data->dp_lanes, dp_lanes, sizeof(typec_data->dp_lanes));
ret = drm_dp_typec_bridge_probe_typec_ports(typec_data, typec_bridge_dev, np);
if (ret)
@@ -679,8 +686,7 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev,
}
hpd_data->dev = dev;
- bridge->of_node = dev_get_platdata(dev);
- bridge->ops = DRM_BRIDGE_OP_HPD;
+ bridge->of_node = np;
bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
auxiliary_set_drvdata(auxdev, hpd_data);
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (7 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 08/17] drm/bridge: dp_typec: Add "no-hpd" support Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:06 ` kernel test robot
2024-08-19 22:38 ` [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher Stephen Boyd
` (7 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
The previous patch added support for no-hpd to drm_dp_typec_bridge code.
Allow users of this bridge to hook the HPD notification path of the
bridge chain so that they can be made aware of the connector status
changing. This helps HPD-less users of the bridge inject the HPD state
into their code by using the connector status as a proxy for HPD being
asserted or deasserted.
In particular, this will help Trogdor/Strongbad boards that need to read
the EC's analog mux which steers the DP signal to one or the other USB
type-c ports to figure out which type-c port has HPD asserted.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 30 +++++++++++++++++++++++++
include/drm/bridge/aux-bridge.h | 9 ++++++++
2 files changed, 39 insertions(+)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index adafda4f128f..815dc026718b 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -92,6 +92,8 @@ struct drm_dp_typec_bridge_dev {
struct auxiliary_device adev;
size_t max_lanes;
size_t num_typec_ports;
+ void (*hpd_notify)(void *data, enum drm_connector_status status);
+ void *hpd_data;
};
static inline struct drm_dp_typec_bridge_dev *
@@ -323,6 +325,20 @@ devm_drm_dp_typec_bridge_alloc(struct device *parent, struct device_node *np)
}
EXPORT_SYMBOL_GPL(devm_drm_dp_typec_bridge_alloc);
+/**
+ * drm_dp_typec_bridge_add_hpd_notify: Register a callback called when the
+ * bridge chain hpd state changes
+ * @hpd_notify: callback for bridge hot plug detect events
+ * @hpd_data: data passed to @hpd_notify callback
+ */
+void drm_dp_typec_bridge_add_hpd_notify(struct drm_dp_typec_bridge_dev *typec_bridge_dev,
+ hpd_notify_fn_t hpd_notify, void *hpd_data)
+{
+ typec_bridge_dev->hpd_notify = hpd_notify;
+ typec_bridge_dev->hpd_data = hpd_data;
+}
+EXPORT_SYMBOL_GPL(drm_dp_typec_bridge_add_hpd_notify);
+
/**
* devm_drm_dp_typec_bridge_add - register a USB type-c DisplayPort bridge
* @dev: struct device to tie registration lifetime to
@@ -362,6 +378,19 @@ void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status sta
}
EXPORT_SYMBOL_GPL(drm_aux_hpd_bridge_notify);
+static void drm_dp_typec_bridge_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ struct drm_dp_typec_bridge_data *data;
+ struct drm_dp_typec_bridge_dev *typec_bridge_dev;
+
+ data = to_drm_dp_typec_bridge_data(bridge);
+ typec_bridge_dev = to_drm_dp_typec_bridge_dev(data->hpd_bridge.dev);
+
+ if (typec_bridge_dev->hpd_notify)
+ typec_bridge_dev->hpd_notify(typec_bridge_dev->hpd_data, status);
+}
+
static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
@@ -519,6 +548,7 @@ static const struct drm_bridge_funcs drm_dp_typec_bridge_funcs = {
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .hpd_notify = drm_dp_typec_bridge_hpd_notify,
};
static int drm_dp_typec_bridge_orientation_set(struct typec_switch_dev *sw,
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index 73fc8582ec07..300f4a203a9b 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -22,6 +22,8 @@ static inline int drm_aux_bridge_register(struct device *parent)
struct drm_dp_typec_bridge_dev;
+typedef void (*hpd_notify_fn_t)(void *data, enum drm_connector_status status);
+
#if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np);
int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
@@ -30,6 +32,8 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent,
void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
struct drm_dp_typec_bridge_dev *devm_drm_dp_typec_bridge_alloc(struct device *parent,
struct device_node *np);
+void drm_dp_typec_bridge_add_hpd_notify(struct drm_dp_typec_bridge_dev *typec_bridge_dev,
+ hpd_notify_fn_t hpd_notify, void *hpd_data);
int devm_drm_dp_typec_bridge_add(struct device *dev, struct drm_dp_typec_bridge_dev *typec_bridge_dev);
#else
static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
@@ -55,6 +59,11 @@ devm_drm_dp_typec_bridge_alloc(struct device *parent, struct device_node *np)
return NULL;
}
+static inline void drm_dp_typec_bridge_add_hpd_notify(struct drm_dp_typec_bridge_dev *typec_bridge_dev,
+ hpd_notify_fn_t hpd_notify, void *hpd_data)
+{
+}
+
static inline int devm_drm_dp_typec_bridge_add(struct device *dev,
struct drm_dp_typec_bridge_dev *typec_bridge_dev)
{
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path
2024-08-19 22:38 ` [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path Stephen Boyd
@ 2024-08-20 10:06 ` kernel test robot
0 siblings, 0 replies; 49+ messages in thread
From: kernel test robot @ 2024-08-20 10:06 UTC (permalink / raw)
To: Stephen Boyd, chrome-platform
Cc: oe-kbuild-all, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Andy Shevchenko, Daniel Scally
Hi Stephen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 8400291e289ee6b2bf9779ff1c83a291501f017b]
url: https://github.com/intel-lab-lkp/linux/commits/Stephen-Boyd/drm-atomic-helper-Introduce-lane-remapping-support-to-bridges/20240820-064107
base: 8400291e289ee6b2bf9779ff1c83a291501f017b
patch link: https://lore.kernel.org/r/20240819223834.2049862-10-swboyd%40chromium.org
patch subject: [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20240820/202408201747.NMpzuToG-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240820/202408201747.NMpzuToG-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408201747.NMpzuToG-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/gpu/drm/bridge/aux-hpd-bridge.c:61: warning: Function parameter or struct member 'orientation_switch' not described in 'drm_dp_typec_bridge_typec_port'
>> drivers/gpu/drm/bridge/aux-hpd-bridge.c:336: warning: Function parameter or struct member 'typec_bridge_dev' not described in 'drm_dp_typec_bridge_add_hpd_notify'
vim +336 drivers/gpu/drm/bridge/aux-hpd-bridge.c
327
328 /**
329 * drm_dp_typec_bridge_add_hpd_notify: Register a callback called when the
330 * bridge chain hpd state changes
331 * @hpd_notify: callback for bridge hot plug detect events
332 * @hpd_data: data passed to @hpd_notify callback
333 */
334 void drm_dp_typec_bridge_add_hpd_notify(struct drm_dp_typec_bridge_dev *typec_bridge_dev,
335 hpd_notify_fn_t hpd_notify, void *hpd_data)
> 336 {
337 typec_bridge_dev->hpd_notify = hpd_notify;
338 typec_bridge_dev->hpd_data = hpd_data;
339 }
340 EXPORT_SYMBOL_GPL(drm_dp_typec_bridge_add_hpd_notify);
341
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (8 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 09/17] drm/bridge: dp_typec: Allow users to hook hpd notify path Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-20 10:20 ` Andy Shevchenko
2024-08-19 22:38 ` [PATCH v3 11/17] dt-bindings: usb-switch: Extract endpoints to defs Stephen Boyd
` (6 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
When a single DT node has a graph connected to more than one
usb-c-connector node we can't differentiate which typec switch
registered for the device is associated with the USB connector because
the devcon matcher code assumes a 1:1 relationship between remote node
and typec switch. Furthermore, we don't have a #typec-switch-cells
property so there can only be one node per typec switch.
Support multiple USB typec switches exposed by one node by passing the
remote endpoint node in addition to the remote node to the devcon
matcher function (devcon_match_fn_t). With this change, typec switch
drivers can register switches with the device node pointer for a graph
endpoint so that they can support more than one typec switch if
necessary. Either way, a DT property like 'mode-switch' is always in the
graph's parent node and not in the endpoint node.
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Daniel Scally <djrscally@gmail.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Ivan Orlov <ivan.orlov0322@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: <devicetree@vger.kernel.org>
Cc: <linux-usb@vger.kernel.org>
Cc: <linux-acpi@vger.kernel.org>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/base/property.c | 7 +++++--
drivers/usb/roles/class.c | 4 ++--
drivers/usb/typec/mux.c | 8 ++++++++
drivers/usb/typec/retimer.c | 7 ++++++-
include/linux/property.h | 5 +++--
5 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 837d77e3af2b..621de33f2956 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1284,6 +1284,7 @@ static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwno
{
struct fwnode_handle *node;
struct fwnode_handle *ep;
+ struct fwnode_handle *remote_ep;
unsigned int count = 0;
void *ret;
@@ -1299,7 +1300,9 @@ static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwno
continue;
}
- ret = match(node, con_id, data);
+ remote_ep = fwnode_graph_get_remote_endpoint(ep);
+ ret = match(node, remote_ep, con_id, data);
+ fwnode_handle_put(remote_ep);
fwnode_handle_put(node);
if (ret) {
if (matches)
@@ -1329,7 +1332,7 @@ static unsigned int fwnode_devcon_matches(const struct fwnode_handle *fwnode,
if (IS_ERR(node))
break;
- ret = match(node, NULL, data);
+ ret = match(node, NULL, NULL, data);
fwnode_handle_put(node);
if (ret) {
if (matches)
diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index d7aa913ceb8a..d8bd5071d9d8 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -121,8 +121,8 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
}
EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
-static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const char *id,
- void *data)
+static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const struct fwnode_handle *endpoint,
+ const char *id, void *data)
{
struct device *dev;
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 3531ab03bac4..ab53532282ff 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -33,6 +33,7 @@ static int switch_fwnode_match(struct device *dev, const void *fwnode)
}
static void *typec_switch_match(const struct fwnode_handle *fwnode,
+ const struct fwnode_handle *endpoint,
const char *id, void *data)
{
struct device *dev;
@@ -55,6 +56,9 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
*/
dev = class_find_device(&typec_mux_class, NULL, fwnode,
switch_fwnode_match);
+ if (!dev)
+ dev = class_find_device(&typec_mux_class, NULL, endpoint,
+ switch_fwnode_match);
return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
}
@@ -290,6 +294,7 @@ static int mux_fwnode_match(struct device *dev, const void *fwnode)
}
static void *typec_mux_match(const struct fwnode_handle *fwnode,
+ const struct fwnode_handle *endpoint,
const char *id, void *data)
{
struct device *dev;
@@ -307,6 +312,9 @@ static void *typec_mux_match(const struct fwnode_handle *fwnode,
dev = class_find_device(&typec_mux_class, NULL, fwnode,
mux_fwnode_match);
+ if (!dev)
+ dev = class_find_device(&typec_mux_class, NULL, endpoint,
+ mux_fwnode_match);
return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
}
diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c
index b519fcf358ca..ee4e6312c2d9 100644
--- a/drivers/usb/typec/retimer.c
+++ b/drivers/usb/typec/retimer.c
@@ -22,7 +22,9 @@ static int retimer_fwnode_match(struct device *dev, const void *fwnode)
return is_typec_retimer(dev) && device_match_fwnode(dev, fwnode);
}
-static void *typec_retimer_match(const struct fwnode_handle *fwnode, const char *id, void *data)
+static void *typec_retimer_match(const struct fwnode_handle *fwnode,
+ const struct fwnode_handle *endpoint,
+ const char *id, void *data)
{
struct device *dev;
@@ -31,6 +33,9 @@ static void *typec_retimer_match(const struct fwnode_handle *fwnode, const char
dev = class_find_device(&retimer_class, NULL, fwnode,
retimer_fwnode_match);
+ if (!dev)
+ dev = class_find_device(&retimer_class, NULL, endpoint,
+ retimer_fwnode_match);
return dev ? to_typec_retimer(dev) : ERR_PTR(-EPROBE_DEFER);
}
diff --git a/include/linux/property.h b/include/linux/property.h
index 61fc20e5f81f..3e27d7b76db9 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -507,8 +507,9 @@ unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode,
int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint);
-typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode, const char *id,
- void *data);
+typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode,
+ const struct fwnode_handle *endpoint,
+ const char *id, void *data);
void *fwnode_connection_find_match(const struct fwnode_handle *fwnode,
const char *con_id, void *data,
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher
2024-08-19 22:38 ` [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher Stephen Boyd
@ 2024-08-20 10:20 ` Andy Shevchenko
2024-08-20 17:34 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-20 10:20 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:24PM -0700, Stephen Boyd wrote:
> When a single DT node has a graph connected to more than one
> usb-c-connector node we can't differentiate which typec switch
> registered for the device is associated with the USB connector because
> the devcon matcher code assumes a 1:1 relationship between remote node
> and typec switch. Furthermore, we don't have a #typec-switch-cells
> property so there can only be one node per typec switch.
>
> Support multiple USB typec switches exposed by one node by passing the
> remote endpoint node in addition to the remote node to the devcon
> matcher function (devcon_match_fn_t). With this change, typec switch
> drivers can register switches with the device node pointer for a graph
> endpoint so that they can support more than one typec switch if
> necessary. Either way, a DT property like 'mode-switch' is always in the
> graph's parent node and not in the endpoint node.
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Daniel Scally <djrscally@gmail.com>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Ivan Orlov <ivan.orlov0322@gmail.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <linux-usb@vger.kernel.org>
> Cc: <linux-acpi@vger.kernel.org>
> Cc: Pin-yen Lin <treapking@chromium.org>
Move these after --- line below.
...
> drivers/base/property.c | 7 +++++--
The changes here are fine to me.
...
> include/linux/property.h | 5 +++--
> -typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode, const char *id,
> - void *data);
> +typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode,
> + const struct fwnode_handle *endpoint,
> + const char *id, void *data);
Seems there is no explanation of the parameters here, can we add a kernel-doc
to this typedef (may be a separate patch)?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher
2024-08-20 10:20 ` Andy Shevchenko
@ 2024-08-20 17:34 ` Stephen Boyd
0 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-20 17:34 UTC (permalink / raw)
To: Andy Shevchenko
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Tzung-Bi Shih,
Alexandre Belloni, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Andy Shevchenko (2024-08-20 03:20:44)
> On Mon, Aug 19, 2024 at 03:38:24PM -0700, Stephen Boyd wrote:
> > include/linux/property.h | 5 +++--
>
> > -typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode, const char *id,
> > - void *data);
> > +typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode,
> > + const struct fwnode_handle *endpoint,
> > + const char *id, void *data);
>
> Seems there is no explanation of the parameters here, can we add a kernel-doc
> to this typedef (may be a separate patch)?
Sure. I'll throw in another patch.
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 11/17] dt-bindings: usb-switch: Extract endpoints to defs
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (9 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 10/17] device property: Add remote endpoint to devcon matcher Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-21 0:33 ` Rob Herring
2024-08-19 22:38 ` [PATCH v3 12/17] dt-bindings: usb-switch: Extend for DisplayPort altmode Stephen Boyd
` (5 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Move the usb-switch endpoint bindings to defs so that they can be reused
by other bindings. Future users of this binding will have more than one
type-c output node when they're muxing a single DP signal to more than
one usb-c-connector. Add an example to show how this binding can be used
and accelerate binding checks.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <devicetree@vger.kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
.../devicetree/bindings/usb/usb-switch.yaml | 74 ++++++++++++++++---
1 file changed, 62 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/usb/usb-switch.yaml b/Documentation/devicetree/bindings/usb/usb-switch.yaml
index da76118e73a5..5fc031b56fad 100644
--- a/Documentation/devicetree/bindings/usb/usb-switch.yaml
+++ b/Documentation/devicetree/bindings/usb/usb-switch.yaml
@@ -35,9 +35,13 @@ properties:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
- $ref: /schemas/graph.yaml#/properties/port
- description:
- Super Speed (SS) Output endpoint to the Type-C connector
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+
+ properties:
+ endpoint:
+ $ref: '#/$defs/usbc-out-endpoint'
+ unevaluatedProperties: false
port@1:
$ref: /schemas/graph.yaml#/$defs/port-base
@@ -47,16 +51,8 @@ properties:
properties:
endpoint:
- $ref: /schemas/graph.yaml#/$defs/endpoint-base
+ $ref: '#/$defs/usbc-in-endpoint'
unevaluatedProperties: false
- properties:
- data-lanes:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- minItems: 1
- maxItems: 8
- uniqueItems: true
- items:
- maximum: 8
oneOf:
- required:
@@ -65,3 +61,57 @@ oneOf:
- ports
additionalProperties: true
+
+$defs:
+ usbc-out-endpoint:
+ $ref: /schemas/graph.yaml#/$defs/endpoint-base
+ description: Super Speed (SS) output endpoint to a type-c connector
+ unevaluatedProperties: false
+
+ usbc-in-endpoint:
+ $ref: /schemas/graph.yaml#/$defs/endpoint-base
+ description: Super Speed (SS) input endpoint from the Super Speed PHY
+ unevaluatedProperties: false
+ properties:
+ data-lanes:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 8
+ uniqueItems: true
+ items:
+ maximum: 8
+
+examples:
+ # A USB orientation switch which flips the pin orientation
+ # for a usb-c-connector node.
+ - |
+ device {
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ endpoint {
+ remote-endpoint = <&usb_c_connector>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ endpoint {
+ remote-endpoint = <&usb_ss_phy>;
+ };
+ };
+ };
+ };
+
+...
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 11/17] dt-bindings: usb-switch: Extract endpoints to defs
2024-08-19 22:38 ` [PATCH v3 11/17] dt-bindings: usb-switch: Extract endpoints to defs Stephen Boyd
@ 2024-08-21 0:33 ` Rob Herring
0 siblings, 0 replies; 49+ messages in thread
From: Rob Herring @ 2024-08-21 0:33 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:25PM -0700, Stephen Boyd wrote:
> Move the usb-switch endpoint bindings to defs so that they can be reused
> by other bindings. Future users of this binding will have more than one
> type-c output node when they're muxing a single DP signal to more than
> one usb-c-connector. Add an example to show how this binding can be used
> and accelerate binding checks.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Prashant Malani <pmalani@chromium.org>
> Cc: Tzung-Bi Shih <tzungbi@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <chrome-platform@lists.linux.dev>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
> .../devicetree/bindings/usb/usb-switch.yaml | 74 ++++++++++++++++---
> 1 file changed, 62 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/usb-switch.yaml b/Documentation/devicetree/bindings/usb/usb-switch.yaml
> index da76118e73a5..5fc031b56fad 100644
> --- a/Documentation/devicetree/bindings/usb/usb-switch.yaml
> +++ b/Documentation/devicetree/bindings/usb/usb-switch.yaml
> @@ -35,9 +35,13 @@ properties:
> $ref: /schemas/graph.yaml#/properties/ports
> properties:
> port@0:
> - $ref: /schemas/graph.yaml#/properties/port
> - description:
> - Super Speed (SS) Output endpoint to the Type-C connector
> + $ref: /schemas/graph.yaml#/$defs/port-base
> + unevaluatedProperties: false
> +
> + properties:
> + endpoint:
> + $ref: '#/$defs/usbc-out-endpoint'
> + unevaluatedProperties: false
You can drop this unevaluatedProperties since the $ref contains one.
Same elsewhere. Otherwise,
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 12/17] dt-bindings: usb-switch: Extend for DisplayPort altmode
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (10 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 11/17] dt-bindings: usb-switch: Extract endpoints to defs Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-21 0:33 ` Rob Herring (Arm)
2024-08-19 22:38 ` [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb Stephen Boyd
` (4 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Extend the usb-switch binding to support DisplayPort (DP) alternate
modes. A third port for the DP signal is necessary when a mode-switch is
muxing USB and DP together onto a usb type-c connector. Add data-lanes
to the usbc output node to allow a device using this binding to remap
the data lanes on the output. Add an example to show how this new port
can be used.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <devicetree@vger.kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
.../devicetree/bindings/usb/usb-switch.yaml | 90 +++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/usb-switch.yaml b/Documentation/devicetree/bindings/usb/usb-switch.yaml
index 5fc031b56fad..7a932c638a90 100644
--- a/Documentation/devicetree/bindings/usb/usb-switch.yaml
+++ b/Documentation/devicetree/bindings/usb/usb-switch.yaml
@@ -54,6 +54,15 @@ properties:
$ref: '#/$defs/usbc-in-endpoint'
unevaluatedProperties: false
+ port@2:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+
+ properties:
+ endpoint:
+ $ref: '#/$defs/dp-endpoint'
+ unevaluatedProperties: false
+
oneOf:
- required:
- port
@@ -67,6 +76,19 @@ $defs:
$ref: /schemas/graph.yaml#/$defs/endpoint-base
description: Super Speed (SS) output endpoint to a type-c connector
unevaluatedProperties: false
+ properties:
+ data-lanes:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ An array of physical USB Type-C data lane indexes.
+ - 0 is SSRX1 lane
+ - 1 is SSTX1 lane
+ - 2 is SSTX2 lane
+ - 3 is SSRX2 lane
+ minItems: 4
+ maxItems: 4
+ items:
+ maximum: 3
usbc-in-endpoint:
$ref: /schemas/graph.yaml#/$defs/endpoint-base
@@ -81,7 +103,75 @@ $defs:
items:
maximum: 8
+ dp-endpoint:
+ $ref: /schemas/graph.yaml#/$defs/endpoint-base
+ description: DisplayPort (DP) input from the DP PHY
+ unevaluatedProperties: false
+ properties:
+ data-lanes:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ An array of physical DP data lane indexes
+ - 0 is DP ML0 lane
+ - 1 is DP ML1 lane
+ - 2 is DP ML2 lane
+ - 3 is DP ML3 lane
+ oneOf:
+ - items:
+ - const: 0
+ - const: 1
+ - items:
+ - const: 0
+ - const: 1
+ - const: 2
+ - const: 3
+
examples:
+ # A USB + DP mode and orientation switch which muxes DP altmode
+ # and USB onto a usb-c-connector node.
+ - |
+ device {
+ mode-switch;
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ endpoint {
+ remote-endpoint = <&usb_c_connector>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ endpoint {
+ remote-endpoint = <&usb_ss_phy>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ endpoint {
+ remote-endpoint = <&dp_phy>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+ };
+ };
+
# A USB orientation switch which flips the pin orientation
# for a usb-c-connector node.
- |
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 12/17] dt-bindings: usb-switch: Extend for DisplayPort altmode
2024-08-19 22:38 ` [PATCH v3 12/17] dt-bindings: usb-switch: Extend for DisplayPort altmode Stephen Boyd
@ 2024-08-21 0:33 ` Rob Herring (Arm)
0 siblings, 0 replies; 49+ messages in thread
From: Rob Herring (Arm) @ 2024-08-21 0:33 UTC (permalink / raw)
To: Stephen Boyd
Cc: David Airlie, Andy Shevchenko, Benson Leung, devicetree,
Guenter Roeck, Dmitry Baryshkov, Andrzej Hajda, linux-kernel,
Heikki Krogerus, Ivan Orlov, Douglas Anderson, Thomas Zimmermann,
patches, dri-devel, Jernej Skrabec, Jonas Karlman, Sakari Ailus,
Vinod Koul, Mika Westerberg, Rafael J . Wysocki, Laurent Pinchart,
chrome-platform, Maarten Lankhorst, Alexandre Belloni,
Neil Armstrong, Daniel Scally, Daniel Vetter, Rob Herring,
linux-acpi, Lee Jones, Pin-yen Lin, Krzysztof Kozlowski,
Prashant Malani, Maxime Ripard, Greg Kroah-Hartman, linux-usb,
Tzung-Bi Shih, Conor Dooley, Robert Foss
On Mon, 19 Aug 2024 15:38:26 -0700, Stephen Boyd wrote:
> Extend the usb-switch binding to support DisplayPort (DP) alternate
> modes. A third port for the DP signal is necessary when a mode-switch is
> muxing USB and DP together onto a usb type-c connector. Add data-lanes
> to the usbc output node to allow a device using this binding to remap
> the data lanes on the output. Add an example to show how this new port
> can be used.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Prashant Malani <pmalani@chromium.org>
> Cc: Tzung-Bi Shih <tzungbi@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <chrome-platform@lists.linux.dev>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
> .../devicetree/bindings/usb/usb-switch.yaml | 90 +++++++++++++++++++
> 1 file changed, 90 insertions(+)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (11 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 12/17] dt-bindings: usb-switch: Extend for DisplayPort altmode Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-21 0:33 ` Rob Herring (Arm)
` (2 more replies)
2024-08-19 22:38 ` [PATCH v3 14/17] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode Stephen Boyd
` (3 subsequent siblings)
16 siblings, 3 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul,
Krzysztof Kozlowski
This binding is about USB type-c control. Move the binding to the usb
directory as it's a better home than chrome.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Lee Jones <lee@kernel.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <devicetree@vger.kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Suggested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml | 2 +-
.../bindings/{chrome => usb}/google,cros-ec-typec.yaml | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
rename Documentation/devicetree/bindings/{chrome => usb}/google,cros-ec-typec.yaml (90%)
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index aac8819bd00b..c991626dc22b 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -99,7 +99,7 @@ properties:
gpio-controller: true
typec:
- $ref: /schemas/chrome/google,cros-ec-typec.yaml#
+ $ref: /schemas/usb/google,cros-ec-typec.yaml#
ec-pwm:
$ref: /schemas/pwm/google,cros-ec-pwm.yaml#
diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml b/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
similarity index 90%
rename from Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
rename to Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
index 9f9816fbecbc..5ec4a9777ea1 100644
--- a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
+++ b/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
-$id: http://devicetree.org/schemas/chrome/google,cros-ec-typec.yaml#
+$id: http://devicetree.org/schemas/usb/google,cros-ec-typec.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Google Chrome OS EC(Embedded Controller) Type C port driver.
+title: Google Chrome OS Embedded Controller (EC) USB type-c port driver
maintainers:
- Benson Leung <bleung@chromium.org>
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb
2024-08-19 22:38 ` [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb Stephen Boyd
@ 2024-08-21 0:33 ` Rob Herring (Arm)
2024-08-22 13:39 ` Lee Jones
2024-08-22 14:34 ` Tzung-Bi Shih
2 siblings, 0 replies; 49+ messages in thread
From: Rob Herring (Arm) @ 2024-08-21 0:33 UTC (permalink / raw)
To: Stephen Boyd
Cc: Lee Jones, Daniel Scally, Pin-yen Lin, linux-usb,
Dmitry Baryshkov, Rafael J . Wysocki, Prashant Malani,
Rob Herring, devicetree, chrome-platform, David Airlie,
Thomas Zimmermann, Maxime Ripard, dri-devel, Andy Shevchenko,
linux-acpi, Sakari Ailus, Benson Leung, Guenter Roeck,
Jernej Skrabec, Mika Westerberg, Douglas Anderson,
Greg Kroah-Hartman, patches, Robert Foss, Heikki Krogerus,
Laurent Pinchart, Conor Dooley, Krzysztof Kozlowski,
Andrzej Hajda, Maarten Lankhorst, Vinod Koul, linux-kernel,
Krzysztof Kozlowski, Neil Armstrong, Tzung-Bi Shih,
Alexandre Belloni, Ivan Orlov, Daniel Vetter, Jonas Karlman
On Mon, 19 Aug 2024 15:38:27 -0700, Stephen Boyd wrote:
> This binding is about USB type-c control. Move the binding to the usb
> directory as it's a better home than chrome.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Lee Jones <lee@kernel.org>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Prashant Malani <pmalani@chromium.org>
> Cc: Tzung-Bi Shih <tzungbi@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <chrome-platform@lists.linux.dev>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Suggested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
> Documentation/devicetree/bindings/mfd/google,cros-ec.yaml | 2 +-
> .../bindings/{chrome => usb}/google,cros-ec-typec.yaml | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
> rename Documentation/devicetree/bindings/{chrome => usb}/google,cros-ec-typec.yaml (90%)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb
2024-08-19 22:38 ` [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb Stephen Boyd
2024-08-21 0:33 ` Rob Herring (Arm)
@ 2024-08-22 13:39 ` Lee Jones
2024-08-22 14:34 ` Tzung-Bi Shih
2 siblings, 0 replies; 49+ messages in thread
From: Lee Jones @ 2024-08-22 13:39 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Maarten Lankhorst,
Maxime Ripard, Neil Armstrong, Prashant Malani, Robert Foss,
Rob Herring, Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul,
Krzysztof Kozlowski
On Mon, 19 Aug 2024, Stephen Boyd wrote:
> This binding is about USB type-c control. Move the binding to the usb
> directory as it's a better home than chrome.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Lee Jones <lee@kernel.org>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Prashant Malani <pmalani@chromium.org>
> Cc: Tzung-Bi Shih <tzungbi@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <chrome-platform@lists.linux.dev>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Suggested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
> Documentation/devicetree/bindings/mfd/google,cros-ec.yaml | 2 +-
> .../bindings/{chrome => usb}/google,cros-ec-typec.yaml | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
> rename Documentation/devicetree/bindings/{chrome => usb}/google,cros-ec-typec.yaml (90%)
Acked-by: Lee Jones <lee@kernel.org>
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb
2024-08-19 22:38 ` [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb Stephen Boyd
2024-08-21 0:33 ` Rob Herring (Arm)
2024-08-22 13:39 ` Lee Jones
@ 2024-08-22 14:34 ` Tzung-Bi Shih
2024-08-23 20:47 ` Stephen Boyd
2 siblings, 1 reply; 49+ messages in thread
From: Tzung-Bi Shih @ 2024-08-22 14:34 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul,
Krzysztof Kozlowski
On Mon, Aug 19, 2024 at 03:38:27PM -0700, Stephen Boyd wrote:
> -title: Google Chrome OS EC(Embedded Controller) Type C port driver.
> +title: Google Chrome OS Embedded Controller (EC) USB type-c port driver
Given that it gets chance to modify, how about s/Chrome OS/ChromeOS/?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb
2024-08-22 14:34 ` Tzung-Bi Shih
@ 2024-08-23 20:47 ` Stephen Boyd
0 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-23 20:47 UTC (permalink / raw)
To: Tzung-Bi Shih
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul,
Krzysztof Kozlowski
Quoting Tzung-Bi Shih (2024-08-22 07:34:31)
> On Mon, Aug 19, 2024 at 03:38:27PM -0700, Stephen Boyd wrote:
> > -title: Google Chrome OS EC(Embedded Controller) Type C port driver.
> > +title: Google Chrome OS Embedded Controller (EC) USB type-c port driver
>
> Given that it gets chance to modify, how about s/Chrome OS/ChromeOS/?
Sure!
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 14/17] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (12 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 13/17] dt-bindings: Move google,cros-ec-typec binding to usb Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-21 0:34 ` Rob Herring (Arm)
2024-08-19 22:38 ` [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge Stephen Boyd
` (2 subsequent siblings)
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Add a DT graph binding to google,cros-ec-typec so that it can combine
DisplayPort (DP) and USB SuperSpeed (SS) data into a USB type-c endpoint
that is connected to the usb-c-connector node's SS endpoint. This also
allows us to connect the DP and USB nodes in the graph to the USB type-c
connectors, providing the full picture of the USB type-c data flows in
the system.
Allow there to be multiple typec nodes underneath the EC node so that
one DT graph exists per DP bridge. The EC is actually controlling TCPCs
and redrivers that combine the DP and USB signals together so this more
accurately reflects the hardware design without introducing yet another
DT node underneath the EC for USB type-c.
If the type-c ports are being shared between a single DP controller then
the ports need to know about each other and determine a policy to drive
DP to one type-c port. If the type-c ports each have their own dedicated
DP controller then they're able to operate independently and enter/exit
DP altmode independently as well. We can't connect the DP controller's
endpoint to one usb-c-connector port@1 endpoint and the USB controller's
endpoint to another usb-c-connector port@1 endpoint either because the
DP muxing case would have DP connected to two usb-c-connector endpoints
which the graph binding doesn't support.
Therefore, one typec node is required per the capabilities of the type-c
port(s) being managed. This also lets us indicate which type-c ports the
DP controller is wired to. For example, if DP was connected to ports 0
and 2, while port 1 was connected to another DP controller we wouldn't
be able to implement that without having some other DT property to
indicate which output ports are connected to the DP endpoint.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Lee Jones <lee@kernel.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <devicetree@vger.kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
.../bindings/mfd/google,cros-ec.yaml | 7 +-
.../bindings/usb/google,cros-ec-typec.yaml | 229 ++++++++++++++++++
2 files changed, 233 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index c991626dc22b..bbe28047d0c0 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -98,9 +98,6 @@ properties:
gpio-controller: true
- typec:
- $ref: /schemas/usb/google,cros-ec-typec.yaml#
-
ec-pwm:
$ref: /schemas/pwm/google,cros-ec-pwm.yaml#
deprecated: true
@@ -166,6 +163,10 @@ patternProperties:
type: object
$ref: /schemas/extcon/extcon-usbc-cros-ec.yaml#
+ "^typec(-[0-9])*$":
+ type: object
+ $ref: /schemas/usb/google,cros-ec-typec.yaml#
+
required:
- compatible
diff --git a/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml b/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
index 5ec4a9777ea1..d4c5c92c78ce 100644
--- a/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
+++ b/Documentation/devicetree/bindings/usb/google,cros-ec-typec.yaml
@@ -26,6 +26,106 @@ properties:
'#size-cells':
const: 0
+ mux-gpios:
+ description: GPIOs indicating which way the DP mux is steered
+ maxItems: 1
+
+ no-hpd:
+ description: Indicates this endpoint doesn't signal HPD for DisplayPort
+ type: boolean
+
+ mode-switch:
+ $ref: usb-switch.yaml#properties/mode-switch
+
+ orientation-switch:
+ $ref: usb-switch.yaml#properties/orientation-switch
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: Output ports for combined DP and USB SS data
+ patternProperties:
+ "^endpoint@([0-8])$":
+ $ref: usb-switch.yaml#/$defs/usbc-out-endpoint
+ unevaluatedProperties: false
+
+ anyOf:
+ - required:
+ - endpoint@0
+ - required:
+ - endpoint@1
+ - required:
+ - endpoint@2
+ - required:
+ - endpoint@3
+ - required:
+ - endpoint@4
+ - required:
+ - endpoint@5
+ - required:
+ - endpoint@6
+ - required:
+ - endpoint@7
+ - required:
+ - endpoint@8
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port to receive USB SuperSpeed (SS) data
+ patternProperties:
+ "^endpoint@([0-8])$":
+ $ref: usb-switch.yaml#/$defs/usbc-in-endpoint
+ unevaluatedProperties: false
+
+ anyOf:
+ - required:
+ - endpoint@0
+ - required:
+ - endpoint@1
+ - required:
+ - endpoint@2
+ - required:
+ - endpoint@3
+ - required:
+ - endpoint@4
+ - required:
+ - endpoint@5
+ - required:
+ - endpoint@6
+ - required:
+ - endpoint@7
+ - required:
+ - endpoint@8
+
+ port@2:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ description:
+ Input port to receive DisplayPort (DP) data
+ unevaluatedProperties: false
+
+ properties:
+ endpoint:
+ $ref: usb-switch.yaml#/$defs/dp-endpoint
+ unevaluatedProperties: false
+
+ required:
+ - endpoint
+
+ required:
+ - port@0
+
+ anyOf:
+ - required:
+ - port@1
+ - required:
+ - port@2
+
patternProperties:
'^connector@[0-9a-f]+$':
$ref: /schemas/connector/usb-connector.yaml#
@@ -35,6 +135,40 @@ patternProperties:
required:
- compatible
+allOf:
+ - if:
+ required:
+ - no-hpd
+ then:
+ properties:
+ ports:
+ required:
+ - port@2
+ - if:
+ required:
+ - mux-gpios
+ then:
+ properties:
+ ports:
+ required:
+ - port@2
+ - if:
+ required:
+ - orientation-switch
+ then:
+ properties:
+ ports:
+ required:
+ - port@2
+ - if:
+ required:
+ - mode-switch
+ then:
+ properties:
+ ports:
+ required:
+ - port@2
+
additionalProperties: false
examples:
@@ -50,6 +184,8 @@ examples:
typec {
compatible = "google,cros-ec-typec";
+ orientation-switch;
+ mode-switch;
#address-cells = <1>;
#size-cells = <0>;
@@ -60,6 +196,99 @@ examples:
power-role = "dual";
data-role = "dual";
try-power-role = "source";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_c0_hs: endpoint {
+ remote-endpoint = <&usb_hub_dfp3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ usb_c0_ss: endpoint {
+ remote-endpoint = <&cros_typec_c0_ss>;
+ };
+ };
+ };
+ };
+
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "source";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_c1_hs: endpoint {
+ remote-endpoint = <&usb_hub_dfp2_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ usb_c1_ss: endpoint {
+ remote-endpoint = <&cros_typec_c1_ss>;
+ };
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cros_typec_c0_ss: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usb_c0_ss>;
+ data-lanes = <0 1 2 3>;
+ };
+
+ cros_typec_c1_ss: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&usb_c1_ss>;
+ data-lanes = <2 3 0 1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb_in_0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usb_ss_0_out>;
+ };
+
+ usb_in_1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&usb_ss_1_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ dp_in: endpoint {
+ remote-endpoint = <&dp_phy>;
+ data-lanes = <0 1>;
+ };
+ };
};
};
};
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 14/17] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode
2024-08-19 22:38 ` [PATCH v3 14/17] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode Stephen Boyd
@ 2024-08-21 0:34 ` Rob Herring (Arm)
0 siblings, 0 replies; 49+ messages in thread
From: Rob Herring (Arm) @ 2024-08-21 0:34 UTC (permalink / raw)
To: Stephen Boyd
Cc: Daniel Scally, Andy Shevchenko, Jonas Karlman, Robert Foss,
Andrzej Hajda, Rob Herring, David Airlie, Maarten Lankhorst,
Sakari Ailus, Douglas Anderson, Vinod Koul, Benson Leung,
Dmitry Baryshkov, patches, Heikki Krogerus, Daniel Vetter,
Jernej Skrabec, Laurent Pinchart, Neil Armstrong, Prashant Malani,
Rafael J . Wysocki, Pin-yen Lin, Krzysztof Kozlowski,
Conor Dooley, linux-kernel, Ivan Orlov, Mika Westerberg,
Thomas Zimmermann, Greg Kroah-Hartman, Tzung-Bi Shih, dri-devel,
linux-usb, linux-acpi, chrome-platform, Alexandre Belloni,
Maxime Ripard, Lee Jones, devicetree, Guenter Roeck
On Mon, 19 Aug 2024 15:38:28 -0700, Stephen Boyd wrote:
> Add a DT graph binding to google,cros-ec-typec so that it can combine
> DisplayPort (DP) and USB SuperSpeed (SS) data into a USB type-c endpoint
> that is connected to the usb-c-connector node's SS endpoint. This also
> allows us to connect the DP and USB nodes in the graph to the USB type-c
> connectors, providing the full picture of the USB type-c data flows in
> the system.
>
> Allow there to be multiple typec nodes underneath the EC node so that
> one DT graph exists per DP bridge. The EC is actually controlling TCPCs
> and redrivers that combine the DP and USB signals together so this more
> accurately reflects the hardware design without introducing yet another
> DT node underneath the EC for USB type-c.
>
> If the type-c ports are being shared between a single DP controller then
> the ports need to know about each other and determine a policy to drive
> DP to one type-c port. If the type-c ports each have their own dedicated
> DP controller then they're able to operate independently and enter/exit
> DP altmode independently as well. We can't connect the DP controller's
> endpoint to one usb-c-connector port@1 endpoint and the USB controller's
> endpoint to another usb-c-connector port@1 endpoint either because the
> DP muxing case would have DP connected to two usb-c-connector endpoints
> which the graph binding doesn't support.
>
> Therefore, one typec node is required per the capabilities of the type-c
> port(s) being managed. This also lets us indicate which type-c ports the
> DP controller is wired to. For example, if DP was connected to ports 0
> and 2, while port 1 was connected to another DP controller we wouldn't
> be able to implement that without having some other DT property to
> indicate which output ports are connected to the DP endpoint.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Lee Jones <lee@kernel.org>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Prashant Malani <pmalani@chromium.org>
> Cc: Tzung-Bi Shih <tzungbi@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Cc: <chrome-platform@lists.linux.dev>
> Cc: Pin-yen Lin <treapking@chromium.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
> .../bindings/mfd/google,cros-ec.yaml | 7 +-
> .../bindings/usb/google,cros-ec-typec.yaml | 229 ++++++++++++++++++
> 2 files changed, 233 insertions(+), 3 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (13 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 14/17] dt-bindings: usb: Add ports to google,cros-ec-typec for DP altmode Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-22 14:35 ` Tzung-Bi Shih
2024-08-19 22:38 ` [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing Stephen Boyd
2024-08-19 22:38 ` [PATCH v3 17/17] platform/chrome: cros_ec_typec: Handle lack of HPD information Stephen Boyd
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
We can imagine that logically the EC is a device that has some number of
DisplayPort (DP) connector inputs, some number of USB3 connector inputs,
and some number of USB type-c connector outputs. If you squint enough it
looks like a USB type-c dock. Logically there's a crossbar pin
assignment capability within the EC that can assign USB and DP lanes to
USB type-c lanes in the connector (i.e. USB type-c pin configurations).
In reality, the EC is a microcontroller that has some TCPCs and
redrivers connected to it over something like i2c and DP/USB from the AP
is wired directly to those ICs, not the EC.
This design allows the EC to abstract many possible USB and DP hardware
configurations away from the AP (kernel) so that the AP can largely deal
with USB and DP without thinking about USB Type-C much at all. The DP
and USB data originate in the AP, not the EC, so it helps to think that
the EC takes the DP and USB data as input to mux onto USB type-c ports
even if it really doesn't do that. With this split design, the EC
forwards the DP HPD state to the DP hardware via a GPIO that's connected
to the DP phy.
Having that HPD state signaled directly to the DP phy uses precious
hardware resources, a pin or two and a wire, and it also forces the TCPM
to live on the EC. If we want to save costs and move more control of USB
type-c to the kernel it's in our interest to get rid of the HPD pin
entirely and signal HPD to the DP phy some other way. Luckily, the EC
already exposes information about the USB Type-C stack to the kernel via
the host command interface in the "google,cros-ec-typec" compatible
driver, which parses EC messages related to USB type-c and effectively
"replays" those messages to the kernel's USB typec subsystem. This
includes the state of HPD, which can be interrogated and acted upon by
registering a 'struct typec_mux_dev' with the typec subsystem or by
hooking directly into this cros_ec_typec driver.
On DT based systems, the DP display pipeline is abstracted via a 'struct
drm_bridge'. If we want to signal HPD state from within the kernel we
need to hook into the drm_bridge framework somehow to call
drm_bridge_hpd_notify() when HPD state changes in the typec framework.
Use the newly added drm_dp_typec_bridge code to do this. When the EC
notifies AP of a type-c event, look at the port state and set the
connector state to connected or disconnected based on the HPD level when
the port is in DP mode.
Luckily all this logic is already handled by the drm_dp_typec bridge.
Register a bridge when this DT node has the 'mode-switch' property. When
cros_typec_configure_mux() puts a port into DP mode, the mode switch
registered in the drm_dp_typec bridge driver will signal HPD state to
the drm_bridge chain because the typec subsystem will configure the usbc
switches connected to the port with the data this driver provides.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/platform/chrome/Kconfig | 1 +
drivers/platform/chrome/cros_ec_typec.c | 43 +++++++++++++++++++++++++
drivers/platform/chrome/cros_ec_typec.h | 3 ++
3 files changed, 47 insertions(+)
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 7dbeb786352a..0aee8a77f1d6 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -231,6 +231,7 @@ config CROS_EC_TYPEC
depends on MFD_CROS_EC_DEV && TYPEC
depends on CROS_USBPD_NOTIFY
depends on USB_ROLE_SWITCH
+ select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF
default MFD_CROS_EC_DEV
help
If you say Y here, you get support for accessing Type C connector
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 4d305876ec08..f7e184fa90c5 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -9,6 +9,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_usbpd_notify.h>
#include <linux/platform_device.h>
@@ -16,11 +17,18 @@
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_tbt.h>
+#include <drm/bridge/aux-bridge.h>
+
#include "cros_ec_typec.h"
#include "cros_typec_vdm.h"
#define DRV_NAME "cros-ec-typec"
+struct cros_typec_dp_bridge {
+ struct cros_typec_data *typec_data;
+ struct drm_dp_typec_bridge_dev *dev;
+};
+
#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
DP_CAP_DFP_D | DP_CAP_RECEPTACLE)
@@ -334,6 +342,9 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
u32 port_num = 0;
nports = device_get_child_node_count(dev);
+ /* Don't count any 'ports' child node */
+ if (of_graph_is_present(dev->of_node))
+ nports--;
if (nports == 0) {
dev_err(dev, "No port entries found.\n");
return -ENODEV;
@@ -347,6 +358,10 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
/* DT uses "reg" to specify port number. */
port_prop = dev->of_node ? "reg" : "port-number";
device_for_each_child_node(dev, fwnode) {
+ /* An OF graph isn't a connector */
+ if (fwnode_name_eq(fwnode, "ports"))
+ continue;
+
if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
ret = -EINVAL;
dev_err(dev, "No port-number for port, aborting.\n");
@@ -413,6 +428,30 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
return ret;
}
+static int cros_typec_init_dp_bridge(struct cros_typec_data *typec)
+{
+ struct device *dev = typec->dev;
+ struct cros_typec_dp_bridge *dp_bridge;
+ struct drm_dp_typec_bridge_dev *dp_dev;
+
+ /* Not capable of DP altmode switching. Ignore. */
+ if (!fwnode_property_read_bool(dev_fwnode(dev), "mode-switch"))
+ return 0;
+
+ dp_bridge = devm_kzalloc(dev, sizeof(*dp_bridge), GFP_KERNEL);
+ if (!dp_bridge)
+ return -ENOMEM;
+ typec->dp_bridge = dp_bridge;
+ dp_bridge->typec_data = typec;
+
+ dp_dev = devm_drm_dp_typec_bridge_alloc(dev, dev->of_node);
+ if (IS_ERR(dp_dev))
+ return PTR_ERR(dp_dev);
+ dp_bridge->dev = dp_dev;
+
+ return devm_drm_dp_typec_bridge_add(dev, dp_dev);
+}
+
static int cros_typec_usb_safe_state(struct cros_typec_port *port)
{
int ret;
@@ -1257,6 +1296,10 @@ static int cros_typec_probe(struct platform_device *pdev)
typec->num_ports = EC_USB_PD_MAX_PORTS;
}
+ ret = cros_typec_init_dp_bridge(typec);
+ if (ret < 0)
+ return ret;
+
ret = cros_typec_init_ports(typec);
if (ret < 0)
return ret;
diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chrome/cros_ec_typec.h
index deda180a646f..73d300427140 100644
--- a/drivers/platform/chrome/cros_ec_typec.h
+++ b/drivers/platform/chrome/cros_ec_typec.h
@@ -27,6 +27,8 @@ struct cros_typec_altmode_node {
struct list_head list;
};
+struct cros_typec_dp_bridge;
+
/* Platform-specific data for the Chrome OS EC Type C controller. */
struct cros_typec_data {
struct device *dev;
@@ -35,6 +37,7 @@ struct cros_typec_data {
unsigned int pd_ctrl_ver;
/* Array of ports, indexed by port number. */
struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
+ struct cros_typec_dp_bridge *dp_bridge;
struct notifier_block nb;
struct work_struct port_work;
bool typec_cmd_supported;
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge
2024-08-19 22:38 ` [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge Stephen Boyd
@ 2024-08-22 14:35 ` Tzung-Bi Shih
2024-08-23 20:47 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Tzung-Bi Shih @ 2024-08-22 14:35 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:29PM -0700, Stephen Boyd wrote:
> +struct cros_typec_dp_bridge {
> + struct cros_typec_data *typec_data;
> + struct drm_dp_typec_bridge_dev *dev;
> +};
It looks like structs are all defined in cros_ec_typec.h. I think this struct
definition can be also moved there.
> diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chrome/cros_ec_typec.h
> index deda180a646f..73d300427140 100644
> --- a/drivers/platform/chrome/cros_ec_typec.h
> +++ b/drivers/platform/chrome/cros_ec_typec.h
> @@ -27,6 +27,8 @@ struct cros_typec_altmode_node {
> struct list_head list;
> };
>
> +struct cros_typec_dp_bridge;
If the struct definition moves here, it doesn't need to declare forward.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge
2024-08-22 14:35 ` Tzung-Bi Shih
@ 2024-08-23 20:47 ` Stephen Boyd
2024-08-27 3:25 ` Tzung-Bi Shih
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-23 20:47 UTC (permalink / raw)
To: Tzung-Bi Shih
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Tzung-Bi Shih (2024-08-22 07:35:13)
> On Mon, Aug 19, 2024 at 03:38:29PM -0700, Stephen Boyd wrote:
> > +struct cros_typec_dp_bridge {
> > + struct cros_typec_data *typec_data;
> > + struct drm_dp_typec_bridge_dev *dev;
> > +};
>
> It looks like structs are all defined in cros_ec_typec.h. I think this struct
> definition can be also moved there.
I put it here because it wasn't used by any other driver. Maybe I can
skip the entire struct though and add what I need directly to 'struct
cros_typec_data'.
>
> > diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chrome/cros_ec_typec.h
> > index deda180a646f..73d300427140 100644
> > --- a/drivers/platform/chrome/cros_ec_typec.h
> > +++ b/drivers/platform/chrome/cros_ec_typec.h
> > @@ -27,6 +27,8 @@ struct cros_typec_altmode_node {
> > struct list_head list;
> > };
> >
> > +struct cros_typec_dp_bridge;
>
> If the struct definition moves here, it doesn't need to declare forward.
But then we have to forward declare 'struct cros_typec_data'? There's no
escape.
^ permalink raw reply [flat|nested] 49+ messages in thread* Re: [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge
2024-08-23 20:47 ` Stephen Boyd
@ 2024-08-27 3:25 ` Tzung-Bi Shih
0 siblings, 0 replies; 49+ messages in thread
From: Tzung-Bi Shih @ 2024-08-27 3:25 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Fri, Aug 23, 2024 at 01:47:23PM -0700, Stephen Boyd wrote:
> Quoting Tzung-Bi Shih (2024-08-22 07:35:13)
> > On Mon, Aug 19, 2024 at 03:38:29PM -0700, Stephen Boyd wrote:
> > > +struct cros_typec_dp_bridge {
> > > + struct cros_typec_data *typec_data;
> > > + struct drm_dp_typec_bridge_dev *dev;
> > > +};
> >
> > It looks like structs are all defined in cros_ec_typec.h. I think this struct
> > definition can be also moved there.
>
> I put it here because it wasn't used by any other driver. Maybe I can
> skip the entire struct though and add what I need directly to 'struct
> cros_typec_data'.
I see.
* struct cros_typec_altmode_node, used by cros_ec_typec.c.
* struct cros_typec_data, used by cros_ec_typec.c and cros_typec_vdm.c.
* struct cros_typec_port, used by cros_ec_typec.c and cros_typec_vdm.c.
cros_typec_switch.c has another struct cros_typec_port.
To simplify, I'm not sure whether we should merge cros_ec_typec.h,
cros_typec_vdm.c, and cros_typec_vdm.h into cros_ec_typec.c.
Back to struct cros_typec_dp_bridge, I think it's fine to keep it as is.
>
> >
> > > diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chrome/cros_ec_typec.h
> > > index deda180a646f..73d300427140 100644
> > > --- a/drivers/platform/chrome/cros_ec_typec.h
> > > +++ b/drivers/platform/chrome/cros_ec_typec.h
> > > @@ -27,6 +27,8 @@ struct cros_typec_altmode_node {
> > > struct list_head list;
> > > };
> > >
> > > +struct cros_typec_dp_bridge;
> >
> > If the struct definition moves here, it doesn't need to declare forward.
>
> But then we have to forward declare 'struct cros_typec_data'? There's no
> escape.
I see.
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (14 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 15/17] platform/chrome: cros_ec_typec: Add support for signaling DP HPD via drm_bridge Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
2024-08-22 14:37 ` Tzung-Bi Shih
2024-08-19 22:38 ` [PATCH v3 17/17] platform/chrome: cros_ec_typec: Handle lack of HPD information Stephen Boyd
16 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Most ARM based chromebooks with two usb-c-connector nodes and one DP
controller are muxing the DP lanes between the two USB ports. This is
done so that the type-c ports are at least equal in capability if not
functionality. Either an analog mux is used to steer the DP signal to
one or the other port, or a DP bridge chip has two lanes (e.g. DP
ML0/ML1) wired to one type-c port while the other two (e.g. DP ML2/ML3)
are wired to another type-c port.
Implement the same algorithm that the EC has to figure out which type-c
port has actually been muxed for DP altmode. Wait for the first type-c
port to assert HPD, and treat that as the actively muxed port until the
port exits DP altmode entirely. Allow HPD to be asserted or deasserted
during this time. If the port isn't active, simply ignore those events
and skip calling cros_typec_enable_dp(). Otherwise, pass the DP
information to the typec subsystem so that the DP controller can respond
to HPD events and pin configurations.
The EC can mux the DP signal to any number of USB type-c ports. We only
need to make sure that the active USB type-c port is tracked so that DP
information about the other ports is ignored. Unfortunately, the EC
doesn't hide these details from the AP so we have to reimplement the
logic in the kernel.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/platform/chrome/cros_ec_typec.c | 27 +++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index f7e184fa90c5..b32abd14825c 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -27,6 +27,7 @@
struct cros_typec_dp_bridge {
struct cros_typec_data *typec_data;
struct drm_dp_typec_bridge_dev *dev;
+ struct cros_typec_port *active_port;
};
#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
@@ -651,6 +652,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
struct ec_response_usb_pd_control_v2 *pd_ctrl)
{
struct cros_typec_port *port = typec->ports[port_num];
+ struct cros_typec_dp_bridge *dp_bridge = typec->dp_bridge;
struct ec_response_usb_pd_mux_info resp;
struct ec_params_usb_pd_mux_info req = {
.port = port_num,
@@ -658,6 +660,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
struct ec_params_usb_pd_mux_ack mux_ack;
enum typec_orientation orientation;
int ret;
+ bool dp_enabled, hpd_asserted, is_active_port;
ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
&req, sizeof(req), &resp, sizeof(resp));
@@ -671,6 +674,20 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
return 0;
+ dp_enabled = resp.flags & USB_PD_MUX_DP_ENABLED;
+ hpd_asserted = resp.flags & USB_PD_MUX_HPD_LVL;
+ /*
+ * Assume the first port to have HPD asserted is the one muxed to DP
+ * (i.e. active_port). When there's only one port this delays setting
+ * the active_port until HPD is asserted, but before that the
+ * drm_connector looks disconnected so active_port doesn't need to be
+ * set.
+ */
+ if (dp_bridge && hpd_asserted && !dp_bridge->active_port)
+ dp_bridge->active_port = port;
+
+ is_active_port = !dp_bridge || dp_bridge->active_port == port;
+
port->mux_flags = resp.flags;
port->role = pd_ctrl->role;
@@ -698,8 +715,11 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
} else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
- } else if (port->mux_flags & USB_PD_MUX_DP_ENABLED) {
- ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
+ } else if (dp_enabled) {
+ ret = 0;
+ /* Ignore DP events for the non-active port */
+ if (is_active_port)
+ ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
} else if (port->mux_flags & USB_PD_MUX_SAFE_MODE) {
ret = cros_typec_usb_safe_state(port);
} else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
@@ -716,6 +736,9 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
}
mux_ack:
+ if (dp_bridge && !dp_enabled && is_active_port)
+ dp_bridge->active_port = NULL;
+
if (!typec->needs_mux_ack)
return ret;
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread* Re: [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing
2024-08-19 22:38 ` [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing Stephen Boyd
@ 2024-08-22 14:37 ` Tzung-Bi Shih
2024-08-23 20:44 ` Stephen Boyd
0 siblings, 1 reply; 49+ messages in thread
From: Tzung-Bi Shih @ 2024-08-22 14:37 UTC (permalink / raw)
To: Stephen Boyd
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
On Mon, Aug 19, 2024 at 03:38:30PM -0700, Stephen Boyd wrote:
> @@ -671,6 +674,20 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
> if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
> return 0;
>
> + dp_enabled = resp.flags & USB_PD_MUX_DP_ENABLED;
> + hpd_asserted = resp.flags & USB_PD_MUX_HPD_LVL;
> + /*
> + * Assume the first port to have HPD asserted is the one muxed to DP
> + * (i.e. active_port). When there's only one port this delays setting
> + * the active_port until HPD is asserted, but before that the
> + * drm_connector looks disconnected so active_port doesn't need to be
> + * set.
> + */
> + if (dp_bridge && hpd_asserted && !dp_bridge->active_port)
> + dp_bridge->active_port = port;
> +
> + is_active_port = !dp_bridge || dp_bridge->active_port == port;
Why `!dp_bridge`? When will `dp_bridge` be NULL?
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing
2024-08-22 14:37 ` Tzung-Bi Shih
@ 2024-08-23 20:44 ` Stephen Boyd
2024-08-26 9:58 ` Andy Shevchenko
0 siblings, 1 reply; 49+ messages in thread
From: Stephen Boyd @ 2024-08-23 20:44 UTC (permalink / raw)
To: Tzung-Bi Shih
Cc: chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Quoting Tzung-Bi Shih (2024-08-22 07:37:05)
> On Mon, Aug 19, 2024 at 03:38:30PM -0700, Stephen Boyd wrote:
> > @@ -671,6 +674,20 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
> > if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
> > return 0;
> >
> > + dp_enabled = resp.flags & USB_PD_MUX_DP_ENABLED;
> > + hpd_asserted = resp.flags & USB_PD_MUX_HPD_LVL;
> > + /*
> > + * Assume the first port to have HPD asserted is the one muxed to DP
> > + * (i.e. active_port). When there's only one port this delays setting
> > + * the active_port until HPD is asserted, but before that the
> > + * drm_connector looks disconnected so active_port doesn't need to be
> > + * set.
> > + */
> > + if (dp_bridge && hpd_asserted && !dp_bridge->active_port)
> > + dp_bridge->active_port = port;
> > +
> > + is_active_port = !dp_bridge || dp_bridge->active_port == port;
>
> Why `!dp_bridge`? When will `dp_bridge` be NULL?
I'll add a comment.
'dp_bridge' is NULL when this driver is running on non-DT platforms,
i.e. ACPI, or there isn't a graph/ports node for this device. The latter
could happen if there's some AP controlled piece of hardware that is a
typec switch, connected directly to a usb-c-connector. This is the case
on Kukui where we send the DP lanes directly to the usb-c-connector.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing
2024-08-23 20:44 ` Stephen Boyd
@ 2024-08-26 9:58 ` Andy Shevchenko
0 siblings, 0 replies; 49+ messages in thread
From: Andy Shevchenko @ 2024-08-26 9:58 UTC (permalink / raw)
To: Stephen Boyd
Cc: Tzung-Bi Shih, chrome-platform, linux-kernel, patches, devicetree,
Douglas Anderson, Pin-yen Lin, Andrzej Hajda, Benson Leung,
Conor Dooley, Daniel Vetter, David Airlie, Dmitry Baryshkov,
dri-devel, Guenter Roeck, Jernej Skrabec, Jonas Karlman,
Krzysztof Kozlowski, Laurent Pinchart, Lee Jones,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Prashant Malani,
Robert Foss, Rob Herring, Thomas Zimmermann, Alexandre Belloni,
Daniel Scally, Greg Kroah-Hartman, Heikki Krogerus, Ivan Orlov,
linux-acpi, linux-usb, Mika Westerberg, Rafael J . Wysocki,
Sakari Ailus, Vinod Koul
On Fri, Aug 23, 2024 at 01:44:41PM -0700, Stephen Boyd wrote:
> Quoting Tzung-Bi Shih (2024-08-22 07:37:05)
> > On Mon, Aug 19, 2024 at 03:38:30PM -0700, Stephen Boyd wrote:
...
> > > + /*
> > > + * Assume the first port to have HPD asserted is the one muxed to DP
> > > + * (i.e. active_port). When there's only one port this delays setting
> > > + * the active_port until HPD is asserted, but before that the
> > > + * drm_connector looks disconnected so active_port doesn't need to be
> > > + * set.
> > > + */
> > > + if (dp_bridge && hpd_asserted && !dp_bridge->active_port)
> > > + dp_bridge->active_port = port;
> > > +
> > > + is_active_port = !dp_bridge || dp_bridge->active_port == port;
> >
> > Why `!dp_bridge`? When will `dp_bridge` be NULL?
>
> I'll add a comment.
>
> 'dp_bridge' is NULL when this driver is running on non-DT platforms,
> i.e. ACPI, or there isn't a graph/ports node for this device. The latter
> could happen if there's some AP controlled piece of hardware that is a
> typec switch, connected directly to a usb-c-connector. This is the case
> on Kukui where we send the DP lanes directly to the usb-c-connector.
Thanks!
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v3 17/17] platform/chrome: cros_ec_typec: Handle lack of HPD information
2024-08-19 22:38 [PATCH v3 00/17] platform/chrome: Add DT USB/DP muxing/topology support Stephen Boyd
` (15 preceding siblings ...)
2024-08-19 22:38 ` [PATCH v3 16/17] platform/chrome: cros_ec_typec: Support DP muxing Stephen Boyd
@ 2024-08-19 22:38 ` Stephen Boyd
16 siblings, 0 replies; 49+ messages in thread
From: Stephen Boyd @ 2024-08-19 22:38 UTC (permalink / raw)
To: chrome-platform
Cc: linux-kernel, patches, devicetree, Douglas Anderson, Pin-yen Lin,
Andrzej Hajda, Benson Leung, Conor Dooley, Daniel Vetter,
David Airlie, Dmitry Baryshkov, dri-devel, Guenter Roeck,
Jernej Skrabec, Jonas Karlman, Krzysztof Kozlowski,
Laurent Pinchart, Lee Jones, Maarten Lankhorst, Maxime Ripard,
Neil Armstrong, Prashant Malani, Robert Foss, Rob Herring,
Thomas Zimmermann, Tzung-Bi Shih, Alexandre Belloni,
Andy Shevchenko, Daniel Scally, Greg Kroah-Hartman,
Heikki Krogerus, Ivan Orlov, linux-acpi, linux-usb,
Mika Westerberg, Rafael J . Wysocki, Sakari Ailus, Vinod Koul
Some EC firmwares on Trogdor/Strongbad boards don't properly indicate
the state of DP HPD on a type-c port. Instead, the EC only indicates
that a type-c port has entered or exited DP mode. To make matters worse,
on these boards the DP signal is muxed between two USB type-c
connectors, so we can't use the DP entry of a port to figure out which
type-c port is actually displaying DP.
Stash the HPD state in this case whenever the drm_bridge is notified of
a connector status change and kick off the port worker so that the
type-c port state can be re-evaluated. If an analog mux is in use, read
the mux to figure out which type-c port signaled HPD. Once we know which
port is actually signaling HPD, inject that state into the message
received from the EC. This simplifies the rest of the logic as it can
all stay the same with respect to picking the first port to assert HPD,
etc.
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Benson Leung <bleung@chromium.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>
Cc: <chrome-platform@lists.linux.dev>
Cc: Pin-yen Lin <treapking@chromium.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
drivers/platform/chrome/cros_ec_typec.c | 79 +++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index b32abd14825c..991361abbc31 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -7,6 +7,7 @@
*/
#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
@@ -28,6 +29,8 @@ struct cros_typec_dp_bridge {
struct cros_typec_data *typec_data;
struct drm_dp_typec_bridge_dev *dev;
struct cros_typec_port *active_port;
+ struct gpio_desc *mux_gpio;
+ bool hpd_asserted;
};
#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
@@ -429,6 +432,18 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
return ret;
}
+static void cros_typec_dp_bridge_hpd_notify(void *data, enum drm_connector_status status)
+{
+ struct cros_typec_dp_bridge *dp_bridge = data;
+ struct cros_typec_data *typec = dp_bridge->typec_data;
+
+ /* Proxy the connector status as the HPD state to replay later. */
+ dp_bridge->hpd_asserted = status == connector_status_connected;
+
+ /* Refresh port state. */
+ schedule_work(&typec->port_work);
+}
+
static int cros_typec_init_dp_bridge(struct cros_typec_data *typec)
{
struct device *dev = typec->dev;
@@ -445,9 +460,19 @@ static int cros_typec_init_dp_bridge(struct cros_typec_data *typec)
typec->dp_bridge = dp_bridge;
dp_bridge->typec_data = typec;
+ dp_bridge->mux_gpio = devm_gpiod_get_optional(dev, "mux", GPIOD_ASIS);
+ if (IS_ERR(dp_bridge->mux_gpio))
+ return dev_err_probe(dev, PTR_ERR(dp_bridge->mux_gpio), "failed to get mux gpio\n");
+
dp_dev = devm_drm_dp_typec_bridge_alloc(dev, dev->of_node);
if (IS_ERR(dp_dev))
return PTR_ERR(dp_dev);
+
+ if (fwnode_property_read_bool(dev_fwnode(dev), "no-hpd")) {
+ drm_dp_typec_bridge_add_hpd_notify(dp_dev, cros_typec_dp_bridge_hpd_notify,
+ dp_bridge);
+ }
+
dp_bridge->dev = dp_dev;
return devm_drm_dp_typec_bridge_add(dev, dp_dev);
@@ -648,6 +673,59 @@ static int cros_typec_enable_usb4(struct cros_typec_data *typec,
return typec_mux_set(port->mux, &port->state);
}
+/* Inject HPD state into the EC's response if EC firmware is broken. */
+static void cros_typec_inject_hpd(struct ec_response_usb_pd_mux_info *resp,
+ struct cros_typec_port *port,
+ struct cros_typec_dp_bridge *dp_bridge)
+{
+ struct cros_typec_data *typec = port->typec_data;
+ struct gpio_desc *mux_gpio;
+ int val;
+
+ if (!dp_bridge)
+ return;
+
+ /* Don't need to inject HPD level when DP isn't enabled */
+ if (!(resp->flags & USB_PD_MUX_DP_ENABLED))
+ return;
+
+ /*
+ * The default setting is HPD deasserted. Ignore if nothing to inject.
+ */
+ if (!dp_bridge->hpd_asserted)
+ return;
+
+ /*
+ * Some ECs don't notify AP when HPD goes high or low so we have to
+ * read the EC GPIO that controls the mux to figure out which type-c
+ * port is connected to DP by the EC.
+ */
+ mux_gpio = dp_bridge->mux_gpio;
+ if (!mux_gpio)
+ return;
+
+ /*
+ * Only read the mux GPIO setting if we need to change the active_port.
+ * Otherwise, an active_port is already set and HPD going high or low
+ * doesn't change the muxed port until DP mode is exited.
+ */
+ if (!dp_bridge->active_port) {
+ val = gpiod_get_value_cansleep(mux_gpio);
+ if (val < 0) {
+ dev_err(typec->dev, "Failed to read mux gpio\n");
+ return;
+ }
+ if (typec->ports[val] != port)
+ return;
+ } else if (port != dp_bridge->active_port) {
+ return;
+ }
+
+ /* Inject HPD from the GPIO state if EC firmware is broken. */
+ if (dp_bridge->hpd_asserted)
+ resp->flags |= USB_PD_MUX_HPD_LVL;
+}
+
static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
struct ec_response_usb_pd_control_v2 *pd_ctrl)
{
@@ -669,6 +747,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
port_num, ret);
return ret;
}
+ cros_typec_inject_hpd(&resp, port, dp_bridge);
/* No change needs to be made, let's exit early. */
if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
--
https://chromeos.dev
^ permalink raw reply related [flat|nested] 49+ messages in thread