Hi Mika,
> -Original Message-
> From: Mika Westerberg [mailto:mika.westerb...@linux.intel.com]
> Sent: Tuesday, October 01, 2019 4:38 AM
> To: linux-...@vger.kernel.org
> Cc: Andreas Noever ; Jamet, Michael
> ; Mika Westerberg
> ; Yehezkel Bernat
> ; Mani, Rajmohan ;
> Nicholas Johnson ; Lukas
> Wunner ; Greg Kroah-Hartman
> ; Alan Stern ;
> mario.limoncie...@dell.com; Anthony Wong
> ; linux-kernel@vger.kernel.org
> Subject: [RFC PATCH 19/22] thunderbolt: Add support for Time Management
> Unit
>
> From: Rajmohan Mani
>
> Time Management Unit (TMU) is included in each USB4 router. It is used to
> synchronize time across the USB4 fabric. By default when USB4 router is
> plugged to the domain, its TMU is turned off. This differs from Thunderbolt
> (1,
> 2 and 3) devices whose TMU is by default configured to bi-directional HiFi
> mode. Since time synchronization is needed for proper Display Port tunneling
> this means we need to configure the TMU on
> USB4 compliant devices.
>
> The USB4 spec allows some flexibility on how the TMU can be configured.
> This makes it possible to enable link power management states (CLx) in certain
> topologies, where for example DP tunneling is not used. TMU can also be re-
> configured dynamicaly depending on types of tunnels created over the USB4
> fabric.
>
> In this patch we simply configure the TMU to be in bi-directional HiFi mode.
> This way we can tunnel any kind of traffic without need to perform complex
> steps to re-configure the domain dynamically. We can add more fine-grained
> TMU configuration later on when we start enabling CLx states.
>
> Signed-off-by: Rajmohan Mani
> Co-developed-by: Mika Westerberg
> Signed-off-by: Mika Westerberg
> ---
> drivers/thunderbolt/Makefile | 2 +-
> drivers/thunderbolt/switch.c | 4 +
> drivers/thunderbolt/tb.c | 29 +++
> drivers/thunderbolt/tb.h | 47 +
> drivers/thunderbolt/tb_regs.h | 20 ++
> drivers/thunderbolt/tmu.c | 380 ++
> 6 files changed, 481 insertions(+), 1 deletion(-) create mode 100644
> drivers/thunderbolt/tmu.c
>
> diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile index
> c0b2fd73dfbd..2014bc840b06 100644
> --- a/drivers/thunderbolt/Makefile
> +++ b/drivers/thunderbolt/Makefile
> @@ -1,4 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0-only obj-${CONFIG_THUNDERBOLT} :=
> thunderbolt.o thunderbolt-objs := nhi.o nhi_ops.o ctl.o tb.o switch.o cap.o
> path.o tunnel.o eeprom.o -thunderbolt-objs += domain.o dma_port.o icm.o
> property.o xdomain.o lc.o usb4.o
> +thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o
> +tmu.o usb4.o
> diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index
> 2ccd1004920e..58e3f54ddbb9 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -2278,6 +2278,10 @@ int tb_switch_add(struct tb_switch *sw)
> ret = tb_switch_update_link_attributes(sw);
> if (ret)
> return ret;
> +
> + ret = tb_switch_tmu_init(sw);
> + if (ret)
> + return ret;
> }
>
> ret = device_add(&sw->dev);
> diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index
> 24e37e47dc48..f2868c125637 100644
> --- a/drivers/thunderbolt/tb.c
> +++ b/drivers/thunderbolt/tb.c
> @@ -161,6 +161,25 @@ static void tb_scan_xdomain(struct tb_port *port)
> }
> }
>
> +static int tb_enable_tmu(struct tb_switch *sw) {
> + int ret;
> +
> + /* If it is already enabled in correct mode, don't touch it */
> + if (tb_switch_tmu_is_enabled(sw))
> + return 0;
> +
> + ret = tb_switch_tmu_disable(sw);
> + if (ret)
> + return ret;
> +
> + ret = tb_switch_tmu_post_time(sw);
> + if (ret)
> + return ret;
> +
> + return tb_switch_tmu_enable(sw);
> +}
> +
> static void tb_scan_port(struct tb_port *port);
>
> /**
> @@ -263,6 +282,9 @@ static void tb_scan_port(struct tb_port *port)
> if (tb_switch_lane_bonding_enable(sw))
> tb_sw_warn(sw, "failed to enable lane bonding\n");
>
> + if (tb_enable_tmu(sw))
> + tb_sw_warn(sw, "failed to enable TMU\n");
> +
> tb_scan_switch(sw);
> }
>
> @@ -713,6 +735,7 @@ static void tb_handle_hotplug(struct work_struct
> *work)
> tb_sw_set_unplugged(port->remote->sw);
> tb_free_invalid_tunnels(tb);
> tb_remove_dp_resources(port->remote->sw);
> + tb_switch_tmu_disable(port->remote->sw);
> tb_switch_lane_bonding_disable(port->remote->sw);
> tb_switch_remove(port->remote->sw);
> port->remote = NULL;
> @@ -860,6 +883,9 @@ static int tb_start(struct tb *tb)
> return ret;
> }
>
> + /* Enable TMU if it is off */
> + if (!tb_switch_tmu_is_enabled(tb->root