diff --git a/drivers/phy/apple/atc-test.c b/drivers/phy/apple/atc-test.c index 09eec7f9d618..7acde177f69b 100644 --- a/drivers/phy/apple/atc-test.c +++ b/drivers/phy/apple/atc-test.c @@ -104,6 +104,40 @@ static void atcphy_test_target_mode_t8132(struct kunit *test) KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_OFF); } +/* Without the CIO calibration, a T8132 port serves a USB4 or TBT partner's USB2 */ +static void atcphy_test_target_mode_t8132_cio(struct kunit *test) +{ + struct typec_altmode tbt = { .svid = USB_TYPEC_TBT_SID }; + struct enter_usb_data eusb = { + .eudo = FIELD_PREP(EUDO_USB_MODE_MASK, EUDO_USB_MODE_USB4), + }; + struct typec_mux_state state = { .mode = TYPEC_MODE_USB4, .data = &eusb }; + struct apple_atcphy *atcphy = atcphy_test_alloc_dev(test, false); + + atcphy->hw = &atcphy_hw_t8132; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_USB2); + state.alt = &tbt; + state.mode = TYPEC_TBT_MODE; + state.data = NULL; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_USB2); + /* The same on a SuperSpeed port. */ + atcphy->t8132_ss = true; + atcphy->ss_tunables = true; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_USB2); + state.alt = NULL; + state.mode = TYPEC_MODE_USB4; + state.data = &eusb; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_USB2); + + /* With the calibration, the link itself is served. */ + atcphy->cio_tunables = true; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_USB4); + state.alt = &tbt; + state.mode = TYPEC_TBT_MODE; + state.data = NULL; + KUNIT_EXPECT_EQ(test, atcphy_typec_target_mode(atcphy, &state), APPLE_ATCPHY_MODE_TBT); +} + static void atcphy_test_noop_same_mode(struct kunit *test) { struct apple_atcphy *atcphy = atcphy_test_alloc(test, true); @@ -1391,6 +1425,7 @@ static struct kunit_case atcphy_mux_test_cases[] = { KUNIT_CASE(atcphy_test_target_mode), KUNIT_CASE(atcphy_test_target_mode_fixed_hub), KUNIT_CASE(atcphy_test_target_mode_t8132), + KUNIT_CASE(atcphy_test_target_mode_t8132_cio), KUNIT_CASE(atcphy_test_noop_same_mode), KUNIT_CASE(atcphy_test_noop_needs_work), KUNIT_CASE(atcphy_test_usb3_port_ready), diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c index 414ce695f37a..af28f03b1a6c 100644 --- a/drivers/phy/apple/atc.c +++ b/drivers/phy/apple/atc.c @@ -5729,10 +5729,24 @@ static enum atcphy_mode atcphy_typec_target_mode(struct apple_atcphy *atcphy, * its USB on the other wires: USB2 next to four DP lanes (pin * assignments C and E), USB3 next to two (D). Serve that USB rather * than refuse the mode, which would leave the port without USB at all. + * + * The same goes for USB4 and Thunderbolt on a port without the CIO + * calibration, such as those of the Mac mini (J773g). Its port + * controller enters USB4 or Thunderbolt 3 by itself with a USB4 dock + * or another Mac, and USB 2.0 on D+/D- does not depend on that link. + * Do this first, so that the DisplayPort fallback below starts from + * the mode actually served rather than putting USB4 back. */ if (atcphy->hw->gen == ATCPHY_GENERATION_T8132) { - enum atcphy_mode usb_mode = target_mode; + enum atcphy_mode usb_mode; + + if (atcphy_mode_is_cio(target_mode) && !atcphy->cio_tunables) { + dev_info(atcphy->dev, + "USB4/Thunderbolt is not available on this port: serving its USB2 only\n"); + target_mode = APPLE_ATCPHY_MODE_USB2; + } + usb_mode = target_mode; /* 4-lane DP stays DP only on a port wired for DP alt mode */ if (target_mode == APPLE_ATCPHY_MODE_DP && !atcphy_t8132_dp_on(atcphy)) usb_mode = APPLE_ATCPHY_MODE_USB2; diff --git a/tools/asahi/atc-usb3-tests.py b/tools/asahi/atc-usb3-tests.py index 6d92c105c45b..30ae465f18e6 100644 --- a/tools/asahi/atc-usb3-tests.py +++ b/tools/asahi/atc-usb3-tests.py @@ -62,6 +62,7 @@ def block(source, marker): static unsigned reports; #define dev_warn(...) ((void)reports++) #define dev_err(...) ((void)reports++) +#define dev_info(...) ((void)0) #define dev_dbg(...) ((void)0) #define lockdep_assert_held(...) ((void)0) #define guard(which) (void) diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/dwc3/prefix.c b/tools/testing/selftests/drivers/gpu/apple-dcp/dwc3/prefix.c index 8c0bfb426e8a..81a66a396ba0 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/dwc3/prefix.c +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/dwc3/prefix.c @@ -28,6 +28,7 @@ static void warning(const char *message) generic_warnings++; } #define dev_warn(d, message, ...) warning(message) +#define dev_info(...) ((void)0) #define dev_err(...) ((void)0) #define dev_dbg(...) ((void)0) #define lockdep_assert_held(p) assert(*(p)) diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/phy.py b/tools/testing/selftests/drivers/gpu/apple-dcp/phy.py index 7998abe4b8ac..d386409fd636 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/phy.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/phy.py @@ -221,6 +221,7 @@ def function(source, name): #define dev_info_once(...) ((void)0) #define dev_dbg(...) ((void)0) #define dev_warn(...) ((void)0) +#define dev_info(...) ((void)0) static void report(void *dev, const char *fmt, ...) { (void)dev; (void)fmt; } #define dev_err report #define lockdep_assert_held(...) ((void)0) @@ -2042,6 +2043,7 @@ def function(name): #define field_prep FIELD_PREP #define dev_dbg(...) ((void)0) #define dev_warn(...) ((void)0) +#define dev_info(...) ((void)0) #define dev_err(...) ((void)0) #define lockdep_assert_held(...) ((void)0) #define WARN_ON_ONCE(v) assert(!(v)) @@ -2459,6 +2461,7 @@ def function(source, name): #define dev_info_once(...) ((void)0) #define dev_dbg(...) ((void)0) #define dev_warn(...) ((void)0) +#define dev_info(...) ((void)0) static void report(void *dev, const char *fmt, ...) { (void)dev; (void)fmt; } #define dev_err report #define lockdep_assert_held(...) ((void)0) diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/pm.py b/tools/testing/selftests/drivers/gpu/apple-dcp/pm.py index 4dcdc35ed409..4431d873c595 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/pm.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/pm.py @@ -570,6 +570,7 @@ def function(text, name): ' struct notifier_block tbt_watch;\n bool tbt_watch_registered;\n', 1) mocks = mocks.replace('static void cd321x_stop_work(struct cd321x *c) {\n', r'''#define INIT_WORK(p,fn) ((p)->pending=false) #define dev_warn(...) ((void)0) +#define dev_info(...) ((void)0) static int watches, watch_error; /* Like the real watch, hold the port fwnode until the port is unregistered. */ static int cd321x_tbt_watch_late(struct cd321x *c,struct fwnode_handle *f) { diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/quiesce.py b/tools/testing/selftests/drivers/gpu/apple-dcp/quiesce.py index 9d5bb22eae4f..c31c25d45a3e 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/quiesce.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/quiesce.py @@ -31,6 +31,7 @@ def make_unit(source, parent=False, reference=None): #define dev_dbg(...) ((void)0) #define dev_warn(...) ((void)0) #define dev_info(...) ((void)0) +#define dev_info(...) ((void)0) #define dev_name(p) "device" #define list_for_each_entry(p,h,m) for((void)(h),(p)=sole_port();(p);(p)=NULL) #define lockdep_assert_held(p) ((void)(p))