brintos

brintos / linux-shallow public Read only

0
0
Text · 73.5 KiB · 402fdf8 Raw
3012 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * USB4 specific functionality4 *5 * Copyright (C) 2019, Intel Corporation6 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>7 *	    Rajmohan Mani <rajmohan.mani@intel.com>8 */9 10#include <linux/delay.h>11#include <linux/ktime.h>12#include <linux/units.h>13 14#include "sb_regs.h"15#include "tb.h"16 17#define USB4_DATA_RETRIES		318#define USB4_DATA_DWORDS		1619 20#define USB4_NVM_READ_OFFSET_MASK	GENMASK(23, 2)21#define USB4_NVM_READ_OFFSET_SHIFT	222#define USB4_NVM_READ_LENGTH_MASK	GENMASK(27, 24)23#define USB4_NVM_READ_LENGTH_SHIFT	2424 25#define USB4_NVM_SET_OFFSET_MASK	USB4_NVM_READ_OFFSET_MASK26#define USB4_NVM_SET_OFFSET_SHIFT	USB4_NVM_READ_OFFSET_SHIFT27 28#define USB4_DROM_ADDRESS_MASK		GENMASK(14, 2)29#define USB4_DROM_ADDRESS_SHIFT		230#define USB4_DROM_SIZE_MASK		GENMASK(19, 15)31#define USB4_DROM_SIZE_SHIFT		1532 33#define USB4_NVM_SECTOR_SIZE_MASK	GENMASK(23, 0)34 35#define USB4_BA_LENGTH_MASK		GENMASK(7, 0)36#define USB4_BA_INDEX_MASK		GENMASK(15, 0)37 38enum usb4_ba_index {39	USB4_BA_MAX_USB3 = 0x1,40	USB4_BA_MIN_DP_AUX = 0x2,41	USB4_BA_MIN_DP_MAIN = 0x3,42	USB4_BA_MAX_PCIE = 0x4,43	USB4_BA_MAX_HI = 0x5,44};45 46#define USB4_BA_VALUE_MASK		GENMASK(31, 16)47#define USB4_BA_VALUE_SHIFT		1648 49/* Delays in us used with usb4_port_wait_for_bit() */50#define USB4_PORT_DELAY			5051#define USB4_PORT_SB_DELAY		100052 53static int usb4_native_switch_op(struct tb_switch *sw, u16 opcode,54				 u32 *metadata, u8 *status,55				 const void *tx_data, size_t tx_dwords,56				 void *rx_data, size_t rx_dwords)57{58	u32 val;59	int ret;60 61	if (metadata) {62		ret = tb_sw_write(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);63		if (ret)64			return ret;65	}66	if (tx_dwords) {67		ret = tb_sw_write(sw, tx_data, TB_CFG_SWITCH, ROUTER_CS_9,68				  tx_dwords);69		if (ret)70			return ret;71	}72 73	val = opcode | ROUTER_CS_26_OV;74	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);75	if (ret)76		return ret;77 78	ret = tb_switch_wait_for_bit(sw, ROUTER_CS_26, ROUTER_CS_26_OV, 0, 500);79	if (ret)80		return ret;81 82	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);83	if (ret)84		return ret;85 86	if (val & ROUTER_CS_26_ONS)87		return -EOPNOTSUPP;88 89	if (status)90		*status = (val & ROUTER_CS_26_STATUS_MASK) >>91			ROUTER_CS_26_STATUS_SHIFT;92 93	if (metadata) {94		ret = tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);95		if (ret)96			return ret;97	}98	if (rx_dwords) {99		ret = tb_sw_read(sw, rx_data, TB_CFG_SWITCH, ROUTER_CS_9,100				 rx_dwords);101		if (ret)102			return ret;103	}104 105	return 0;106}107 108static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,109			    u8 *status, const void *tx_data, size_t tx_dwords,110			    void *rx_data, size_t rx_dwords)111{112	const struct tb_cm_ops *cm_ops = sw->tb->cm_ops;113 114	if (tx_dwords > USB4_DATA_DWORDS || rx_dwords > USB4_DATA_DWORDS)115		return -EINVAL;116 117	/*118	 * If the connection manager implementation provides USB4 router119	 * operation proxy callback, call it here instead of running the120	 * operation natively.121	 */122	if (cm_ops->usb4_switch_op) {123		int ret;124 125		ret = cm_ops->usb4_switch_op(sw, opcode, metadata, status,126					     tx_data, tx_dwords, rx_data,127					     rx_dwords);128		if (ret != -EOPNOTSUPP)129			return ret;130 131		/*132		 * If the proxy was not supported then run the native133		 * router operation instead.134		 */135	}136 137	return usb4_native_switch_op(sw, opcode, metadata, status, tx_data,138				     tx_dwords, rx_data, rx_dwords);139}140 141static inline int usb4_switch_op(struct tb_switch *sw, u16 opcode,142				 u32 *metadata, u8 *status)143{144	return __usb4_switch_op(sw, opcode, metadata, status, NULL, 0, NULL, 0);145}146 147static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,148				      u32 *metadata, u8 *status,149				      const void *tx_data, size_t tx_dwords,150				      void *rx_data, size_t rx_dwords)151{152	return __usb4_switch_op(sw, opcode, metadata, status, tx_data,153				tx_dwords, rx_data, rx_dwords);154}155 156/**157 * usb4_switch_check_wakes() - Check for wakes and notify PM core about them158 * @sw: Router whose wakes to check159 *160 * Checks wakes occurred during suspend and notify the PM core about them.161 */162void usb4_switch_check_wakes(struct tb_switch *sw)163{164	bool wakeup_usb4 = false;165	struct usb4_port *usb4;166	struct tb_port *port;167	bool wakeup = false;168	u32 val;169 170	if (tb_route(sw)) {171		if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1))172			return;173 174		tb_sw_dbg(sw, "PCIe wake: %s, USB3 wake: %s\n",175			  (val & ROUTER_CS_6_WOPS) ? "yes" : "no",176			  (val & ROUTER_CS_6_WOUS) ? "yes" : "no");177 178		wakeup = val & (ROUTER_CS_6_WOPS | ROUTER_CS_6_WOUS);179	}180 181	/*182	 * Check for any downstream ports for USB4 wake,183	 * connection wake and disconnection wake.184	 */185	tb_switch_for_each_port(sw, port) {186		if (!port->cap_usb4)187			continue;188 189		if (tb_port_read(port, &val, TB_CFG_PORT,190				 port->cap_usb4 + PORT_CS_18, 1))191			break;192 193		tb_port_dbg(port, "USB4 wake: %s, connection wake: %s, disconnection wake: %s\n",194			    (val & PORT_CS_18_WOU4S) ? "yes" : "no",195			    (val & PORT_CS_18_WOCS) ? "yes" : "no",196			    (val & PORT_CS_18_WODS) ? "yes" : "no");197 198		wakeup_usb4 = val & (PORT_CS_18_WOU4S | PORT_CS_18_WOCS |199				     PORT_CS_18_WODS);200 201		usb4 = port->usb4;202		if (device_may_wakeup(&usb4->dev) && wakeup_usb4)203			pm_wakeup_event(&usb4->dev, 0);204 205		wakeup |= wakeup_usb4;206	}207 208	if (wakeup)209		pm_wakeup_event(&sw->dev, 0);210}211 212static bool link_is_usb4(struct tb_port *port)213{214	u32 val;215 216	if (!port->cap_usb4)217		return false;218 219	if (tb_port_read(port, &val, TB_CFG_PORT,220			 port->cap_usb4 + PORT_CS_18, 1))221		return false;222 223	return !(val & PORT_CS_18_TCM);224}225 226/**227 * usb4_switch_setup() - Additional setup for USB4 device228 * @sw: USB4 router to setup229 *230 * USB4 routers need additional settings in order to enable all the231 * tunneling. This function enables USB and PCIe tunneling if it can be232 * enabled (e.g the parent switch also supports them). If USB tunneling233 * is not available for some reason (like that there is Thunderbolt 3234 * switch upstream) then the internal xHCI controller is enabled235 * instead.236 *237 * This does not set the configuration valid bit of the router. To do238 * that call usb4_switch_configuration_valid().239 */240int usb4_switch_setup(struct tb_switch *sw)241{242	struct tb_switch *parent = tb_switch_parent(sw);243	struct tb_port *down;244	bool tbt3, xhci;245	u32 val = 0;246	int ret;247 248	if (!tb_route(sw))249		return 0;250 251	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1);252	if (ret)253		return ret;254 255	down = tb_switch_downstream_port(sw);256	sw->link_usb4 = link_is_usb4(down);257	tb_sw_dbg(sw, "link: %s\n", sw->link_usb4 ? "USB4" : "TBT");258 259	xhci = val & ROUTER_CS_6_HCI;260	tbt3 = !(val & ROUTER_CS_6_TNS);261 262	tb_sw_dbg(sw, "TBT3 support: %s, xHCI: %s\n",263		  tbt3 ? "yes" : "no", xhci ? "yes" : "no");264 265	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);266	if (ret)267		return ret;268 269	if (tb_acpi_may_tunnel_usb3() && sw->link_usb4 &&270	    tb_switch_find_port(parent, TB_TYPE_USB3_DOWN)) {271		val |= ROUTER_CS_5_UTO;272		xhci = false;273	}274 275	/*276	 * Only enable PCIe tunneling if the parent router supports it277	 * and it is not disabled.278	 */279	if (tb_acpi_may_tunnel_pcie() &&280	    tb_switch_find_port(parent, TB_TYPE_PCIE_DOWN)) {281		val |= ROUTER_CS_5_PTO;282		/*283		 * xHCI can be enabled if PCIe tunneling is supported284		 * and the parent does not have any USB3 dowstream285		 * adapters (so we cannot do USB 3.x tunneling).286		 */287		if (xhci)288			val |= ROUTER_CS_5_HCO;289	}290 291	/* TBT3 supported by the CM */292	val &= ~ROUTER_CS_5_CNS;293 294	return tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);295}296 297/**298 * usb4_switch_configuration_valid() - Set tunneling configuration to be valid299 * @sw: USB4 router300 *301 * Sets configuration valid bit for the router. Must be called before302 * any tunnels can be set through the router and after303 * usb4_switch_setup() has been called. Can be called to host and device304 * routers (does nothing for the latter).305 *306 * Returns %0 in success and negative errno otherwise.307 */308int usb4_switch_configuration_valid(struct tb_switch *sw)309{310	u32 val;311	int ret;312 313	if (!tb_route(sw))314		return 0;315 316	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);317	if (ret)318		return ret;319 320	val |= ROUTER_CS_5_CV;321 322	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);323	if (ret)324		return ret;325 326	return tb_switch_wait_for_bit(sw, ROUTER_CS_6, ROUTER_CS_6_CR,327				      ROUTER_CS_6_CR, 50);328}329 330/**331 * usb4_switch_read_uid() - Read UID from USB4 router332 * @sw: USB4 router333 * @uid: UID is stored here334 *335 * Reads 64-bit UID from USB4 router config space.336 */337int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid)338{339	return tb_sw_read(sw, uid, TB_CFG_SWITCH, ROUTER_CS_7, 2);340}341 342static int usb4_switch_drom_read_block(void *data,343				       unsigned int dwaddress, void *buf,344				       size_t dwords)345{346	struct tb_switch *sw = data;347	u8 status = 0;348	u32 metadata;349	int ret;350 351	metadata = (dwords << USB4_DROM_SIZE_SHIFT) & USB4_DROM_SIZE_MASK;352	metadata |= (dwaddress << USB4_DROM_ADDRESS_SHIFT) &353		USB4_DROM_ADDRESS_MASK;354 355	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_DROM_READ, &metadata,356				  &status, NULL, 0, buf, dwords);357	if (ret)358		return ret;359 360	return status ? -EIO : 0;361}362 363/**364 * usb4_switch_drom_read() - Read arbitrary bytes from USB4 router DROM365 * @sw: USB4 router366 * @address: Byte address inside DROM to start reading367 * @buf: Buffer where the DROM content is stored368 * @size: Number of bytes to read from DROM369 *370 * Uses USB4 router operations to read router DROM. For devices this371 * should always work but for hosts it may return %-EOPNOTSUPP in which372 * case the host router does not have DROM.373 */374int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,375			  size_t size)376{377	return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES,378				usb4_switch_drom_read_block, sw);379}380 381/**382 * usb4_switch_lane_bonding_possible() - Are conditions met for lane bonding383 * @sw: USB4 router384 *385 * Checks whether conditions are met so that lane bonding can be386 * established with the upstream router. Call only for device routers.387 */388bool usb4_switch_lane_bonding_possible(struct tb_switch *sw)389{390	struct tb_port *up;391	int ret;392	u32 val;393 394	up = tb_upstream_port(sw);395	ret = tb_port_read(up, &val, TB_CFG_PORT, up->cap_usb4 + PORT_CS_18, 1);396	if (ret)397		return false;398 399	return !!(val & PORT_CS_18_BE);400}401 402/**403 * usb4_switch_set_wake() - Enabled/disable wake404 * @sw: USB4 router405 * @flags: Wakeup flags (%0 to disable)406 *407 * Enables/disables router to wake up from sleep.408 */409int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)410{411	struct usb4_port *usb4;412	struct tb_port *port;413	u64 route = tb_route(sw);414	u32 val;415	int ret;416 417	/*418	 * Enable wakes coming from all USB4 downstream ports (from419	 * child routers). For device routers do this also for the420	 * upstream USB4 port.421	 */422	tb_switch_for_each_port(sw, port) {423		if (!tb_port_is_null(port))424			continue;425		if (!route && tb_is_upstream_port(port))426			continue;427		if (!port->cap_usb4)428			continue;429 430		ret = tb_port_read(port, &val, TB_CFG_PORT,431				   port->cap_usb4 + PORT_CS_19, 1);432		if (ret)433			return ret;434 435		val &= ~(PORT_CS_19_WOC | PORT_CS_19_WOD | PORT_CS_19_WOU4);436 437		if (tb_is_upstream_port(port)) {438			val |= PORT_CS_19_WOU4;439		} else {440			bool configured = val & PORT_CS_19_PC;441			usb4 = port->usb4;442 443			if (((flags & TB_WAKE_ON_CONNECT) |444			      device_may_wakeup(&usb4->dev)) && !configured)445				val |= PORT_CS_19_WOC;446			if (((flags & TB_WAKE_ON_DISCONNECT) |447			      device_may_wakeup(&usb4->dev)) && configured)448				val |= PORT_CS_19_WOD;449			if ((flags & TB_WAKE_ON_USB4) && configured)450				val |= PORT_CS_19_WOU4;451		}452 453		ret = tb_port_write(port, &val, TB_CFG_PORT,454				    port->cap_usb4 + PORT_CS_19, 1);455		if (ret)456			return ret;457	}458 459	/*460	 * Enable wakes from PCIe, USB 3.x and DP on this router. Only461	 * needed for device routers.462	 */463	if (route) {464		ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);465		if (ret)466			return ret;467 468		val &= ~(ROUTER_CS_5_WOP | ROUTER_CS_5_WOU | ROUTER_CS_5_WOD);469		if (flags & TB_WAKE_ON_USB3)470			val |= ROUTER_CS_5_WOU;471		if (flags & TB_WAKE_ON_PCIE)472			val |= ROUTER_CS_5_WOP;473		if (flags & TB_WAKE_ON_DP)474			val |= ROUTER_CS_5_WOD;475 476		ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);477		if (ret)478			return ret;479	}480 481	return 0;482}483 484/**485 * usb4_switch_set_sleep() - Prepare the router to enter sleep486 * @sw: USB4 router487 *488 * Sets sleep bit for the router. Returns when the router sleep ready489 * bit has been asserted.490 */491int usb4_switch_set_sleep(struct tb_switch *sw)492{493	int ret;494	u32 val;495 496	/* Set sleep bit and wait for sleep ready to be asserted */497	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);498	if (ret)499		return ret;500 501	val |= ROUTER_CS_5_SLP;502 503	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_5, 1);504	if (ret)505		return ret;506 507	return tb_switch_wait_for_bit(sw, ROUTER_CS_6, ROUTER_CS_6_SLPR,508				      ROUTER_CS_6_SLPR, 500);509}510 511/**512 * usb4_switch_nvm_sector_size() - Return router NVM sector size513 * @sw: USB4 router514 *515 * If the router supports NVM operations this function returns the NVM516 * sector size in bytes. If NVM operations are not supported returns517 * %-EOPNOTSUPP.518 */519int usb4_switch_nvm_sector_size(struct tb_switch *sw)520{521	u32 metadata;522	u8 status;523	int ret;524 525	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SECTOR_SIZE, &metadata,526			     &status);527	if (ret)528		return ret;529 530	if (status)531		return status == 0x2 ? -EOPNOTSUPP : -EIO;532 533	return metadata & USB4_NVM_SECTOR_SIZE_MASK;534}535 536static int usb4_switch_nvm_read_block(void *data,537	unsigned int dwaddress, void *buf, size_t dwords)538{539	struct tb_switch *sw = data;540	u8 status = 0;541	u32 metadata;542	int ret;543 544	metadata = (dwords << USB4_NVM_READ_LENGTH_SHIFT) &545		   USB4_NVM_READ_LENGTH_MASK;546	metadata |= (dwaddress << USB4_NVM_READ_OFFSET_SHIFT) &547		   USB4_NVM_READ_OFFSET_MASK;548 549	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_NVM_READ, &metadata,550				  &status, NULL, 0, buf, dwords);551	if (ret)552		return ret;553 554	return status ? -EIO : 0;555}556 557/**558 * usb4_switch_nvm_read() - Read arbitrary bytes from router NVM559 * @sw: USB4 router560 * @address: Starting address in bytes561 * @buf: Read data is placed here562 * @size: How many bytes to read563 *564 * Reads NVM contents of the router. If NVM is not supported returns565 * %-EOPNOTSUPP.566 */567int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf,568			 size_t size)569{570	return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES,571				usb4_switch_nvm_read_block, sw);572}573 574/**575 * usb4_switch_nvm_set_offset() - Set NVM write offset576 * @sw: USB4 router577 * @address: Start offset578 *579 * Explicitly sets NVM write offset. Normally when writing to NVM this580 * is done automatically by usb4_switch_nvm_write().581 *582 * Returns %0 in success and negative errno if there was a failure.583 */584int usb4_switch_nvm_set_offset(struct tb_switch *sw, unsigned int address)585{586	u32 metadata, dwaddress;587	u8 status = 0;588	int ret;589 590	dwaddress = address / 4;591	metadata = (dwaddress << USB4_NVM_SET_OFFSET_SHIFT) &592		   USB4_NVM_SET_OFFSET_MASK;593 594	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SET_OFFSET, &metadata,595			     &status);596	if (ret)597		return ret;598 599	return status ? -EIO : 0;600}601 602static int usb4_switch_nvm_write_next_block(void *data, unsigned int dwaddress,603					    const void *buf, size_t dwords)604{605	struct tb_switch *sw = data;606	u8 status;607	int ret;608 609	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_NVM_WRITE, NULL, &status,610				  buf, dwords, NULL, 0);611	if (ret)612		return ret;613 614	return status ? -EIO : 0;615}616 617/**618 * usb4_switch_nvm_write() - Write to the router NVM619 * @sw: USB4 router620 * @address: Start address where to write in bytes621 * @buf: Pointer to the data to write622 * @size: Size of @buf in bytes623 *624 * Writes @buf to the router NVM using USB4 router operations. If NVM625 * write is not supported returns %-EOPNOTSUPP.626 */627int usb4_switch_nvm_write(struct tb_switch *sw, unsigned int address,628			  const void *buf, size_t size)629{630	int ret;631 632	ret = usb4_switch_nvm_set_offset(sw, address);633	if (ret)634		return ret;635 636	return tb_nvm_write_data(address, buf, size, USB4_DATA_RETRIES,637				 usb4_switch_nvm_write_next_block, sw);638}639 640/**641 * usb4_switch_nvm_authenticate() - Authenticate new NVM642 * @sw: USB4 router643 *644 * After the new NVM has been written via usb4_switch_nvm_write(), this645 * function triggers NVM authentication process. The router gets power646 * cycled and if the authentication is successful the new NVM starts647 * running. In case of failure returns negative errno.648 *649 * The caller should call usb4_switch_nvm_authenticate_status() to read650 * the status of the authentication after power cycle. It should be the651 * first router operation to avoid the status being lost.652 */653int usb4_switch_nvm_authenticate(struct tb_switch *sw)654{655	int ret;656 657	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_AUTH, NULL, NULL);658	switch (ret) {659	/*660	 * The router is power cycled once NVM_AUTH is started so it is661	 * expected to get any of the following errors back.662	 */663	case -EACCES:664	case -ENOTCONN:665	case -ETIMEDOUT:666		return 0;667 668	default:669		return ret;670	}671}672 673/**674 * usb4_switch_nvm_authenticate_status() - Read status of last NVM authenticate675 * @sw: USB4 router676 * @status: Status code of the operation677 *678 * The function checks if there is status available from the last NVM679 * authenticate router operation. If there is status then %0 is returned680 * and the status code is placed in @status. Returns negative errno in case681 * of failure.682 *683 * Must be called before any other router operation.684 */685int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status)686{687	const struct tb_cm_ops *cm_ops = sw->tb->cm_ops;688	u16 opcode;689	u32 val;690	int ret;691 692	if (cm_ops->usb4_switch_nvm_authenticate_status) {693		ret = cm_ops->usb4_switch_nvm_authenticate_status(sw, status);694		if (ret != -EOPNOTSUPP)695			return ret;696	}697 698	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);699	if (ret)700		return ret;701 702	/* Check that the opcode is correct */703	opcode = val & ROUTER_CS_26_OPCODE_MASK;704	if (opcode == USB4_SWITCH_OP_NVM_AUTH) {705		if (val & ROUTER_CS_26_OV)706			return -EBUSY;707		if (val & ROUTER_CS_26_ONS)708			return -EOPNOTSUPP;709 710		*status = (val & ROUTER_CS_26_STATUS_MASK) >>711			ROUTER_CS_26_STATUS_SHIFT;712	} else {713		*status = 0;714	}715 716	return 0;717}718 719/**720 * usb4_switch_credits_init() - Read buffer allocation parameters721 * @sw: USB4 router722 *723 * Reads @sw buffer allocation parameters and initializes @sw buffer724 * allocation fields accordingly. Specifically @sw->credits_allocation725 * is set to %true if these parameters can be used in tunneling.726 *727 * Returns %0 on success and negative errno otherwise.728 */729int usb4_switch_credits_init(struct tb_switch *sw)730{731	int max_usb3, min_dp_aux, min_dp_main, max_pcie, max_dma;732	int ret, length, i, nports;733	const struct tb_port *port;734	u32 data[USB4_DATA_DWORDS];735	u32 metadata = 0;736	u8 status = 0;737 738	memset(data, 0, sizeof(data));739	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_BUFFER_ALLOC, &metadata,740				  &status, NULL, 0, data, ARRAY_SIZE(data));741	if (ret)742		return ret;743	if (status)744		return -EIO;745 746	length = metadata & USB4_BA_LENGTH_MASK;747	if (WARN_ON(length > ARRAY_SIZE(data)))748		return -EMSGSIZE;749 750	max_usb3 = -1;751	min_dp_aux = -1;752	min_dp_main = -1;753	max_pcie = -1;754	max_dma = -1;755 756	tb_sw_dbg(sw, "credit allocation parameters:\n");757 758	for (i = 0; i < length; i++) {759		u16 index, value;760 761		index = data[i] & USB4_BA_INDEX_MASK;762		value = (data[i] & USB4_BA_VALUE_MASK) >> USB4_BA_VALUE_SHIFT;763 764		switch (index) {765		case USB4_BA_MAX_USB3:766			tb_sw_dbg(sw, " USB3: %u\n", value);767			max_usb3 = value;768			break;769		case USB4_BA_MIN_DP_AUX:770			tb_sw_dbg(sw, " DP AUX: %u\n", value);771			min_dp_aux = value;772			break;773		case USB4_BA_MIN_DP_MAIN:774			tb_sw_dbg(sw, " DP main: %u\n", value);775			min_dp_main = value;776			break;777		case USB4_BA_MAX_PCIE:778			tb_sw_dbg(sw, " PCIe: %u\n", value);779			max_pcie = value;780			break;781		case USB4_BA_MAX_HI:782			tb_sw_dbg(sw, " DMA: %u\n", value);783			max_dma = value;784			break;785		default:786			tb_sw_dbg(sw, " unknown credit allocation index %#x, skipping\n",787				  index);788			break;789		}790	}791 792	/*793	 * Validate the buffer allocation preferences. If we find794	 * issues, log a warning and fall back using the hard-coded795	 * values.796	 */797 798	/* Host router must report baMaxHI */799	if (!tb_route(sw) && max_dma < 0) {800		tb_sw_warn(sw, "host router is missing baMaxHI\n");801		goto err_invalid;802	}803 804	nports = 0;805	tb_switch_for_each_port(sw, port) {806		if (tb_port_is_null(port))807			nports++;808	}809 810	/* Must have DP buffer allocation (multiple USB4 ports) */811	if (nports > 2 && (min_dp_aux < 0 || min_dp_main < 0)) {812		tb_sw_warn(sw, "multiple USB4 ports require baMinDPaux/baMinDPmain\n");813		goto err_invalid;814	}815 816	tb_switch_for_each_port(sw, port) {817		if (tb_port_is_dpout(port) && min_dp_main < 0) {818			tb_sw_warn(sw, "missing baMinDPmain");819			goto err_invalid;820		}821		if ((tb_port_is_dpin(port) || tb_port_is_dpout(port)) &&822		    min_dp_aux < 0) {823			tb_sw_warn(sw, "missing baMinDPaux");824			goto err_invalid;825		}826		if ((tb_port_is_usb3_down(port) || tb_port_is_usb3_up(port)) &&827		    max_usb3 < 0) {828			tb_sw_warn(sw, "missing baMaxUSB3");829			goto err_invalid;830		}831		if ((tb_port_is_pcie_down(port) || tb_port_is_pcie_up(port)) &&832		    max_pcie < 0) {833			tb_sw_warn(sw, "missing baMaxPCIe");834			goto err_invalid;835		}836	}837 838	/*839	 * Buffer allocation passed the validation so we can use it in840	 * path creation.841	 */842	sw->credit_allocation = true;843	if (max_usb3 > 0)844		sw->max_usb3_credits = max_usb3;845	if (min_dp_aux > 0)846		sw->min_dp_aux_credits = min_dp_aux;847	if (min_dp_main > 0)848		sw->min_dp_main_credits = min_dp_main;849	if (max_pcie > 0)850		sw->max_pcie_credits = max_pcie;851	if (max_dma > 0)852		sw->max_dma_credits = max_dma;853 854	return 0;855 856err_invalid:857	return -EINVAL;858}859 860/**861 * usb4_switch_query_dp_resource() - Query availability of DP IN resource862 * @sw: USB4 router863 * @in: DP IN adapter864 *865 * For DP tunneling this function can be used to query availability of866 * DP IN resource. Returns true if the resource is available for DP867 * tunneling, false otherwise.868 */869bool usb4_switch_query_dp_resource(struct tb_switch *sw, struct tb_port *in)870{871	u32 metadata = in->port;872	u8 status;873	int ret;874 875	ret = usb4_switch_op(sw, USB4_SWITCH_OP_QUERY_DP_RESOURCE, &metadata,876			     &status);877	/*878	 * If DP resource allocation is not supported assume it is879	 * always available.880	 */881	if (ret == -EOPNOTSUPP)882		return true;883	if (ret)884		return false;885 886	return !status;887}888 889/**890 * usb4_switch_alloc_dp_resource() - Allocate DP IN resource891 * @sw: USB4 router892 * @in: DP IN adapter893 *894 * Allocates DP IN resource for DP tunneling using USB4 router895 * operations. If the resource was allocated returns %0. Otherwise896 * returns negative errno, in particular %-EBUSY if the resource is897 * already allocated.898 */899int usb4_switch_alloc_dp_resource(struct tb_switch *sw, struct tb_port *in)900{901	u32 metadata = in->port;902	u8 status;903	int ret;904 905	ret = usb4_switch_op(sw, USB4_SWITCH_OP_ALLOC_DP_RESOURCE, &metadata,906			     &status);907	if (ret == -EOPNOTSUPP)908		return 0;909	if (ret)910		return ret;911 912	return status ? -EBUSY : 0;913}914 915/**916 * usb4_switch_dealloc_dp_resource() - Releases allocated DP IN resource917 * @sw: USB4 router918 * @in: DP IN adapter919 *920 * Releases the previously allocated DP IN resource.921 */922int usb4_switch_dealloc_dp_resource(struct tb_switch *sw, struct tb_port *in)923{924	u32 metadata = in->port;925	u8 status;926	int ret;927 928	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DEALLOC_DP_RESOURCE, &metadata,929			     &status);930	if (ret == -EOPNOTSUPP)931		return 0;932	if (ret)933		return ret;934 935	return status ? -EIO : 0;936}937 938static int usb4_port_idx(const struct tb_switch *sw, const struct tb_port *port)939{940	struct tb_port *p;941	int usb4_idx = 0;942 943	/* Assume port is primary */944	tb_switch_for_each_port(sw, p) {945		if (!tb_port_is_null(p))946			continue;947		if (tb_is_upstream_port(p))948			continue;949		if (!p->link_nr) {950			if (p == port)951				break;952			usb4_idx++;953		}954	}955 956	return usb4_idx;957}958 959/**960 * usb4_switch_map_pcie_down() - Map USB4 port to a PCIe downstream adapter961 * @sw: USB4 router962 * @port: USB4 port963 *964 * USB4 routers have direct mapping between USB4 ports and PCIe965 * downstream adapters where the PCIe topology is extended. This966 * function returns the corresponding downstream PCIe adapter or %NULL967 * if no such mapping was possible.968 */969struct tb_port *usb4_switch_map_pcie_down(struct tb_switch *sw,970					  const struct tb_port *port)971{972	int usb4_idx = usb4_port_idx(sw, port);973	struct tb_port *p;974	int pcie_idx = 0;975 976	/* Find PCIe down port matching usb4_port */977	tb_switch_for_each_port(sw, p) {978		if (!tb_port_is_pcie_down(p))979			continue;980 981		if (pcie_idx == usb4_idx)982			return p;983 984		pcie_idx++;985	}986 987	return NULL;988}989 990/**991 * usb4_switch_map_usb3_down() - Map USB4 port to a USB3 downstream adapter992 * @sw: USB4 router993 * @port: USB4 port994 *995 * USB4 routers have direct mapping between USB4 ports and USB 3.x996 * downstream adapters where the USB 3.x topology is extended. This997 * function returns the corresponding downstream USB 3.x adapter or998 * %NULL if no such mapping was possible.999 */1000struct tb_port *usb4_switch_map_usb3_down(struct tb_switch *sw,1001					  const struct tb_port *port)1002{1003	int usb4_idx = usb4_port_idx(sw, port);1004	struct tb_port *p;1005	int usb_idx = 0;1006 1007	/* Find USB3 down port matching usb4_port */1008	tb_switch_for_each_port(sw, p) {1009		if (!tb_port_is_usb3_down(p))1010			continue;1011 1012		if (usb_idx == usb4_idx)1013			return p;1014 1015		usb_idx++;1016	}1017 1018	return NULL;1019}1020 1021/**1022 * usb4_switch_add_ports() - Add USB4 ports for this router1023 * @sw: USB4 router1024 *1025 * For USB4 router finds all USB4 ports and registers devices for each.1026 * Can be called to any router.1027 *1028 * Return %0 in case of success and negative errno in case of failure.1029 */1030int usb4_switch_add_ports(struct tb_switch *sw)1031{1032	struct tb_port *port;1033 1034	if (tb_switch_is_icm(sw) || !tb_switch_is_usb4(sw))1035		return 0;1036 1037	tb_switch_for_each_port(sw, port) {1038		struct usb4_port *usb4;1039 1040		if (!tb_port_is_null(port))1041			continue;1042		if (!port->cap_usb4)1043			continue;1044 1045		usb4 = usb4_port_device_add(port);1046		if (IS_ERR(usb4)) {1047			usb4_switch_remove_ports(sw);1048			return PTR_ERR(usb4);1049		}1050 1051		port->usb4 = usb4;1052	}1053 1054	return 0;1055}1056 1057/**1058 * usb4_switch_remove_ports() - Removes USB4 ports from this router1059 * @sw: USB4 router1060 *1061 * Unregisters previously registered USB4 ports.1062 */1063void usb4_switch_remove_ports(struct tb_switch *sw)1064{1065	struct tb_port *port;1066 1067	tb_switch_for_each_port(sw, port) {1068		if (port->usb4) {1069			usb4_port_device_remove(port->usb4);1070			port->usb4 = NULL;1071		}1072	}1073}1074 1075/**1076 * usb4_port_unlock() - Unlock USB4 downstream port1077 * @port: USB4 port to unlock1078 *1079 * Unlocks USB4 downstream port so that the connection manager can1080 * access the router below this port.1081 */1082int usb4_port_unlock(struct tb_port *port)1083{1084	int ret;1085	u32 val;1086 1087	ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_4, 1);1088	if (ret)1089		return ret;1090 1091	val &= ~ADP_CS_4_LCK;1092	return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1);1093}1094 1095/**1096 * usb4_port_hotplug_enable() - Enables hotplug for a port1097 * @port: USB4 port to operate on1098 *1099 * Enables hot plug events on a given port. This is only intended1100 * to be used on lane, DP-IN, and DP-OUT adapters.1101 */1102int usb4_port_hotplug_enable(struct tb_port *port)1103{1104	int ret;1105	u32 val;1106 1107	ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_5, 1);1108	if (ret)1109		return ret;1110 1111	val &= ~ADP_CS_5_DHP;1112	return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1);1113}1114 1115/**1116 * usb4_port_reset() - Issue downstream port reset1117 * @port: USB4 port to reset1118 *1119 * Issues downstream port reset to @port.1120 */1121int usb4_port_reset(struct tb_port *port)1122{1123	int ret;1124	u32 val;1125 1126	if (!port->cap_usb4)1127		return -EINVAL;1128 1129	ret = tb_port_read(port, &val, TB_CFG_PORT,1130			   port->cap_usb4 + PORT_CS_19, 1);1131	if (ret)1132		return ret;1133 1134	val |= PORT_CS_19_DPR;1135 1136	ret = tb_port_write(port, &val, TB_CFG_PORT,1137			    port->cap_usb4 + PORT_CS_19, 1);1138	if (ret)1139		return ret;1140 1141	fsleep(10000);1142 1143	ret = tb_port_read(port, &val, TB_CFG_PORT,1144			   port->cap_usb4 + PORT_CS_19, 1);1145	if (ret)1146		return ret;1147 1148	val &= ~PORT_CS_19_DPR;1149 1150	return tb_port_write(port, &val, TB_CFG_PORT,1151			     port->cap_usb4 + PORT_CS_19, 1);1152}1153 1154static int usb4_port_set_configured(struct tb_port *port, bool configured)1155{1156	int ret;1157	u32 val;1158 1159	if (!port->cap_usb4)1160		return -EINVAL;1161 1162	ret = tb_port_read(port, &val, TB_CFG_PORT,1163			   port->cap_usb4 + PORT_CS_19, 1);1164	if (ret)1165		return ret;1166 1167	if (configured)1168		val |= PORT_CS_19_PC;1169	else1170		val &= ~PORT_CS_19_PC;1171 1172	return tb_port_write(port, &val, TB_CFG_PORT,1173			     port->cap_usb4 + PORT_CS_19, 1);1174}1175 1176/**1177 * usb4_port_configure() - Set USB4 port configured1178 * @port: USB4 router1179 *1180 * Sets the USB4 link to be configured for power management purposes.1181 */1182int usb4_port_configure(struct tb_port *port)1183{1184	return usb4_port_set_configured(port, true);1185}1186 1187/**1188 * usb4_port_unconfigure() - Set USB4 port unconfigured1189 * @port: USB4 router1190 *1191 * Sets the USB4 link to be unconfigured for power management purposes.1192 */1193void usb4_port_unconfigure(struct tb_port *port)1194{1195	usb4_port_set_configured(port, false);1196}1197 1198static int usb4_set_xdomain_configured(struct tb_port *port, bool configured)1199{1200	int ret;1201	u32 val;1202 1203	if (!port->cap_usb4)1204		return -EINVAL;1205 1206	ret = tb_port_read(port, &val, TB_CFG_PORT,1207			   port->cap_usb4 + PORT_CS_19, 1);1208	if (ret)1209		return ret;1210 1211	if (configured)1212		val |= PORT_CS_19_PID;1213	else1214		val &= ~PORT_CS_19_PID;1215 1216	return tb_port_write(port, &val, TB_CFG_PORT,1217			     port->cap_usb4 + PORT_CS_19, 1);1218}1219 1220/**1221 * usb4_port_configure_xdomain() - Configure port for XDomain1222 * @port: USB4 port connected to another host1223 * @xd: XDomain that is connected to the port1224 *1225 * Marks the USB4 port as being connected to another host and updates1226 * the link type. Returns %0 in success and negative errno in failure.1227 */1228int usb4_port_configure_xdomain(struct tb_port *port, struct tb_xdomain *xd)1229{1230	xd->link_usb4 = link_is_usb4(port);1231	return usb4_set_xdomain_configured(port, true);1232}1233 1234/**1235 * usb4_port_unconfigure_xdomain() - Unconfigure port for XDomain1236 * @port: USB4 port that was connected to another host1237 *1238 * Clears USB4 port from being marked as XDomain.1239 */1240void usb4_port_unconfigure_xdomain(struct tb_port *port)1241{1242	usb4_set_xdomain_configured(port, false);1243}1244 1245static int usb4_port_wait_for_bit(struct tb_port *port, u32 offset, u32 bit,1246			  u32 value, int timeout_msec, unsigned long delay_usec)1247{1248	ktime_t timeout = ktime_add_ms(ktime_get(), timeout_msec);1249 1250	do {1251		u32 val;1252		int ret;1253 1254		ret = tb_port_read(port, &val, TB_CFG_PORT, offset, 1);1255		if (ret)1256			return ret;1257 1258		if ((val & bit) == value)1259			return 0;1260 1261		fsleep(delay_usec);1262	} while (ktime_before(ktime_get(), timeout));1263 1264	return -ETIMEDOUT;1265}1266 1267static int usb4_port_read_data(struct tb_port *port, void *data, size_t dwords)1268{1269	if (dwords > USB4_DATA_DWORDS)1270		return -EINVAL;1271 1272	return tb_port_read(port, data, TB_CFG_PORT, port->cap_usb4 + PORT_CS_2,1273			    dwords);1274}1275 1276static int usb4_port_write_data(struct tb_port *port, const void *data,1277				size_t dwords)1278{1279	if (dwords > USB4_DATA_DWORDS)1280		return -EINVAL;1281 1282	return tb_port_write(port, data, TB_CFG_PORT, port->cap_usb4 + PORT_CS_2,1283			     dwords);1284}1285 1286/**1287 * usb4_port_sb_read() - Read from sideband register1288 * @port: USB4 port to read1289 * @target: Sideband target1290 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1291 * @reg: Sideband register index1292 * @buf: Buffer where the sideband data is copied1293 * @size: Size of @buf1294 *1295 * Reads data from sideband register @reg and copies it into @buf.1296 * Returns %0 in case of success and negative errno in case of failure.1297 */1298int usb4_port_sb_read(struct tb_port *port, enum usb4_sb_target target, u8 index,1299		      u8 reg, void *buf, u8 size)1300{1301	size_t dwords = DIV_ROUND_UP(size, 4);1302	int ret;1303	u32 val;1304 1305	if (!port->cap_usb4)1306		return -EINVAL;1307 1308	val = reg;1309	val |= size << PORT_CS_1_LENGTH_SHIFT;1310	val |= (target << PORT_CS_1_TARGET_SHIFT) & PORT_CS_1_TARGET_MASK;1311	if (target == USB4_SB_TARGET_RETIMER)1312		val |= (index << PORT_CS_1_RETIMER_INDEX_SHIFT);1313	val |= PORT_CS_1_PND;1314 1315	ret = tb_port_write(port, &val, TB_CFG_PORT,1316			    port->cap_usb4 + PORT_CS_1, 1);1317	if (ret)1318		return ret;1319 1320	ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_1,1321				     PORT_CS_1_PND, 0, 500, USB4_PORT_SB_DELAY);1322	if (ret)1323		return ret;1324 1325	ret = tb_port_read(port, &val, TB_CFG_PORT,1326			    port->cap_usb4 + PORT_CS_1, 1);1327	if (ret)1328		return ret;1329 1330	if (val & PORT_CS_1_NR)1331		return -ENODEV;1332	if (val & PORT_CS_1_RC)1333		return -EIO;1334 1335	return buf ? usb4_port_read_data(port, buf, dwords) : 0;1336}1337 1338/**1339 * usb4_port_sb_write() - Write to sideband register1340 * @port: USB4 port to write1341 * @target: Sideband target1342 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1343 * @reg: Sideband register index1344 * @buf: Data to write1345 * @size: Size of @buf1346 *1347 * Writes @buf to sideband register @reg. Returns %0 in case of success1348 * and negative errno in case of failure.1349 */1350int usb4_port_sb_write(struct tb_port *port, enum usb4_sb_target target,1351		       u8 index, u8 reg, const void *buf, u8 size)1352{1353	size_t dwords = DIV_ROUND_UP(size, 4);1354	int ret;1355	u32 val;1356 1357	if (!port->cap_usb4)1358		return -EINVAL;1359 1360	if (buf) {1361		ret = usb4_port_write_data(port, buf, dwords);1362		if (ret)1363			return ret;1364	}1365 1366	val = reg;1367	val |= size << PORT_CS_1_LENGTH_SHIFT;1368	val |= PORT_CS_1_WNR_WRITE;1369	val |= (target << PORT_CS_1_TARGET_SHIFT) & PORT_CS_1_TARGET_MASK;1370	if (target == USB4_SB_TARGET_RETIMER)1371		val |= (index << PORT_CS_1_RETIMER_INDEX_SHIFT);1372	val |= PORT_CS_1_PND;1373 1374	ret = tb_port_write(port, &val, TB_CFG_PORT,1375			    port->cap_usb4 + PORT_CS_1, 1);1376	if (ret)1377		return ret;1378 1379	ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_1,1380				     PORT_CS_1_PND, 0, 500, USB4_PORT_SB_DELAY);1381	if (ret)1382		return ret;1383 1384	ret = tb_port_read(port, &val, TB_CFG_PORT,1385			    port->cap_usb4 + PORT_CS_1, 1);1386	if (ret)1387		return ret;1388 1389	if (val & PORT_CS_1_NR)1390		return -ENODEV;1391	if (val & PORT_CS_1_RC)1392		return -EIO;1393 1394	return 0;1395}1396 1397static int usb4_port_sb_opcode_err_to_errno(u32 val)1398{1399	switch (val) {1400	case 0:1401		return 0;1402	case USB4_SB_OPCODE_ERR:1403		return -EAGAIN;1404	case USB4_SB_OPCODE_ONS:1405		return -EOPNOTSUPP;1406	default:1407		return -EIO;1408	}1409}1410 1411static int usb4_port_sb_op(struct tb_port *port, enum usb4_sb_target target,1412			   u8 index, enum usb4_sb_opcode opcode, int timeout_msec)1413{1414	ktime_t timeout;1415	u32 val;1416	int ret;1417 1418	val = opcode;1419	ret = usb4_port_sb_write(port, target, index, USB4_SB_OPCODE, &val,1420				 sizeof(val));1421	if (ret)1422		return ret;1423 1424	timeout = ktime_add_ms(ktime_get(), timeout_msec);1425 1426	do {1427		/* Check results */1428		ret = usb4_port_sb_read(port, target, index, USB4_SB_OPCODE,1429					&val, sizeof(val));1430		if (ret)1431			return ret;1432 1433		if (val != opcode)1434			return usb4_port_sb_opcode_err_to_errno(val);1435 1436		fsleep(USB4_PORT_SB_DELAY);1437	} while (ktime_before(ktime_get(), timeout));1438 1439	return -ETIMEDOUT;1440}1441 1442static int usb4_port_set_router_offline(struct tb_port *port, bool offline)1443{1444	u32 val = !offline;1445	int ret;1446 1447	ret = usb4_port_sb_write(port, USB4_SB_TARGET_ROUTER, 0,1448				  USB4_SB_METADATA, &val, sizeof(val));1449	if (ret)1450		return ret;1451 1452	val = USB4_SB_OPCODE_ROUTER_OFFLINE;1453	return usb4_port_sb_write(port, USB4_SB_TARGET_ROUTER, 0,1454				  USB4_SB_OPCODE, &val, sizeof(val));1455}1456 1457/**1458 * usb4_port_router_offline() - Put the USB4 port to offline mode1459 * @port: USB4 port1460 *1461 * This function puts the USB4 port into offline mode. In this mode the1462 * port does not react on hotplug events anymore. This needs to be1463 * called before retimer access is done when the USB4 links is not up.1464 *1465 * Returns %0 in case of success and negative errno if there was an1466 * error.1467 */1468int usb4_port_router_offline(struct tb_port *port)1469{1470	return usb4_port_set_router_offline(port, true);1471}1472 1473/**1474 * usb4_port_router_online() - Put the USB4 port back to online1475 * @port: USB4 port1476 *1477 * Makes the USB4 port functional again.1478 */1479int usb4_port_router_online(struct tb_port *port)1480{1481	return usb4_port_set_router_offline(port, false);1482}1483 1484/**1485 * usb4_port_enumerate_retimers() - Send RT broadcast transaction1486 * @port: USB4 port1487 *1488 * This forces the USB4 port to send broadcast RT transaction which1489 * makes the retimers on the link to assign index to themselves. Returns1490 * %0 in case of success and negative errno if there was an error.1491 */1492int usb4_port_enumerate_retimers(struct tb_port *port)1493{1494	u32 val;1495 1496	val = USB4_SB_OPCODE_ENUMERATE_RETIMERS;1497	return usb4_port_sb_write(port, USB4_SB_TARGET_ROUTER, 0,1498				  USB4_SB_OPCODE, &val, sizeof(val));1499}1500 1501/**1502 * usb4_port_clx_supported() - Check if CLx is supported by the link1503 * @port: Port to check for CLx support for1504 *1505 * PORT_CS_18_CPS bit reflects if the link supports CLx including1506 * active cables (if connected on the link).1507 */1508bool usb4_port_clx_supported(struct tb_port *port)1509{1510	int ret;1511	u32 val;1512 1513	ret = tb_port_read(port, &val, TB_CFG_PORT,1514			   port->cap_usb4 + PORT_CS_18, 1);1515	if (ret)1516		return false;1517 1518	return !!(val & PORT_CS_18_CPS);1519}1520 1521/**1522 * usb4_port_asym_supported() - If the port supports asymmetric link1523 * @port: USB4 port1524 *1525 * Checks if the port and the cable supports asymmetric link and returns1526 * %true in that case.1527 */1528bool usb4_port_asym_supported(struct tb_port *port)1529{1530	u32 val;1531 1532	if (!port->cap_usb4)1533		return false;1534 1535	if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1))1536		return false;1537 1538	return !!(val & PORT_CS_18_CSA);1539}1540 1541/**1542 * usb4_port_asym_set_link_width() - Set link width to asymmetric or symmetric1543 * @port: USB4 port1544 * @width: Asymmetric width to configure1545 *1546 * Sets USB4 port link width to @width. Can be called for widths where1547 * usb4_port_asym_width_supported() returned @true.1548 */1549int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width)1550{1551	u32 val;1552	int ret;1553 1554	if (!port->cap_phy)1555		return -EINVAL;1556 1557	ret = tb_port_read(port, &val, TB_CFG_PORT,1558			   port->cap_phy + LANE_ADP_CS_1, 1);1559	if (ret)1560		return ret;1561 1562	val &= ~LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK;1563	switch (width) {1564	case TB_LINK_WIDTH_DUAL:1565		val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK,1566				  LANE_ADP_CS_1_TARGET_WIDTH_ASYM_DUAL);1567		break;1568	case TB_LINK_WIDTH_ASYM_TX:1569		val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK,1570				  LANE_ADP_CS_1_TARGET_WIDTH_ASYM_TX);1571		break;1572	case TB_LINK_WIDTH_ASYM_RX:1573		val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK,1574				  LANE_ADP_CS_1_TARGET_WIDTH_ASYM_RX);1575		break;1576	default:1577		return -EINVAL;1578	}1579 1580	return tb_port_write(port, &val, TB_CFG_PORT,1581			     port->cap_phy + LANE_ADP_CS_1, 1);1582}1583 1584/**1585 * usb4_port_asym_start() - Start symmetry change and wait for completion1586 * @port: USB4 port1587 *1588 * Start symmetry change of the link to asymmetric or symmetric1589 * (according to what was previously set in tb_port_set_link_width().1590 * Wait for completion of the change.1591 *1592 * Returns %0 in case of success, %-ETIMEDOUT if case of timeout or1593 * a negative errno in case of a failure.1594 */1595int usb4_port_asym_start(struct tb_port *port)1596{1597	int ret;1598	u32 val;1599 1600	ret = tb_port_read(port, &val, TB_CFG_PORT,1601			   port->cap_usb4 + PORT_CS_19, 1);1602	if (ret)1603		return ret;1604 1605	val &= ~PORT_CS_19_START_ASYM;1606	val |= FIELD_PREP(PORT_CS_19_START_ASYM, 1);1607 1608	ret = tb_port_write(port, &val, TB_CFG_PORT,1609			    port->cap_usb4 + PORT_CS_19, 1);1610	if (ret)1611		return ret;1612 1613	/*1614	 * Wait for PORT_CS_19_START_ASYM to be 0. This means the USB41615	 * port started the symmetry transition.1616	 */1617	ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_19,1618				     PORT_CS_19_START_ASYM, 0, 1000,1619				     USB4_PORT_DELAY);1620	if (ret)1621		return ret;1622 1623	/* Then wait for the transtion to be completed */1624	return usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_18,1625				      PORT_CS_18_TIP, 0, 5000, USB4_PORT_DELAY);1626}1627 1628/**1629 * usb4_port_margining_caps() - Read USB4 port marginig capabilities1630 * @port: USB4 port1631 * @target: Sideband target1632 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1633 * @caps: Array with at least two elements to hold the results1634 *1635 * Reads the USB4 port lane margining capabilities into @caps.1636 */1637int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target,1638			     u8 index, u32 *caps)1639{1640	int ret;1641 1642	ret = usb4_port_sb_op(port, target, index,1643			      USB4_SB_OPCODE_READ_LANE_MARGINING_CAP, 500);1644	if (ret)1645		return ret;1646 1647	return usb4_port_sb_read(port, target, index, USB4_SB_DATA, caps,1648				 sizeof(*caps) * 2);1649}1650 1651/**1652 * usb4_port_hw_margin() - Run hardware lane margining on port1653 * @port: USB4 port1654 * @target: Sideband target1655 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1656 * @params: Parameters for USB4 hardware margining1657 * @results: Array with at least two elements to hold the results1658 *1659 * Runs hardware lane margining on USB4 port and returns the result in1660 * @results.1661 */1662int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target,1663			u8 index, const struct usb4_port_margining_params *params,1664			u32 *results)1665{1666	u32 val;1667	int ret;1668 1669	if (WARN_ON_ONCE(!params))1670		return -EINVAL;1671 1672	val = params->lanes;1673	if (params->time)1674		val |= USB4_MARGIN_HW_TIME;1675	if (params->right_high)1676		val |= USB4_MARGIN_HW_RH;1677	if (params->ber_level)1678		val |= FIELD_PREP(USB4_MARGIN_HW_BER_MASK, params->ber_level);1679	if (params->optional_voltage_offset_range)1680		val |= USB4_MARGIN_HW_OPT_VOLTAGE;1681 1682	ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,1683				 sizeof(val));1684	if (ret)1685		return ret;1686 1687	ret = usb4_port_sb_op(port, target, index,1688			      USB4_SB_OPCODE_RUN_HW_LANE_MARGINING, 2500);1689	if (ret)1690		return ret;1691 1692	return usb4_port_sb_read(port, target, index, USB4_SB_DATA, results,1693				 sizeof(*results) * 2);1694}1695 1696/**1697 * usb4_port_sw_margin() - Run software lane margining on port1698 * @port: USB4 port1699 * @target: Sideband target1700 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1701 * @params: Parameters for USB4 software margining1702 * @results: Data word for the operation completion data1703 *1704 * Runs software lane margining on USB4 port. Read back the error1705 * counters by calling usb4_port_sw_margin_errors(). Returns %0 in1706 * success and negative errno otherwise.1707 */1708int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target,1709			u8 index, const struct usb4_port_margining_params *params,1710			u32 *results)1711{1712	u32 val;1713	int ret;1714 1715	if (WARN_ON_ONCE(!params))1716		return -EINVAL;1717 1718	val = params->lanes;1719	if (params->time)1720		val |= USB4_MARGIN_SW_TIME;1721	if (params->optional_voltage_offset_range)1722		val |= USB4_MARGIN_SW_OPT_VOLTAGE;1723	if (params->right_high)1724		val |= USB4_MARGIN_SW_RH;1725	val |= FIELD_PREP(USB4_MARGIN_SW_COUNTER_MASK, params->error_counter);1726	val |= FIELD_PREP(USB4_MARGIN_SW_VT_MASK, params->voltage_time_offset);1727 1728	ret = usb4_port_sb_write(port, target, index, USB4_SB_METADATA, &val,1729				 sizeof(val));1730	if (ret)1731		return ret;1732 1733	ret = usb4_port_sb_op(port, target, index,1734			      USB4_SB_OPCODE_RUN_SW_LANE_MARGINING, 2500);1735	if (ret)1736		return ret;1737 1738	return usb4_port_sb_read(port, target, index, USB4_SB_DATA, results,1739				 sizeof(*results));1740 1741}1742 1743/**1744 * usb4_port_sw_margin_errors() - Read the software margining error counters1745 * @port: USB4 port1746 * @target: Sideband target1747 * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER1748 * @errors: Error metadata is copied here.1749 *1750 * This reads back the software margining error counters from the port.1751 * Returns %0 in success and negative errno otherwise.1752 */1753int usb4_port_sw_margin_errors(struct tb_port *port, enum usb4_sb_target target,1754			       u8 index, u32 *errors)1755{1756	int ret;1757 1758	ret = usb4_port_sb_op(port, target, index,1759			      USB4_SB_OPCODE_READ_SW_MARGIN_ERR, 150);1760	if (ret)1761		return ret;1762 1763	return usb4_port_sb_read(port, target, index, USB4_SB_METADATA, errors,1764				 sizeof(*errors));1765}1766 1767static inline int usb4_port_retimer_op(struct tb_port *port, u8 index,1768				       enum usb4_sb_opcode opcode,1769				       int timeout_msec)1770{1771	return usb4_port_sb_op(port, USB4_SB_TARGET_RETIMER, index, opcode,1772			       timeout_msec);1773}1774 1775/**1776 * usb4_port_retimer_set_inbound_sbtx() - Enable sideband channel transactions1777 * @port: USB4 port1778 * @index: Retimer index1779 *1780 * Enables sideband channel transations on SBTX. Can be used when USB41781 * link does not go up, for example if there is no device connected.1782 */1783int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index)1784{1785	int ret;1786 1787	ret = usb4_port_retimer_op(port, index, USB4_SB_OPCODE_SET_INBOUND_SBTX,1788				   500);1789 1790	if (ret != -ENODEV)1791		return ret;1792 1793	/*1794	 * Per the USB4 retimer spec, the retimer is not required to1795	 * send an RT (Retimer Transaction) response for the first1796	 * SET_INBOUND_SBTX command1797	 */1798	return usb4_port_retimer_op(port, index, USB4_SB_OPCODE_SET_INBOUND_SBTX,1799				    500);1800}1801 1802/**1803 * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions1804 * @port: USB4 port1805 * @index: Retimer index1806 *1807 * Disables sideband channel transations on SBTX. The reverse of1808 * usb4_port_retimer_set_inbound_sbtx().1809 */1810int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index)1811{1812	return usb4_port_retimer_op(port, index,1813				    USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500);1814}1815 1816/**1817 * usb4_port_retimer_is_last() - Is the retimer last on-board retimer1818 * @port: USB4 port1819 * @index: Retimer index1820 *1821 * If the retimer at @index is last one (connected directly to the1822 * Type-C port) this function returns %1. If it is not returns %0. If1823 * the retimer is not present returns %-ENODEV. Otherwise returns1824 * negative errno.1825 */1826int usb4_port_retimer_is_last(struct tb_port *port, u8 index)1827{1828	u32 metadata;1829	int ret;1830 1831	ret = usb4_port_retimer_op(port, index, USB4_SB_OPCODE_QUERY_LAST_RETIMER,1832				   500);1833	if (ret)1834		return ret;1835 1836	ret = usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,1837				USB4_SB_METADATA, &metadata, sizeof(metadata));1838	return ret ? ret : metadata & 1;1839}1840 1841/**1842 * usb4_port_retimer_is_cable() - Is the retimer cable retimer1843 * @port: USB4 port1844 * @index: Retimer index1845 *1846 * If the retimer at @index is last cable retimer this function returns1847 * %1 and %0 if it is on-board retimer. In case a retimer is not present1848 * at @index returns %-ENODEV. Otherwise returns negative errno.1849 */1850int usb4_port_retimer_is_cable(struct tb_port *port, u8 index)1851{1852	u32 metadata;1853	int ret;1854 1855	ret = usb4_port_retimer_op(port, index, USB4_SB_OPCODE_QUERY_CABLE_RETIMER,1856				   500);1857	if (ret)1858		return ret;1859 1860	ret = usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,1861				USB4_SB_METADATA, &metadata, sizeof(metadata));1862	return ret ? ret : metadata & 1;1863}1864 1865/**1866 * usb4_port_retimer_nvm_sector_size() - Read retimer NVM sector size1867 * @port: USB4 port1868 * @index: Retimer index1869 *1870 * Reads NVM sector size (in bytes) of a retimer at @index. This1871 * operation can be used to determine whether the retimer supports NVM1872 * upgrade for example. Returns sector size in bytes or negative errno1873 * in case of error. Specifically returns %-ENODEV if there is no1874 * retimer at @index.1875 */1876int usb4_port_retimer_nvm_sector_size(struct tb_port *port, u8 index)1877{1878	u32 metadata;1879	int ret;1880 1881	ret = usb4_port_retimer_op(port, index, USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE,1882				   500);1883	if (ret)1884		return ret;1885 1886	ret = usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,1887				USB4_SB_METADATA, &metadata, sizeof(metadata));1888	return ret ? ret : metadata & USB4_NVM_SECTOR_SIZE_MASK;1889}1890 1891/**1892 * usb4_port_retimer_nvm_set_offset() - Set NVM write offset1893 * @port: USB4 port1894 * @index: Retimer index1895 * @address: Start offset1896 *1897 * Exlicitly sets NVM write offset. Normally when writing to NVM this is1898 * done automatically by usb4_port_retimer_nvm_write().1899 *1900 * Returns %0 in success and negative errno if there was a failure.1901 */1902int usb4_port_retimer_nvm_set_offset(struct tb_port *port, u8 index,1903				     unsigned int address)1904{1905	u32 metadata, dwaddress;1906	int ret;1907 1908	dwaddress = address / 4;1909	metadata = (dwaddress << USB4_NVM_SET_OFFSET_SHIFT) &1910		  USB4_NVM_SET_OFFSET_MASK;1911 1912	ret = usb4_port_sb_write(port, USB4_SB_TARGET_RETIMER, index,1913				 USB4_SB_METADATA, &metadata, sizeof(metadata));1914	if (ret)1915		return ret;1916 1917	return usb4_port_retimer_op(port, index, USB4_SB_OPCODE_NVM_SET_OFFSET,1918				    500);1919}1920 1921struct retimer_info {1922	struct tb_port *port;1923	u8 index;1924};1925 1926static int usb4_port_retimer_nvm_write_next_block(void *data,1927	unsigned int dwaddress, const void *buf, size_t dwords)1928 1929{1930	const struct retimer_info *info = data;1931	struct tb_port *port = info->port;1932	u8 index = info->index;1933	int ret;1934 1935	ret = usb4_port_sb_write(port, USB4_SB_TARGET_RETIMER, index,1936				 USB4_SB_DATA, buf, dwords * 4);1937	if (ret)1938		return ret;1939 1940	return usb4_port_retimer_op(port, index,1941			USB4_SB_OPCODE_NVM_BLOCK_WRITE, 1000);1942}1943 1944/**1945 * usb4_port_retimer_nvm_write() - Write to retimer NVM1946 * @port: USB4 port1947 * @index: Retimer index1948 * @address: Byte address where to start the write1949 * @buf: Data to write1950 * @size: Size in bytes how much to write1951 *1952 * Writes @size bytes from @buf to the retimer NVM. Used for NVM1953 * upgrade. Returns %0 if the data was written successfully and negative1954 * errno in case of failure. Specifically returns %-ENODEV if there is1955 * no retimer at @index.1956 */1957int usb4_port_retimer_nvm_write(struct tb_port *port, u8 index, unsigned int address,1958				const void *buf, size_t size)1959{1960	struct retimer_info info = { .port = port, .index = index };1961	int ret;1962 1963	ret = usb4_port_retimer_nvm_set_offset(port, index, address);1964	if (ret)1965		return ret;1966 1967	return tb_nvm_write_data(address, buf, size, USB4_DATA_RETRIES,1968				 usb4_port_retimer_nvm_write_next_block, &info);1969}1970 1971/**1972 * usb4_port_retimer_nvm_authenticate() - Start retimer NVM upgrade1973 * @port: USB4 port1974 * @index: Retimer index1975 *1976 * After the new NVM image has been written via usb4_port_retimer_nvm_write()1977 * this function can be used to trigger the NVM upgrade process. If1978 * successful the retimer restarts with the new NVM and may not have the1979 * index set so one needs to call usb4_port_enumerate_retimers() to1980 * force index to be assigned.1981 */1982int usb4_port_retimer_nvm_authenticate(struct tb_port *port, u8 index)1983{1984	u32 val;1985 1986	/*1987	 * We need to use the raw operation here because once the1988	 * authentication completes the retimer index is not set anymore1989	 * so we do not get back the status now.1990	 */1991	val = USB4_SB_OPCODE_NVM_AUTH_WRITE;1992	return usb4_port_sb_write(port, USB4_SB_TARGET_RETIMER, index,1993				  USB4_SB_OPCODE, &val, sizeof(val));1994}1995 1996/**1997 * usb4_port_retimer_nvm_authenticate_status() - Read status of NVM upgrade1998 * @port: USB4 port1999 * @index: Retimer index2000 * @status: Raw status code read from metadata2001 *2002 * This can be called after usb4_port_retimer_nvm_authenticate() and2003 * usb4_port_enumerate_retimers() to fetch status of the NVM upgrade.2004 *2005 * Returns %0 if the authentication status was successfully read. The2006 * completion metadata (the result) is then stored into @status. If2007 * reading the status fails, returns negative errno.2008 */2009int usb4_port_retimer_nvm_authenticate_status(struct tb_port *port, u8 index,2010					      u32 *status)2011{2012	u32 metadata, val;2013	int ret;2014 2015	ret = usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,2016				USB4_SB_OPCODE, &val, sizeof(val));2017	if (ret)2018		return ret;2019 2020	ret = usb4_port_sb_opcode_err_to_errno(val);2021	switch (ret) {2022	case 0:2023		*status = 0;2024		return 0;2025 2026	case -EAGAIN:2027		ret = usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,2028					USB4_SB_METADATA, &metadata,2029					sizeof(metadata));2030		if (ret)2031			return ret;2032 2033		*status = metadata & USB4_SB_METADATA_NVM_AUTH_WRITE_MASK;2034		return 0;2035 2036	default:2037		return ret;2038	}2039}2040 2041static int usb4_port_retimer_nvm_read_block(void *data, unsigned int dwaddress,2042					    void *buf, size_t dwords)2043{2044	const struct retimer_info *info = data;2045	struct tb_port *port = info->port;2046	u8 index = info->index;2047	u32 metadata;2048	int ret;2049 2050	metadata = dwaddress << USB4_NVM_READ_OFFSET_SHIFT;2051	if (dwords < USB4_DATA_DWORDS)2052		metadata |= dwords << USB4_NVM_READ_LENGTH_SHIFT;2053 2054	ret = usb4_port_sb_write(port, USB4_SB_TARGET_RETIMER, index,2055				 USB4_SB_METADATA, &metadata, sizeof(metadata));2056	if (ret)2057		return ret;2058 2059	ret = usb4_port_retimer_op(port, index, USB4_SB_OPCODE_NVM_READ, 500);2060	if (ret)2061		return ret;2062 2063	return usb4_port_sb_read(port, USB4_SB_TARGET_RETIMER, index,2064				 USB4_SB_DATA, buf, dwords * 4);2065}2066 2067/**2068 * usb4_port_retimer_nvm_read() - Read contents of retimer NVM2069 * @port: USB4 port2070 * @index: Retimer index2071 * @address: NVM address (in bytes) to start reading2072 * @buf: Data read from NVM is stored here2073 * @size: Number of bytes to read2074 *2075 * Reads retimer NVM and copies the contents to @buf. Returns %0 if the2076 * read was successful and negative errno in case of failure.2077 * Specifically returns %-ENODEV if there is no retimer at @index.2078 */2079int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index,2080			       unsigned int address, void *buf, size_t size)2081{2082	struct retimer_info info = { .port = port, .index = index };2083 2084	return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES,2085				usb4_port_retimer_nvm_read_block, &info);2086}2087 2088static inline unsigned int2089usb4_usb3_port_max_bandwidth(const struct tb_port *port, unsigned int bw)2090{2091	/* Take the possible bandwidth limitation into account */2092	if (port->max_bw)2093		return min(bw, port->max_bw);2094	return bw;2095}2096 2097/**2098 * usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate2099 * @port: USB3 adapter port2100 *2101 * Return maximum supported link rate of a USB3 adapter in Mb/s.2102 * Negative errno in case of error.2103 */2104int usb4_usb3_port_max_link_rate(struct tb_port *port)2105{2106	int ret, lr;2107	u32 val;2108 2109	if (!tb_port_is_usb3_down(port) && !tb_port_is_usb3_up(port))2110		return -EINVAL;2111 2112	ret = tb_port_read(port, &val, TB_CFG_PORT,2113			   port->cap_adap + ADP_USB3_CS_4, 1);2114	if (ret)2115		return ret;2116 2117	lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT;2118	ret = lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;2119 2120	return usb4_usb3_port_max_bandwidth(port, ret);2121}2122 2123static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)2124{2125	int ret;2126	u32 val;2127 2128	if (!tb_port_is_usb3_down(port))2129		return -EINVAL;2130	if (tb_route(port->sw))2131		return -EINVAL;2132 2133	ret = tb_port_read(port, &val, TB_CFG_PORT,2134			   port->cap_adap + ADP_USB3_CS_2, 1);2135	if (ret)2136		return ret;2137 2138	if (request)2139		val |= ADP_USB3_CS_2_CMR;2140	else2141		val &= ~ADP_USB3_CS_2_CMR;2142 2143	ret = tb_port_write(port, &val, TB_CFG_PORT,2144			    port->cap_adap + ADP_USB3_CS_2, 1);2145	if (ret)2146		return ret;2147 2148	/*2149	 * We can use val here directly as the CMR bit is in the same place2150	 * as HCA. Just mask out others.2151	 */2152	val &= ADP_USB3_CS_2_CMR;2153	return usb4_port_wait_for_bit(port, port->cap_adap + ADP_USB3_CS_1,2154				      ADP_USB3_CS_1_HCA, val, 1500,2155				      USB4_PORT_DELAY);2156}2157 2158static inline int usb4_usb3_port_set_cm_request(struct tb_port *port)2159{2160	return usb4_usb3_port_cm_request(port, true);2161}2162 2163static inline int usb4_usb3_port_clear_cm_request(struct tb_port *port)2164{2165	return usb4_usb3_port_cm_request(port, false);2166}2167 2168static unsigned int usb3_bw_to_mbps(u32 bw, u8 scale)2169{2170	unsigned long uframes;2171 2172	uframes = bw * 512UL << scale;2173	return DIV_ROUND_CLOSEST(uframes * 8000, MEGA);2174}2175 2176static u32 mbps_to_usb3_bw(unsigned int mbps, u8 scale)2177{2178	unsigned long uframes;2179 2180	/* 1 uframe is 1/8 ms (125 us) -> 1 / 8000 s */2181	uframes = ((unsigned long)mbps * MEGA) / 8000;2182	return DIV_ROUND_UP(uframes, 512UL << scale);2183}2184 2185static int usb4_usb3_port_read_allocated_bandwidth(struct tb_port *port,2186						   int *upstream_bw,2187						   int *downstream_bw)2188{2189	u32 val, bw, scale;2190	int ret;2191 2192	ret = tb_port_read(port, &val, TB_CFG_PORT,2193			   port->cap_adap + ADP_USB3_CS_2, 1);2194	if (ret)2195		return ret;2196 2197	ret = tb_port_read(port, &scale, TB_CFG_PORT,2198			   port->cap_adap + ADP_USB3_CS_3, 1);2199	if (ret)2200		return ret;2201 2202	scale &= ADP_USB3_CS_3_SCALE_MASK;2203 2204	bw = val & ADP_USB3_CS_2_AUBW_MASK;2205	*upstream_bw = usb3_bw_to_mbps(bw, scale);2206 2207	bw = (val & ADP_USB3_CS_2_ADBW_MASK) >> ADP_USB3_CS_2_ADBW_SHIFT;2208	*downstream_bw = usb3_bw_to_mbps(bw, scale);2209 2210	return 0;2211}2212 2213/**2214 * usb4_usb3_port_allocated_bandwidth() - Bandwidth allocated for USB32215 * @port: USB3 adapter port2216 * @upstream_bw: Allocated upstream bandwidth is stored here2217 * @downstream_bw: Allocated downstream bandwidth is stored here2218 *2219 * Stores currently allocated USB3 bandwidth into @upstream_bw and2220 * @downstream_bw in Mb/s. Returns %0 in case of success and negative2221 * errno in failure.2222 */2223int usb4_usb3_port_allocated_bandwidth(struct tb_port *port, int *upstream_bw,2224				       int *downstream_bw)2225{2226	int ret;2227 2228	ret = usb4_usb3_port_set_cm_request(port);2229	if (ret)2230		return ret;2231 2232	ret = usb4_usb3_port_read_allocated_bandwidth(port, upstream_bw,2233						      downstream_bw);2234	usb4_usb3_port_clear_cm_request(port);2235 2236	return ret;2237}2238 2239static int usb4_usb3_port_read_consumed_bandwidth(struct tb_port *port,2240						  int *upstream_bw,2241						  int *downstream_bw)2242{2243	u32 val, bw, scale;2244	int ret;2245 2246	ret = tb_port_read(port, &val, TB_CFG_PORT,2247			   port->cap_adap + ADP_USB3_CS_1, 1);2248	if (ret)2249		return ret;2250 2251	ret = tb_port_read(port, &scale, TB_CFG_PORT,2252			   port->cap_adap + ADP_USB3_CS_3, 1);2253	if (ret)2254		return ret;2255 2256	scale &= ADP_USB3_CS_3_SCALE_MASK;2257 2258	bw = val & ADP_USB3_CS_1_CUBW_MASK;2259	*upstream_bw = usb3_bw_to_mbps(bw, scale);2260 2261	bw = (val & ADP_USB3_CS_1_CDBW_MASK) >> ADP_USB3_CS_1_CDBW_SHIFT;2262	*downstream_bw = usb3_bw_to_mbps(bw, scale);2263 2264	return 0;2265}2266 2267static int usb4_usb3_port_write_allocated_bandwidth(struct tb_port *port,2268						    int upstream_bw,2269						    int downstream_bw)2270{2271	u32 val, ubw, dbw, scale;2272	int ret, max_bw;2273 2274	/* Figure out suitable scale */2275	scale = 0;2276	max_bw = max(upstream_bw, downstream_bw);2277	while (scale < 64) {2278		if (mbps_to_usb3_bw(max_bw, scale) < 4096)2279			break;2280		scale++;2281	}2282 2283	if (WARN_ON(scale >= 64))2284		return -EINVAL;2285 2286	ret = tb_port_write(port, &scale, TB_CFG_PORT,2287			    port->cap_adap + ADP_USB3_CS_3, 1);2288	if (ret)2289		return ret;2290 2291	ubw = mbps_to_usb3_bw(upstream_bw, scale);2292	dbw = mbps_to_usb3_bw(downstream_bw, scale);2293 2294	tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);2295 2296	ret = tb_port_read(port, &val, TB_CFG_PORT,2297			   port->cap_adap + ADP_USB3_CS_2, 1);2298	if (ret)2299		return ret;2300 2301	val &= ~(ADP_USB3_CS_2_AUBW_MASK | ADP_USB3_CS_2_ADBW_MASK);2302	val |= dbw << ADP_USB3_CS_2_ADBW_SHIFT;2303	val |= ubw;2304 2305	return tb_port_write(port, &val, TB_CFG_PORT,2306			     port->cap_adap + ADP_USB3_CS_2, 1);2307}2308 2309/**2310 * usb4_usb3_port_allocate_bandwidth() - Allocate bandwidth for USB32311 * @port: USB3 adapter port2312 * @upstream_bw: New upstream bandwidth2313 * @downstream_bw: New downstream bandwidth2314 *2315 * This can be used to set how much bandwidth is allocated for the USB32316 * tunneled isochronous traffic. @upstream_bw and @downstream_bw are the2317 * new values programmed to the USB3 adapter allocation registers. If2318 * the values are lower than what is currently consumed the allocation2319 * is set to what is currently consumed instead (consumed bandwidth2320 * cannot be taken away by CM). The actual new values are returned in2321 * @upstream_bw and @downstream_bw.2322 *2323 * Returns %0 in case of success and negative errno if there was a2324 * failure.2325 */2326int usb4_usb3_port_allocate_bandwidth(struct tb_port *port, int *upstream_bw,2327				      int *downstream_bw)2328{2329	int ret, consumed_up, consumed_down, allocate_up, allocate_down;2330 2331	ret = usb4_usb3_port_set_cm_request(port);2332	if (ret)2333		return ret;2334 2335	ret = usb4_usb3_port_read_consumed_bandwidth(port, &consumed_up,2336						     &consumed_down);2337	if (ret)2338		goto err_request;2339 2340	/* Don't allow it go lower than what is consumed */2341	allocate_up = max(*upstream_bw, consumed_up);2342	allocate_down = max(*downstream_bw, consumed_down);2343 2344	ret = usb4_usb3_port_write_allocated_bandwidth(port, allocate_up,2345						       allocate_down);2346	if (ret)2347		goto err_request;2348 2349	*upstream_bw = allocate_up;2350	*downstream_bw = allocate_down;2351 2352err_request:2353	usb4_usb3_port_clear_cm_request(port);2354	return ret;2355}2356 2357/**2358 * usb4_usb3_port_release_bandwidth() - Release allocated USB3 bandwidth2359 * @port: USB3 adapter port2360 * @upstream_bw: New allocated upstream bandwidth2361 * @downstream_bw: New allocated downstream bandwidth2362 *2363 * Releases USB3 allocated bandwidth down to what is actually consumed.2364 * The new bandwidth is returned in @upstream_bw and @downstream_bw.2365 *2366 * Returns 0% in success and negative errno in case of failure.2367 */2368int usb4_usb3_port_release_bandwidth(struct tb_port *port, int *upstream_bw,2369				     int *downstream_bw)2370{2371	int ret, consumed_up, consumed_down;2372 2373	ret = usb4_usb3_port_set_cm_request(port);2374	if (ret)2375		return ret;2376 2377	ret = usb4_usb3_port_read_consumed_bandwidth(port, &consumed_up,2378						     &consumed_down);2379	if (ret)2380		goto err_request;2381 2382	/*2383	 * Always keep 900 Mb/s to make sure xHCI has at least some2384	 * bandwidth available for isochronous traffic.2385	 */2386	if (consumed_up < 900)2387		consumed_up = 900;2388	if (consumed_down < 900)2389		consumed_down = 900;2390 2391	ret = usb4_usb3_port_write_allocated_bandwidth(port, consumed_up,2392						       consumed_down);2393	if (ret)2394		goto err_request;2395 2396	*upstream_bw = consumed_up;2397	*downstream_bw = consumed_down;2398 2399err_request:2400	usb4_usb3_port_clear_cm_request(port);2401	return ret;2402}2403 2404static bool is_usb4_dpin(const struct tb_port *port)2405{2406	if (!tb_port_is_dpin(port))2407		return false;2408	if (!tb_switch_is_usb4(port->sw))2409		return false;2410	return true;2411}2412 2413/**2414 * usb4_dp_port_set_cm_id() - Assign CM ID to the DP IN adapter2415 * @port: DP IN adapter2416 * @cm_id: CM ID to assign2417 *2418 * Sets CM ID for the @port. Returns %0 on success and negative errno2419 * otherwise. Speficially returns %-EOPNOTSUPP if the @port does not2420 * support this.2421 */2422int usb4_dp_port_set_cm_id(struct tb_port *port, int cm_id)2423{2424	u32 val;2425	int ret;2426 2427	if (!is_usb4_dpin(port))2428		return -EOPNOTSUPP;2429 2430	ret = tb_port_read(port, &val, TB_CFG_PORT,2431			   port->cap_adap + ADP_DP_CS_2, 1);2432	if (ret)2433		return ret;2434 2435	val &= ~ADP_DP_CS_2_CM_ID_MASK;2436	val |= cm_id << ADP_DP_CS_2_CM_ID_SHIFT;2437 2438	return tb_port_write(port, &val, TB_CFG_PORT,2439			     port->cap_adap + ADP_DP_CS_2, 1);2440}2441 2442/**2443 * usb4_dp_port_bandwidth_mode_supported() - Is the bandwidth allocation mode2444 *					     supported2445 * @port: DP IN adapter to check2446 *2447 * Can be called to any DP IN adapter. Returns true if the adapter2448 * supports USB4 bandwidth allocation mode, false otherwise.2449 */2450bool usb4_dp_port_bandwidth_mode_supported(struct tb_port *port)2451{2452	int ret;2453	u32 val;2454 2455	if (!is_usb4_dpin(port))2456		return false;2457 2458	ret = tb_port_read(port, &val, TB_CFG_PORT,2459			   port->cap_adap + DP_LOCAL_CAP, 1);2460	if (ret)2461		return false;2462 2463	return !!(val & DP_COMMON_CAP_BW_MODE);2464}2465 2466/**2467 * usb4_dp_port_bandwidth_mode_enabled() - Is the bandwidth allocation mode2468 *					   enabled2469 * @port: DP IN adapter to check2470 *2471 * Can be called to any DP IN adapter. Returns true if the bandwidth2472 * allocation mode has been enabled, false otherwise.2473 */2474bool usb4_dp_port_bandwidth_mode_enabled(struct tb_port *port)2475{2476	int ret;2477	u32 val;2478 2479	if (!is_usb4_dpin(port))2480		return false;2481 2482	ret = tb_port_read(port, &val, TB_CFG_PORT,2483			   port->cap_adap + ADP_DP_CS_8, 1);2484	if (ret)2485		return false;2486 2487	return !!(val & ADP_DP_CS_8_DPME);2488}2489 2490/**2491 * usb4_dp_port_set_cm_bandwidth_mode_supported() - Set/clear CM support for2492 *						    bandwidth allocation mode2493 * @port: DP IN adapter2494 * @supported: Does the CM support bandwidth allocation mode2495 *2496 * Can be called to any DP IN adapter. Sets or clears the CM support bit2497 * of the DP IN adapter. Returns %0 in success and negative errno2498 * otherwise. Specifically returns %-OPNOTSUPP if the passed in adapter2499 * does not support this.2500 */2501int usb4_dp_port_set_cm_bandwidth_mode_supported(struct tb_port *port,2502						 bool supported)2503{2504	u32 val;2505	int ret;2506 2507	if (!is_usb4_dpin(port))2508		return -EOPNOTSUPP;2509 2510	ret = tb_port_read(port, &val, TB_CFG_PORT,2511			   port->cap_adap + ADP_DP_CS_2, 1);2512	if (ret)2513		return ret;2514 2515	if (supported)2516		val |= ADP_DP_CS_2_CMMS;2517	else2518		val &= ~ADP_DP_CS_2_CMMS;2519 2520	return tb_port_write(port, &val, TB_CFG_PORT,2521			     port->cap_adap + ADP_DP_CS_2, 1);2522}2523 2524/**2525 * usb4_dp_port_group_id() - Return Group ID assigned for the adapter2526 * @port: DP IN adapter2527 *2528 * Reads bandwidth allocation Group ID from the DP IN adapter and2529 * returns it. If the adapter does not support setting Group_ID2530 * %-EOPNOTSUPP is returned.2531 */2532int usb4_dp_port_group_id(struct tb_port *port)2533{2534	u32 val;2535	int ret;2536 2537	if (!is_usb4_dpin(port))2538		return -EOPNOTSUPP;2539 2540	ret = tb_port_read(port, &val, TB_CFG_PORT,2541			   port->cap_adap + ADP_DP_CS_2, 1);2542	if (ret)2543		return ret;2544 2545	return (val & ADP_DP_CS_2_GROUP_ID_MASK) >> ADP_DP_CS_2_GROUP_ID_SHIFT;2546}2547 2548/**2549 * usb4_dp_port_set_group_id() - Set adapter Group ID2550 * @port: DP IN adapter2551 * @group_id: Group ID for the adapter2552 *2553 * Sets bandwidth allocation mode Group ID for the DP IN adapter.2554 * Returns %0 in case of success and negative errno otherwise.2555 * Specifically returns %-EOPNOTSUPP if the adapter does not support2556 * this.2557 */2558int usb4_dp_port_set_group_id(struct tb_port *port, int group_id)2559{2560	u32 val;2561	int ret;2562 2563	if (!is_usb4_dpin(port))2564		return -EOPNOTSUPP;2565 2566	ret = tb_port_read(port, &val, TB_CFG_PORT,2567			   port->cap_adap + ADP_DP_CS_2, 1);2568	if (ret)2569		return ret;2570 2571	val &= ~ADP_DP_CS_2_GROUP_ID_MASK;2572	val |= group_id << ADP_DP_CS_2_GROUP_ID_SHIFT;2573 2574	return tb_port_write(port, &val, TB_CFG_PORT,2575			     port->cap_adap + ADP_DP_CS_2, 1);2576}2577 2578/**2579 * usb4_dp_port_nrd() - Read non-reduced rate and lanes2580 * @port: DP IN adapter2581 * @rate: Non-reduced rate in Mb/s is placed here2582 * @lanes: Non-reduced lanes are placed here2583 *2584 * Reads the non-reduced rate and lanes from the DP IN adapter. Returns2585 * %0 in success and negative errno otherwise. Specifically returns2586 * %-EOPNOTSUPP if the adapter does not support this.2587 */2588int usb4_dp_port_nrd(struct tb_port *port, int *rate, int *lanes)2589{2590	u32 val, tmp;2591	int ret;2592 2593	if (!is_usb4_dpin(port))2594		return -EOPNOTSUPP;2595 2596	ret = tb_port_read(port, &val, TB_CFG_PORT,2597			   port->cap_adap + ADP_DP_CS_2, 1);2598	if (ret)2599		return ret;2600 2601	tmp = (val & ADP_DP_CS_2_NRD_MLR_MASK) >> ADP_DP_CS_2_NRD_MLR_SHIFT;2602	switch (tmp) {2603	case DP_COMMON_CAP_RATE_RBR:2604		*rate = 1620;2605		break;2606	case DP_COMMON_CAP_RATE_HBR:2607		*rate = 2700;2608		break;2609	case DP_COMMON_CAP_RATE_HBR2:2610		*rate = 5400;2611		break;2612	case DP_COMMON_CAP_RATE_HBR3:2613		*rate = 8100;2614		break;2615	}2616 2617	tmp = val & ADP_DP_CS_2_NRD_MLC_MASK;2618	switch (tmp) {2619	case DP_COMMON_CAP_1_LANE:2620		*lanes = 1;2621		break;2622	case DP_COMMON_CAP_2_LANES:2623		*lanes = 2;2624		break;2625	case DP_COMMON_CAP_4_LANES:2626		*lanes = 4;2627		break;2628	}2629 2630	return 0;2631}2632 2633/**2634 * usb4_dp_port_set_nrd() - Set non-reduced rate and lanes2635 * @port: DP IN adapter2636 * @rate: Non-reduced rate in Mb/s2637 * @lanes: Non-reduced lanes2638 *2639 * Before the capabilities reduction this function can be used to set2640 * the non-reduced values for the DP IN adapter. Returns %0 in success2641 * and negative errno otherwise. If the adapter does not support this2642 * %-EOPNOTSUPP is returned.2643 */2644int usb4_dp_port_set_nrd(struct tb_port *port, int rate, int lanes)2645{2646	u32 val;2647	int ret;2648 2649	if (!is_usb4_dpin(port))2650		return -EOPNOTSUPP;2651 2652	ret = tb_port_read(port, &val, TB_CFG_PORT,2653			   port->cap_adap + ADP_DP_CS_2, 1);2654	if (ret)2655		return ret;2656 2657	val &= ~ADP_DP_CS_2_NRD_MLR_MASK;2658 2659	switch (rate) {2660	case 1620:2661		break;2662	case 2700:2663		val |= (DP_COMMON_CAP_RATE_HBR << ADP_DP_CS_2_NRD_MLR_SHIFT)2664			& ADP_DP_CS_2_NRD_MLR_MASK;2665		break;2666	case 5400:2667		val |= (DP_COMMON_CAP_RATE_HBR2 << ADP_DP_CS_2_NRD_MLR_SHIFT)2668			& ADP_DP_CS_2_NRD_MLR_MASK;2669		break;2670	case 8100:2671		val |= (DP_COMMON_CAP_RATE_HBR3 << ADP_DP_CS_2_NRD_MLR_SHIFT)2672			& ADP_DP_CS_2_NRD_MLR_MASK;2673		break;2674	default:2675		return -EINVAL;2676	}2677 2678	val &= ~ADP_DP_CS_2_NRD_MLC_MASK;2679 2680	switch (lanes) {2681	case 1:2682		break;2683	case 2:2684		val |= DP_COMMON_CAP_2_LANES;2685		break;2686	case 4:2687		val |= DP_COMMON_CAP_4_LANES;2688		break;2689	default:2690		return -EINVAL;2691	}2692 2693	return tb_port_write(port, &val, TB_CFG_PORT,2694			     port->cap_adap + ADP_DP_CS_2, 1);2695}2696 2697/**2698 * usb4_dp_port_granularity() - Return granularity for the bandwidth values2699 * @port: DP IN adapter2700 *2701 * Reads the programmed granularity from @port. If the DP IN adapter does2702 * not support bandwidth allocation mode returns %-EOPNOTSUPP and negative2703 * errno in other error cases.2704 */2705int usb4_dp_port_granularity(struct tb_port *port)2706{2707	u32 val;2708	int ret;2709 2710	if (!is_usb4_dpin(port))2711		return -EOPNOTSUPP;2712 2713	ret = tb_port_read(port, &val, TB_CFG_PORT,2714			   port->cap_adap + ADP_DP_CS_2, 1);2715	if (ret)2716		return ret;2717 2718	val &= ADP_DP_CS_2_GR_MASK;2719	val >>= ADP_DP_CS_2_GR_SHIFT;2720 2721	switch (val) {2722	case ADP_DP_CS_2_GR_0_25G:2723		return 250;2724	case ADP_DP_CS_2_GR_0_5G:2725		return 500;2726	case ADP_DP_CS_2_GR_1G:2727		return 1000;2728	}2729 2730	return -EINVAL;2731}2732 2733/**2734 * usb4_dp_port_set_granularity() - Set granularity for the bandwidth values2735 * @port: DP IN adapter2736 * @granularity: Granularity in Mb/s. Supported values: 1000, 500 and 250.2737 *2738 * Sets the granularity used with the estimated, allocated and requested2739 * bandwidth. Returns %0 in success and negative errno otherwise. If the2740 * adapter does not support this %-EOPNOTSUPP is returned.2741 */2742int usb4_dp_port_set_granularity(struct tb_port *port, int granularity)2743{2744	u32 val;2745	int ret;2746 2747	if (!is_usb4_dpin(port))2748		return -EOPNOTSUPP;2749 2750	ret = tb_port_read(port, &val, TB_CFG_PORT,2751			   port->cap_adap + ADP_DP_CS_2, 1);2752	if (ret)2753		return ret;2754 2755	val &= ~ADP_DP_CS_2_GR_MASK;2756 2757	switch (granularity) {2758	case 250:2759		val |= ADP_DP_CS_2_GR_0_25G << ADP_DP_CS_2_GR_SHIFT;2760		break;2761	case 500:2762		val |= ADP_DP_CS_2_GR_0_5G << ADP_DP_CS_2_GR_SHIFT;2763		break;2764	case 1000:2765		val |= ADP_DP_CS_2_GR_1G << ADP_DP_CS_2_GR_SHIFT;2766		break;2767	default:2768		return -EINVAL;2769	}2770 2771	return tb_port_write(port, &val, TB_CFG_PORT,2772			     port->cap_adap + ADP_DP_CS_2, 1);2773}2774 2775/**2776 * usb4_dp_port_set_estimated_bandwidth() - Set estimated bandwidth2777 * @port: DP IN adapter2778 * @bw: Estimated bandwidth in Mb/s.2779 *2780 * Sets the estimated bandwidth to @bw. Set the granularity by calling2781 * usb4_dp_port_set_granularity() before calling this. The @bw is round2782 * down to the closest granularity multiplier. Returns %0 in success2783 * and negative errno otherwise. Specifically returns %-EOPNOTSUPP if2784 * the adapter does not support this.2785 */2786int usb4_dp_port_set_estimated_bandwidth(struct tb_port *port, int bw)2787{2788	u32 val, granularity;2789	int ret;2790 2791	if (!is_usb4_dpin(port))2792		return -EOPNOTSUPP;2793 2794	ret = usb4_dp_port_granularity(port);2795	if (ret < 0)2796		return ret;2797	granularity = ret;2798 2799	ret = tb_port_read(port, &val, TB_CFG_PORT,2800			   port->cap_adap + ADP_DP_CS_2, 1);2801	if (ret)2802		return ret;2803 2804	val &= ~ADP_DP_CS_2_ESTIMATED_BW_MASK;2805	val |= (bw / granularity) << ADP_DP_CS_2_ESTIMATED_BW_SHIFT;2806 2807	return tb_port_write(port, &val, TB_CFG_PORT,2808			     port->cap_adap + ADP_DP_CS_2, 1);2809}2810 2811/**2812 * usb4_dp_port_allocated_bandwidth() - Return allocated bandwidth2813 * @port: DP IN adapter2814 *2815 * Reads and returns allocated bandwidth for @port in Mb/s (taking into2816 * account the programmed granularity). Returns negative errno in case2817 * of error.2818 */2819int usb4_dp_port_allocated_bandwidth(struct tb_port *port)2820{2821	u32 val, granularity;2822	int ret;2823 2824	if (!is_usb4_dpin(port))2825		return -EOPNOTSUPP;2826 2827	ret = usb4_dp_port_granularity(port);2828	if (ret < 0)2829		return ret;2830	granularity = ret;2831 2832	ret = tb_port_read(port, &val, TB_CFG_PORT,2833			   port->cap_adap + DP_STATUS, 1);2834	if (ret)2835		return ret;2836 2837	val &= DP_STATUS_ALLOCATED_BW_MASK;2838	val >>= DP_STATUS_ALLOCATED_BW_SHIFT;2839 2840	return val * granularity;2841}2842 2843static int __usb4_dp_port_set_cm_ack(struct tb_port *port, bool ack)2844{2845	u32 val;2846	int ret;2847 2848	ret = tb_port_read(port, &val, TB_CFG_PORT,2849			   port->cap_adap + ADP_DP_CS_2, 1);2850	if (ret)2851		return ret;2852 2853	if (ack)2854		val |= ADP_DP_CS_2_CA;2855	else2856		val &= ~ADP_DP_CS_2_CA;2857 2858	return tb_port_write(port, &val, TB_CFG_PORT,2859			     port->cap_adap + ADP_DP_CS_2, 1);2860}2861 2862static inline int usb4_dp_port_set_cm_ack(struct tb_port *port)2863{2864	return __usb4_dp_port_set_cm_ack(port, true);2865}2866 2867static int usb4_dp_port_wait_and_clear_cm_ack(struct tb_port *port,2868					      int timeout_msec)2869{2870	ktime_t end;2871	u32 val;2872	int ret;2873 2874	ret = __usb4_dp_port_set_cm_ack(port, false);2875	if (ret)2876		return ret;2877 2878	end = ktime_add_ms(ktime_get(), timeout_msec);2879	do {2880		ret = tb_port_read(port, &val, TB_CFG_PORT,2881				   port->cap_adap + ADP_DP_CS_8, 1);2882		if (ret)2883			return ret;2884 2885		if (!(val & ADP_DP_CS_8_DR))2886			break;2887 2888		usleep_range(50, 100);2889	} while (ktime_before(ktime_get(), end));2890 2891	if (val & ADP_DP_CS_8_DR) {2892		tb_port_warn(port, "timeout waiting for DPTX request to clear\n");2893		return -ETIMEDOUT;2894	}2895 2896	ret = tb_port_read(port, &val, TB_CFG_PORT,2897			   port->cap_adap + ADP_DP_CS_2, 1);2898	if (ret)2899		return ret;2900 2901	val &= ~ADP_DP_CS_2_CA;2902	return tb_port_write(port, &val, TB_CFG_PORT,2903			     port->cap_adap + ADP_DP_CS_2, 1);2904}2905 2906/**2907 * usb4_dp_port_allocate_bandwidth() - Set allocated bandwidth2908 * @port: DP IN adapter2909 * @bw: New allocated bandwidth in Mb/s2910 *2911 * Communicates the new allocated bandwidth with the DPCD (graphics2912 * driver). Takes into account the programmed granularity. Returns %0 in2913 * success and negative errno in case of error.2914 */2915int usb4_dp_port_allocate_bandwidth(struct tb_port *port, int bw)2916{2917	u32 val, granularity;2918	int ret;2919 2920	if (!is_usb4_dpin(port))2921		return -EOPNOTSUPP;2922 2923	ret = usb4_dp_port_granularity(port);2924	if (ret < 0)2925		return ret;2926	granularity = ret;2927 2928	ret = tb_port_read(port, &val, TB_CFG_PORT,2929			   port->cap_adap + DP_STATUS, 1);2930	if (ret)2931		return ret;2932 2933	val &= ~DP_STATUS_ALLOCATED_BW_MASK;2934	val |= (bw / granularity) << DP_STATUS_ALLOCATED_BW_SHIFT;2935 2936	ret = tb_port_write(port, &val, TB_CFG_PORT,2937			    port->cap_adap + DP_STATUS, 1);2938	if (ret)2939		return ret;2940 2941	ret = usb4_dp_port_set_cm_ack(port);2942	if (ret)2943		return ret;2944 2945	return usb4_dp_port_wait_and_clear_cm_ack(port, 500);2946}2947 2948/**2949 * usb4_dp_port_requested_bandwidth() - Read requested bandwidth2950 * @port: DP IN adapter2951 *2952 * Reads the DPCD (graphics driver) requested bandwidth and returns it2953 * in Mb/s. Takes the programmed granularity into account. In case of2954 * error returns negative errno. Specifically returns %-EOPNOTSUPP if2955 * the adapter does not support bandwidth allocation mode, and %ENODATA2956 * if there is no active bandwidth request from the graphics driver.2957 */2958int usb4_dp_port_requested_bandwidth(struct tb_port *port)2959{2960	u32 val, granularity;2961	int ret;2962 2963	if (!is_usb4_dpin(port))2964		return -EOPNOTSUPP;2965 2966	ret = usb4_dp_port_granularity(port);2967	if (ret < 0)2968		return ret;2969	granularity = ret;2970 2971	ret = tb_port_read(port, &val, TB_CFG_PORT,2972			   port->cap_adap + ADP_DP_CS_8, 1);2973	if (ret)2974		return ret;2975 2976	if (!(val & ADP_DP_CS_8_DR))2977		return -ENODATA;2978 2979	return (val & ADP_DP_CS_8_REQUESTED_BW_MASK) * granularity;2980}2981 2982/**2983 * usb4_pci_port_set_ext_encapsulation() - Enable/disable extended encapsulation2984 * @port: PCIe adapter2985 * @enable: Enable/disable extended encapsulation2986 *2987 * Enables or disables extended encapsulation used in PCIe tunneling. Caller2988 * needs to make sure both adapters support this before enabling. Returns %0 on2989 * success and negative errno otherwise.2990 */2991int usb4_pci_port_set_ext_encapsulation(struct tb_port *port, bool enable)2992{2993	u32 val;2994	int ret;2995 2996	if (!tb_port_is_pcie_up(port) && !tb_port_is_pcie_down(port))2997		return -EINVAL;2998 2999	ret = tb_port_read(port, &val, TB_CFG_PORT,3000			   port->cap_adap + ADP_PCIE_CS_1, 1);3001	if (ret)3002		return ret;3003 3004	if (enable)3005		val |= ADP_PCIE_CS_1_EE;3006	else3007		val &= ~ADP_PCIE_CS_1_EE;3008 3009	return tb_port_write(port, &val, TB_CFG_PORT,3010			     port->cap_adap + ADP_PCIE_CS_1, 1);3011}3012