diff mbox series

usb: typec: mux: intel_pmc_mux: Fix DP alternate mode entry

Message ID 20200529131753.15587-1-heikki.krogerus@linux.intel.com (mailing list archive)
State Mainlined
Commit 130206a88683d859f63ed6d4a56ab5c2b4930c8e
Headers show
Series usb: typec: mux: intel_pmc_mux: Fix DP alternate mode entry | expand

Commit Message

Heikki Krogerus May 29, 2020, 1:17 p.m. UTC
The PMC needs to be notified separately about HPD (hotplug
detected) signal being high after mode entry. There is a bit
"HPD High" in the Alternate Mode Request that the driver
already sets, but that bit is only valid when the
DisplayPort Alternate Mode is directly entered from
disconnected state.

Fixes: 5c4edcdbcd97 ("usb: typec: mux: intel: Fix DP_HPD_LVL bit field")
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/typec/mux/intel_pmc_mux.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Comments

Prashant Malani May 29, 2020, 10:18 p.m. UTC | #1
Hi Heikki,

On Fri, May 29, 2020 at 04:17:53PM +0300, Heikki Krogerus wrote:
> The PMC needs to be notified separately about HPD (hotplug
> detected) signal being high after mode entry. There is a bit
> "HPD High" in the Alternate Mode Request that the driver
> already sets, but that bit is only valid when the
> DisplayPort Alternate Mode is directly entered from
> disconnected state.
> 
> Fixes: 5c4edcdbcd97 ("usb: typec: mux: intel: Fix DP_HPD_LVL bit field")
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

Tried this out; my DP monitor seems to enumerate correctly, so:

Tested-by: Prashant Malani <pmalani@chromium.org>
> ---
>  drivers/usb/typec/mux/intel_pmc_mux.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c
> index 962bc69a6a59e..70ddc9d6d49e4 100644
> --- a/drivers/usb/typec/mux/intel_pmc_mux.c
> +++ b/drivers/usb/typec/mux/intel_pmc_mux.c
> @@ -148,7 +148,8 @@ pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_mux_state *state)
>  	msg[0] = PMC_USB_DP_HPD;
>  	msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
>  
> -	msg[1] = PMC_USB_DP_HPD_IRQ;
> +	if (data->status & DP_STATUS_IRQ_HPD)
> +		msg[1] = PMC_USB_DP_HPD_IRQ;
>  
>  	if (data->status & DP_STATUS_HPD_STATE)
>  		msg[1] |= PMC_USB_DP_HPD_LVL;
> @@ -161,6 +162,7 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
>  {
>  	struct typec_displayport_data *data = state->data;
>  	struct altmode_req req = { };
> +	int ret;
>  
>  	if (data->status & DP_STATUS_IRQ_HPD)
>  		return pmc_usb_mux_dp_hpd(port, state);
> @@ -181,7 +183,14 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
>  	if (data->status & DP_STATUS_HPD_STATE)
>  		req.mode_data |= PMC_USB_ALTMODE_HPD_HIGH;
>  
> -	return pmc_usb_command(port, (void *)&req, sizeof(req));
> +	ret = pmc_usb_command(port, (void *)&req, sizeof(req));
> +	if (ret)
> +		return ret;
> +
> +	if (data->status & DP_STATUS_HPD_STATE)
> +		return pmc_usb_mux_dp_hpd(port, state);
> +
> +	return 0;
>  }
>  
>  static int
> -- 
> 2.26.2
>
diff mbox series

Patch

diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c
index 962bc69a6a59e..70ddc9d6d49e4 100644
--- a/drivers/usb/typec/mux/intel_pmc_mux.c
+++ b/drivers/usb/typec/mux/intel_pmc_mux.c
@@ -148,7 +148,8 @@  pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_mux_state *state)
 	msg[0] = PMC_USB_DP_HPD;
 	msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
 
-	msg[1] = PMC_USB_DP_HPD_IRQ;
+	if (data->status & DP_STATUS_IRQ_HPD)
+		msg[1] = PMC_USB_DP_HPD_IRQ;
 
 	if (data->status & DP_STATUS_HPD_STATE)
 		msg[1] |= PMC_USB_DP_HPD_LVL;
@@ -161,6 +162,7 @@  pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
 {
 	struct typec_displayport_data *data = state->data;
 	struct altmode_req req = { };
+	int ret;
 
 	if (data->status & DP_STATUS_IRQ_HPD)
 		return pmc_usb_mux_dp_hpd(port, state);
@@ -181,7 +183,14 @@  pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)
 	if (data->status & DP_STATUS_HPD_STATE)
 		req.mode_data |= PMC_USB_ALTMODE_HPD_HIGH;
 
-	return pmc_usb_command(port, (void *)&req, sizeof(req));
+	ret = pmc_usb_command(port, (void *)&req, sizeof(req));
+	if (ret)
+		return ret;
+
+	if (data->status & DP_STATUS_HPD_STATE)
+		return pmc_usb_mux_dp_hpd(port, state);
+
+	return 0;
 }
 
 static int