// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt link controller support * * Copyright (C) 2019, Intel Corporation * Author: Mika Westerberg <[email protected]> */ #include <linux/delay.h> #include "tb.h" /** * tb_lc_read_uuid() - Read switch UUID from link controller common register * @sw: Switch whose UUID is read * @uuid: UUID is placed here */ int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid) { … } static int read_lc_desc(struct tb_switch *sw, u32 *desc) { … } static int find_port_lc_cap(struct tb_port *port) { … } /** * tb_lc_reset_port() - Trigger downstream port reset through LC * @port: Port that is reset * * Triggers downstream port reset through link controller registers. * Returns %0 in case of success negative errno otherwise. Only supports * non-USB4 routers with link controller (that's Thunderbolt 2 and * Thunderbolt 3). */ int tb_lc_reset_port(struct tb_port *port) { … } static int tb_lc_set_port_configured(struct tb_port *port, bool configured) { … } /** * tb_lc_configure_port() - Let LC know about configured port * @port: Port that is set as configured * * Sets the port configured for power management purposes. */ int tb_lc_configure_port(struct tb_port *port) { … } /** * tb_lc_unconfigure_port() - Let LC know about unconfigured port * @port: Port that is set as configured * * Sets the port unconfigured for power management purposes. */ void tb_lc_unconfigure_port(struct tb_port *port) { … } static int tb_lc_set_xdomain_configured(struct tb_port *port, bool configure) { … } /** * tb_lc_configure_xdomain() - Inform LC that the link is XDomain * @port: Switch downstream port connected to another host * * Sets the lane configured for XDomain accordingly so that the LC knows * about this. Returns %0 in success and negative errno in failure. */ int tb_lc_configure_xdomain(struct tb_port *port) { … } /** * tb_lc_unconfigure_xdomain() - Unconfigure XDomain from port * @port: Switch downstream port that was connected to another host * * Unsets the lane XDomain configuration. */ void tb_lc_unconfigure_xdomain(struct tb_port *port) { … } /** * tb_lc_start_lane_initialization() - Start lane initialization * @port: Device router lane 0 adapter * * Starts lane initialization for @port after the router resumed from * sleep. Should be called for those downstream lane adapters that were * not connected (tb_lc_configure_port() was not called) before sleep. * * Returns %0 in success and negative errno in case of failure. */ int tb_lc_start_lane_initialization(struct tb_port *port) { … } /** * tb_lc_is_clx_supported() - Check whether CLx is supported by the lane adapter * @port: Lane adapter * * TB_LC_LINK_ATTR_CPS bit reflects if the link supports CLx including * active cables (if connected on the link). */ bool tb_lc_is_clx_supported(struct tb_port *port) { … } /** * tb_lc_is_usb_plugged() - Is there USB device connected to port * @port: Device router lane 0 adapter * * Returns true if the @port has USB type-C device connected. */ bool tb_lc_is_usb_plugged(struct tb_port *port) { … } /** * tb_lc_is_xhci_connected() - Is the internal xHCI connected * @port: Device router lane 0 adapter * * Returns true if the internal xHCI has been connected to @port. */ bool tb_lc_is_xhci_connected(struct tb_port *port) { … } static int __tb_lc_xhci_connect(struct tb_port *port, bool connect) { … } /** * tb_lc_xhci_connect() - Connect internal xHCI * @port: Device router lane 0 adapter * * Tells LC to connect the internal xHCI to @port. Returns %0 on success * and negative errno in case of failure. Can be called for Thunderbolt 3 * routers only. */ int tb_lc_xhci_connect(struct tb_port *port) { … } /** * tb_lc_xhci_disconnect() - Disconnect internal xHCI * @port: Device router lane 0 adapter * * Tells LC to disconnect the internal xHCI from @port. Can be called * for Thunderbolt 3 routers only. */ void tb_lc_xhci_disconnect(struct tb_port *port) { … } static int tb_lc_set_wake_one(struct tb_switch *sw, unsigned int offset, unsigned int flags) { … } /** * tb_lc_set_wake() - Enable/disable wake * @sw: Switch whose wakes to configure * @flags: Wakeup flags (%0 to disable) * * For each LC sets wake bits accordingly. */ int tb_lc_set_wake(struct tb_switch *sw, unsigned int flags) { … } /** * tb_lc_set_sleep() - Inform LC that the switch is going to sleep * @sw: Switch to set sleep * * Let the switch link controllers know that the switch is going to * sleep. */ int tb_lc_set_sleep(struct tb_switch *sw) { … } /** * tb_lc_lane_bonding_possible() - Is lane bonding possible towards switch * @sw: Switch to check * * Checks whether conditions for lane bonding from parent to @sw are * possible. */ bool tb_lc_lane_bonding_possible(struct tb_switch *sw) { … } static int tb_lc_dp_sink_from_port(const struct tb_switch *sw, struct tb_port *in) { … } static int tb_lc_dp_sink_available(struct tb_switch *sw, int sink) { … } /** * tb_lc_dp_sink_query() - Is DP sink available for DP IN port * @sw: Switch whose DP sink is queried * @in: DP IN port to check * * Queries through LC SNK_ALLOCATION registers whether DP sink is available * for the given DP IN port or not. */ bool tb_lc_dp_sink_query(struct tb_switch *sw, struct tb_port *in) { … } /** * tb_lc_dp_sink_alloc() - Allocate DP sink * @sw: Switch whose DP sink is allocated * @in: DP IN port the DP sink is allocated for * * Allocate DP sink for @in via LC SNK_ALLOCATION registers. If the * resource is available and allocation is successful returns %0. In all * other cases returs negative errno. In particular %-EBUSY is returned if * the resource was not available. */ int tb_lc_dp_sink_alloc(struct tb_switch *sw, struct tb_port *in) { … } /** * tb_lc_dp_sink_dealloc() - De-allocate DP sink * @sw: Switch whose DP sink is de-allocated * @in: DP IN port whose DP sink is de-allocated * * De-allocate DP sink from @in using LC SNK_ALLOCATION registers. */ int tb_lc_dp_sink_dealloc(struct tb_switch *sw, struct tb_port *in) { … } /** * tb_lc_force_power() - Forces LC to be powered on * @sw: Thunderbolt switch * * This is useful to let authentication cycle pass even without * a Thunderbolt link present. */ int tb_lc_force_power(struct tb_switch *sw) { … }