Re: [RFC PATCH 19/22] thunderbolt: Add support for Time Management Unit

2019-10-03 Thread Mika Westerberg
On Wed, Oct 02, 2019 at 04:52:06PM +, Mani, Rajmohan wrote:
> > +   /* Enable TMU if it is off */
> > +   if (!tb_switch_tmu_is_enabled(tb->root_switch))
> 
> To be consistent with the implementation of tb_switch_tmu_disable(), should we
> move the above check inside tb_switch_tmu_enable()?

Yes, I think it makes sense.


RE: [RFC PATCH 19/22] thunderbolt: Add support for Time Management Unit

2019-10-02 Thread Mani, Rajmohan
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