From 0cd06e7ac72825a4a414057c45e0874a539f2909 Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 17 Jul 2024 15:52:29 +0800 Subject: [PATCH] phy: rockchip: usbdp: Disable u3 port if wait rx cdr lock timeout Test on RK3576 EVB1/Tablet connected with Type-C to HDMI cable, it is easy to trigger kernel panic during system enter/exit deep sleep with the following log: [ 100.859203][ T3862] PM: PM: Pending Wakeup Sources: NETLINK [ 100.874736][ T3862] PM: Some devices failed to suspend, or early wake event detected [ 100.984288][ T3862] rockchip-usbdp-phy 2b010000.phy: trsv ln0 mon rx cdr lock timeout [ 100.989921][ T3893] xhci-hcd xhci-hcd.6.auto: xHC error in resume, USBSTS 0x411, Reinit [ 100.989936][ T3893] usb usb1: root hub lost power or was reset [ 100.989946][ T3893] ub usb2: root hub lost power or was reset [ 100.990852][ C3] SError Interrupt on CPU3, code 0x00000000bf000002 -- SError [ 100.990862][ C3] CPU: 3 PID: 3895 Comm: kworker/u16:18 Tainted: G [ 100.990868][ C3] Hardware name: Rockchip RK3576 TABLET V10 Board (DT) [ 100.990871][ C3] Workqueue: events_unbound async_run_entry_fn [ 100.990886][ C3] pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 100.990891][ C3] pc : local_daif_inherit+0xc/0x10 [ 100.990898][ C3] lr : el1_abort+0x2c/0x5c [ 100.990905][ C3] sp : ffffffc014973650 ...... [ 100.990969][ C3] Kernel panic - not syncing: Asynchronous SError Interrupt [ 100.990973][ C3] CPU: 3 PID: 3895 Comm: kworker/u16:18 Tainted: G [ 100.990978][ C3] Hardware name: Rockchip RK3576 TABLET V10 Board (DT) [ 100.990980][ C3] Workqueue: events_unbound async_run_entry_fn [ 100.990988][ C3] Call trace: [ 100.990990][ C3] dump_backtrace+0xf4/0x118 [ 100.990996][ C3] show_stack+0x18/0x24 [ 100.991000][ C3] dump_stack_lvl+0x60/0x7c [ 100.991005][ C3] dump_stack+0x18/0x38 [ 100.991010][ C3] panic+0x16c/0x388 [ 100.991014][ C3] nmi_panic+0xa4/0xa8 [ 100.991019][ C3] arm64_serror_panic+0x6c/0x94 [ 100.991025][ C3] do_serror+0xc4/0xd0 [ 100.991029][ C3] el1h_64_error_handler+0x34/0x48 [ 100.991034][ C3] el1h_64_error+0x68/0x6c [ 100.991038][ C3] local_daif_inherit+0xc/0x10 [ 100.991044][ C3] el1h_64_sync_handler+0x54/0x90 [ 100.991049][ C3] el1h_64_sync+0x68/0x6c [ 100.991053][ C3] readl+0x44/0x8c [ 100.991059][ C3] xhci_set_port_power+0x8c/0xcc [ 100.991066][ C3] xhci_hub_control+0xb7c/0x19b8 [ 100.991071][ C3] usb_hcd_submit_urb+0x688/0x9b8 [ 100.991079][ C3] usb_submit_urb+0x480/0x4f4 [ 100.991084][ C3] usb_start_wait_urb+0x6c/0x110 [ 100.991089][ C3] usb_control_msg+0xc4/0x144 [ 100.991093][ C3] hub_activate+0x374/0xa1c [ 100.991099][ C3] hub_reset_resume+0x18/0x2c [ 100.991105][ C3] usb_resume_both+0x218/0x32c [ 100.991110][ C3] usb_resume+0x28/0x7c [ 100.991115][ C3] usb_dev_resume+0x14/0x24 [ 100.991121][ C3] dpm_run_callback+0x64/0x230 [ 100.991128][ C3] __device_resume+0x1c8/0x360 [ 100.991133][ C3] async_resume+0x24/0x3c The root cause is that the source clock of the usb xHCI maybe changed during system suspend and wakeup. 1. When plug in Type-C to HDMI cable which support DP 4*lanes + USB2.0, the usbdp phy driver call the udphy_u3_port_disable() to disable u3 port and select the utmi clock which from usb2 phy for usb xHCI source clock. 2. During system wakeup, the Type-C CC state maybe changed and the Type-C subsystem will call the udphy_orien_sw_set() to reinit the udphy->mode as DP 2*lanes + USB3.0. 3. In the system pm resume process, the usb controller driver call the rockchip_u3phy_init() to initialize the usbdp phy. Because the udphy->mode has been modified to UDPHY_MODE_USB, so it call udphy_u3_port_disable() to enable u3 port and select the pipe clock which from usbdp phy for usb xHCI source clock. 4. In udphy_init(), it waits for rx cdr lock timeout, which means that the usb3 phy and its pipe clock are not ready. 5. Later in the usb_dev_resume(), the xHCI driver trigger kernel panic when access the xHCI controller register because its source clock isn't ready. To fixes this issue, the patch disable u3 port and select the utmi clock for usb controller if wait rx cdr lock timeout. Change-Id: I3213c59dc9f0bb183037c943c6adaf769def194e Signed-off-by: William Wu --- drivers/phy/rockchip/phy-rockchip-usbdp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index a1072d584c33..520059604da1 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -780,6 +780,11 @@ static int udphy_status_check(struct rockchip_udphy *udphy) if (ret) dev_notice(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n"); } + + if (ret) { + udphy_u3_port_disable(udphy, true); + dev_warn(udphy->dev, "disable u3 port because udphy not ready\n"); + } } return 0;