Commit 6026b703 authored by Mika Westerberg's avatar Mika Westerberg
Browse files

thunderbolt: Add wake from DisplayPort



Latest USB4 spec added a new wake bit for DisplayPort so add this to the
driver when runtime suspending. This way wake up the domain when a new
monitor is plugged in to any of the device routers.

Also do the same for pre-USB4 devices through the link controller
registers as documented in chapter 13 of the USB4 spec.

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 68977e61
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -208,8 +208,8 @@ static int tb_lc_set_wake_one(struct tb_switch *sw, unsigned int offset,
	if (ret)
		return ret;

	ctrl &= ~(TB_LC_SX_CTRL_WOC | TB_LC_SX_CTRL_WOD | TB_LC_SX_CTRL_WOP |
		  TB_LC_SX_CTRL_WOU4);
	ctrl &= ~(TB_LC_SX_CTRL_WOC | TB_LC_SX_CTRL_WOD | TB_LC_SX_CTRL_WODPC |
		  TB_LC_SX_CTRL_WODPD | TB_LC_SX_CTRL_WOP | TB_LC_SX_CTRL_WOU4);

	if (flags & TB_WAKE_ON_CONNECT)
		ctrl |= TB_LC_SX_CTRL_WOC | TB_LC_SX_CTRL_WOD;
@@ -217,6 +217,8 @@ static int tb_lc_set_wake_one(struct tb_switch *sw, unsigned int offset,
		ctrl |= TB_LC_SX_CTRL_WOU4;
	if (flags & TB_WAKE_ON_PCIE)
		ctrl |= TB_LC_SX_CTRL_WOP;
	if (flags & TB_WAKE_ON_DP)
		ctrl |= TB_LC_SX_CTRL_WODPC | TB_LC_SX_CTRL_WODPD;

	return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, offset + TB_LC_SX_CTRL, 1);
}
+2 −1
Original line number Diff line number Diff line
@@ -2844,7 +2844,8 @@ void tb_switch_suspend(struct tb_switch *sw, bool runtime)
	if (runtime) {
		/* Trigger wake when something is plugged in/out */
		flags |= TB_WAKE_ON_CONNECT | TB_WAKE_ON_DISCONNECT;
		flags |= TB_WAKE_ON_USB4 | TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE;
		flags |= TB_WAKE_ON_USB4;
		flags |= TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE | TB_WAKE_ON_DP;
	} else if (device_may_wakeup(&sw->dev)) {
		flags |= TB_WAKE_ON_USB4 | TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE;
	}
+1 −0
Original line number Diff line number Diff line
@@ -347,6 +347,7 @@ struct tb_path {
#define TB_WAKE_ON_USB4		BIT(2)
#define TB_WAKE_ON_USB3		BIT(3)
#define TB_WAKE_ON_PCIE		BIT(4)
#define TB_WAKE_ON_DP		BIT(5)

/**
 * struct tb_cm_ops - Connection manager specific operations vector
+3 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ struct tb_regs_switch_header {
#define ROUTER_CS_5_SLP				BIT(0)
#define ROUTER_CS_5_WOP				BIT(1)
#define ROUTER_CS_5_WOU				BIT(2)
#define ROUTER_CS_5_WOD				BIT(3)
#define ROUTER_CS_5_C3S				BIT(23)
#define ROUTER_CS_5_PTO				BIT(24)
#define ROUTER_CS_5_UTO				BIT(25)
@@ -458,6 +459,8 @@ struct tb_regs_hop {
#define TB_LC_SX_CTRL			0x96
#define TB_LC_SX_CTRL_WOC		BIT(1)
#define TB_LC_SX_CTRL_WOD		BIT(2)
#define TB_LC_SX_CTRL_WODPC		BIT(3)
#define TB_LC_SX_CTRL_WODPD		BIT(4)
#define TB_LC_SX_CTRL_WOU4		BIT(5)
#define TB_LC_SX_CTRL_WOP		BIT(6)
#define TB_LC_SX_CTRL_L1C		BIT(16)
+4 −2
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
	}

	/*
	 * Enable wakes from PCIe and USB 3.x on this router. Only
	 * Enable wakes from PCIe, USB 3.x and DP on this router. Only
	 * needed for device routers.
	 */
	if (route) {
@@ -421,11 +421,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
		if (ret)
			return ret;

		val &= ~(ROUTER_CS_5_WOP | ROUTER_CS_5_WOU);
		val &= ~(ROUTER_CS_5_WOP | ROUTER_CS_5_WOU | ROUTER_CS_5_WOD);
		if (flags & TB_WAKE_ON_USB3)
			val |= ROUTER_CS_5_WOU;
		if (flags & TB_WAKE_ON_PCIE)
			val |= ROUTER_CS_5_WOP;
		if (flags & TB_WAKE_ON_DP)
			val |= ROUTER_CS_5_WOD;

		ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);
		if (ret)